package com.example.myapplication.Service;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.location.Location;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;


import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.room.Room;

import com.example.myapplication.DataBase.AppDatabase;

import com.example.myapplication.R;
import com.example.myapplication.Tool.BackgroundToast;
import com.example.myapplication.Tool.RetrofitClient;
import com.example.myapplication.model.AudioEntity;
import com.example.myapplication.model.SharedDataManager;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import io.reactivex.disposables.Disposable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class RecordingService extends Service implements SharedDataManager.DataChangeListener {
    private static final String CHANNEL_ID = "recording_channel";
    private static final int NOTIFICATION_ID = 2;
    private MediaRecorder mediaRecorder;
    private String currentAudioPath;
    private Handler handler;
    private Runnable updateTimerRunnable;
    private AppDatabase db;
    private AppDatabase db2;
    private final ExecutorService executor = Executors.newFixedThreadPool(4);
    private String ImageId="-1";
    private String currentToken="-1";
    private  SharedDataManager dataManager;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    private final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)  // 连接超时
            .readTimeout(60, TimeUnit.SECONDS)     // 读取超时
            .writeTimeout(60, TimeUnit.SECONDS)    // 写入超时
            .build();
    private int recordingSeconds = 0;
    @RequiresApi(api = Build.VERSION_CODES.R)
    @Override
    public void onCreate() {
        super.onCreate();
        try {
        createNotificationChannel();
        // 启动前台服务（必须5秒内调用startForeground）
        Notification notification = buildNotification("录音服务运行中");

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                // Android 10+ 需要指定类型
                startForeground(NOTIFICATION_ID, notification,
                        ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
            } else {
                // Android 8.0-9.0
                startForeground(NOTIFICATION_ID, notification);
            }
        } catch (Exception e) {
            Toast.makeText(this,"错误:"+e,Toast.LENGTH_LONG).show();
            stopSelf();
        }
        handler = new Handler(Looper.getMainLooper());
        db = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class, "image-database").build();
        db2 = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class, "image-database2").build();
        createNotificationChannel();


        // 在 onCreate() 中改进 ViewModel 初始化

        // 观察LiveData变化
        // 在类成员变量中添加

         dataManager=SharedDataManager.getInstance();
        dataManager.addListener(this);

        currentToken = dataManager.getToken();
        ImageId=dataManager.getImageId();
// 在onCreate()中改为使用成员变量观察

    }


    @Override
    public void onImageIdChanged(String newId) {
        ImageId=newId;
    }

    @Override
    public void onTokenChanged(String newToken) {
        currentToken = newToken;
        Log.d("Service", "Token updated: " + newToken);
    }

    @Override
    public void onUserChanged(String newUser) {

    }

    @Override
    public void onAudioPathChanged(String newAudioPath) {

    }

    @Override
    public void onProjectIdChanged(String newProjectId) {

    }

    @Override
    public void onPartIdChanged(String newUnit) {

    }

    @Override
    public void onTurbineIdChanged(String newTurbineId) {

    }

    @Override
    public void onPartNameChanged(String newPartName) {

    }

    @Override
    public void onTurbineNameChanged(String newTurbineName) {

    }

    @Override
    public void onChooseImageSourceChanged(String newChooseImageSource) {

    }

    @Override
    public void onIsRecordingChanged(boolean newisRecording) {

    }

    @Override
    public void onUploadingStatusChanged(boolean isUploading) {


    }

    @Override
    public void onLocationChanged(Location newLocation) {

    }

    @Override
    public void onOtherMsgChanged(String msg) {

    }


    // 获取当前数据（可选，如果 Activity 需要读取）

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        if (intent != null && "start_recording".equals(intent.getAction())) {
            startRecording();
        } else if (intent != null && "stop_recording".equals(intent.getAction())) {
            stopRecording();
        }
        return START_REDELIVER_INTENT;
    }
    private void startRecording() {

        try {
            dataManager.setIsRecording(true);
            // 1. 设置录音文件路径
            currentAudioPath = getExternalCacheDir().getAbsolutePath()
                    + "/" + System.currentTimeMillis() + ".3gp";
            dataManager.setAudioPath(currentAudioPath);
            // 2. 初始化MediaRecorder
            mediaRecorder = new MediaRecorder();

            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mediaRecorder.setOutputFile(currentAudioPath);
            mediaRecorder.prepare();
            mediaRecorder.start();

            // 3. 启动前台服务
            startForegroundService();

            // 4. 开始计时更新通知
            startUpdatingTimer();

        } catch (Exception e) {
            Toast.makeText(this, "录音失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            stopSelf();
        }
    }

    private void startForegroundService() {
        Notification notification = buildNotification("录音中... 00:00");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            startForeground(NOTIFICATION_ID, notification,
                    ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
        } else {
            startForeground(NOTIFICATION_ID, notification);
        }
    }

    private void startUpdatingTimer() {
        updateTimerRunnable = new Runnable() {
            @Override
            public void run() {
                recordingSeconds++;
                String time = String.format("%02d:%02d",
                        recordingSeconds / 60, recordingSeconds % 60);
                updateNotification("录音中... " + time);
                handler.postDelayed(this, 1000);
            }
        };
        handler.post(updateTimerRunnable);
    }
    private void uploadAudio(String imageId, String audioPath, String token) {
        // 1. 参数校验（在调用线程执行，避免不必要的后台任务）
        if (audioPath == null || audioPath.equals("0")) {
            BackgroundToast.show(this, "文件路径为空");
            return;
        }

        File audioFile = new File(audioPath);
        if (!audioFile.exists()) {
            BackgroundToast.show(this, "文件不存在");
            return;
        }

        // 2. 在后台线程执行上传逻辑
        executor.execute(() -> {
            // 3. 构建请求体（已在后台线程）
            RequestBody requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("file", audioFile.getName(),
                            RequestBody.create(audioFile, MediaType.parse("audio/*")))
                    .build();

            // 4. 构建请求
            Request.Builder requestBuilder = new Request.Builder()
                    .url(RetrofitClient.BASE_URL + "audio/upload/" + imageId)
                    .post(requestBody);

            if (token != null && !token.isEmpty()) {
                requestBuilder.addHeader("Authorization", token);
            }

            // 5. 同步执行请求（try-with-resources 自动关闭 Response）
            try (Response response = httpClient.newCall(requestBuilder.build()).execute()) {
                String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
                        .format(new Date());

                if (response.isSuccessful()) {
                    // 上传成功
                    executor.execute(()->{  db.AudioDao().deleteByPath(audioPath);

                    db2.AudioDao().insert(new AudioEntity(audioPath, imageId, currentTime,true));});
                    BackgroundToast.show(this, "录音上传成功: " + imageId);
                    stopSelf();
                } else {
                    // 上传失败（HTTP 错误）
                    executor.execute(()->{ db.AudioDao().insert(new AudioEntity(audioPath, imageId, currentTime,false));});
                    BackgroundToast.show(this,
                            "录音上传失败: " + response.code() + " " + response.message());
                    stopSelf();
                }
            } catch (IOException e) {
                // 网络异常
                String currentTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
                        .format(new Date());

                 executor.execute(() -> {
                    db.AudioDao().insert(new AudioEntity(currentAudioPath, ImageId, currentToken, false));
                });
                BackgroundToast.show(this, "录音上传失败: " + e.getMessage());
                Log.e("录音上传失败:",e.toString());
                stopSelf();
            }
        });
    }

    private void stopRecording() {
        try {
            // 1. 停止录音
            if (mediaRecorder != null) {
                mediaRecorder.stop();
                mediaRecorder.release();
                mediaRecorder = null;
            }
            dataManager.setIsRecording(false);
            // 2. 停止计时器
            if (handler != null && updateTimerRunnable != null) {
                handler.removeCallbacks(updateTimerRunnable);
            }
            // 3. 更新通知
            updateNotification("录音已保存");
            // 4. 上传录音文件（如果有需要）
            if (currentAudioPath != null && ImageId != "-1") {
                BackgroundToast.show(this,"开始上传录音了");
                uploadAudio(ImageId, currentAudioPath, currentToken);
            } else
            {
                BackgroundToast.show(this,"Imageid不存在，上传录音失败");
                executor.execute(() -> {
                db.AudioDao().insert(new AudioEntity(currentAudioPath, ImageId, currentToken, false));
            });
            }

            // 5. 不立即停止服务，等待上传完成
            // 可以通过其他机制（如广播或LiveData）在上传完成后通知服务停止

        } catch (Exception e) {
            Toast.makeText(this, "停止录音失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            dataManager.setIsRecording(false);
            stopSelf();
        }
    }



    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    "recording_channel",
                    "Recording Service",
                    NotificationManager.IMPORTANCE_LOW);
            NotificationManager manager = getSystemService(NotificationManager.class);
            if (manager != null) {
                manager.createNotificationChannel(channel);
            }
        }
    }

    public Notification buildNotification(String text) {
        // 确保图标有效（R.drawable.ic_mic_on必须存在）
        return new NotificationCompat.Builder(this, CHANNEL_ID)
                .setSmallIcon(R.drawable.ic_mic_on)
                .setContentTitle("录音服务")
                .setContentText(text)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();
    }

    public void updateNotification(String text) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            if (ActivityCompat.checkSelfPermission(this,
                    android.Manifest.permission.POST_NOTIFICATIONS)
                    != PackageManager.PERMISSION_GRANTED) {
                // 无权限时不显示通知（避免崩溃）
                return;
            }
        }
        NotificationManagerCompat.from(this)
                .notify(NOTIFICATION_ID, buildNotification(text));
    }
    @Override
    public void onDestroy() {
        super.onDestroy();


        // 2. 停止并释放MediaRecorder
        if (mediaRecorder != null) {
            try {
                mediaRecorder.stop();
                mediaRecorder.release();
            } catch (IllegalStateException e) {
                Log.e("Service", "MediaRecorder释放异常", e);
            }
            mediaRecorder = null;
        }

        // 3. 移除Handler回调
        if (handler != null && updateTimerRunnable != null) {
            handler.removeCallbacks(updateTimerRunnable);
        }


       dataManager.removeListener(this);
        // 5. 关闭数据库（如果Room支持）
        if (db != null) {
            db.close();
        }
        if (db2 != null) {
            db2.close();
        }
    }
}