package com.example.myapplication.Service;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationManager;
import android.media.ExifInterface;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.provider.MediaStore;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
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.NotificationReceiver;
import com.example.myapplication.Tool.RetrofitClient;
import com.example.myapplication.model.ImageEntity;
import com.example.myapplication.model.SharedDataManager;

import org.json.JSONObject;

import java.io.File;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class PhotoMonitoringService extends Service implements SharedDataManager.DataChangeListener {
    private static final String CHANNEL_ID = "PhotoMonitoringChannel";
    private static final int NOTIFICATION_ID = 101;
    private static final int THUMBNAIL_SIZE = 100;

    // 锁对象
    private final Object monitoringLock = new Object();
    private final Object uploadLock = new Object();
    private long lastSuccessToastTime = 0;
    private static final long TOAST_THROTTLE_INTERVAL = 1500;

    // 状态标志
    private boolean isMonitoring = false;
    private boolean isUploading = false;
    private boolean isRecording = false;
    private int successCount = 0;
    private int totalUploadedCount = 0; // 新增：总上传成功计数

    // 组件
    private ContentObserver contentObserver;
    private final ExecutorService executor = Executors.newFixedThreadPool(5);
    private final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)  // 连接超时
            .readTimeout(60, TimeUnit.SECONDS)     // 读取超时
            .writeTimeout(60, TimeUnit.SECONDS)    // 写入超时
            .build();

    // 数据库
    private AppDatabase db;
    private AppDatabase db2;

    // 位置相关
    private Location lastKnownLocation;
    private LocationManager locationManager;

    // 配置参数
    private String token;
    private String user;
    private String projectId;
    private String partId;
    private String partName;
    private String turbineId;
    private String turbineName;
    private String Temperator;
    private String Humidity;
    private String Weather;
    private String ChooseImageSource;

    // 其他状态
    private long lastPhotoId = 0;
    private String currentAudioPath="-1";
    private String imgpath="-1";
    private String UserId;


    @Override
    public void onImageIdChanged(String newId) {

    }

    @Override
    public void onTokenChanged(String newToken) {
    }

    @Override
    public void onUserChanged(String newUser) {
        user=newUser;
    }

    @Override
    public void onAudioPathChanged(String newAudioPath) {
        currentAudioPath=newAudioPath;
    }

    @Override
    public void onProjectIdChanged(String newProjectId) {
        projectId=newProjectId;
    }

    @Override
    public void onPartIdChanged(String newPartId) {
        partId =newPartId;
    }

    @Override
    public void onPartNameChanged(String newPartName) {
        partName = newPartName;
    }

    @Override
    public void onTurbineIdChanged(String newTurbineId) {
        turbineId =newTurbineId;
    }

    @Override
    public void onTurbineNameChanged(String newTurbineName) {
        turbineName = newTurbineName;
    }

    @Override
    public void onChooseImageSourceChanged(String newChooseImageSource) {
        ChooseImageSource=newChooseImageSource;
    }

    @Override
    public void onIsRecordingChanged(boolean newisRecording) {
        isRecording=newisRecording;
    }

    @Override
    public void onUploadingStatusChanged(boolean isUploading) {
        this.isUploading=isUploading;
    }

    @Override
    public void onLocationChanged(Location newLocation) {
        lastKnownLocation=newLocation;
    }

    @Override
    public void onOtherMsgChanged(String msg) {

    }

    SharedDataManager dataManager;

    @Override
    public void onCreate() {
        super.onCreate();
        createNotificationChannel();
        SharedPreferences prefs = getSharedPreferences("WeatherPrefs", MODE_PRIVATE);
        Weather = prefs.getString("weather", "0");
        Temperator = prefs.getString("temperature", "0");
        Humidity = prefs.getString("humidity", "0");
        SharedPreferences sharedPreferences = getSharedPreferences("LoginPrefs", Context.MODE_PRIVATE);
        // 初始化数据库
        UserId=sharedPreferences.getString("userid","-1");
        db = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class, "image-database").build();
        db2 = Room.databaseBuilder(getApplicationContext(),
                AppDatabase.class, "image-database2").build();

        // 初始化位置管理器
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        dataManager=SharedDataManager.getInstance();

        dataManager.addListener(this);
        updateFromSharedData();

        // 初始化时从数据库获取已上传成功的数量

            totalUploadedCount = 0;
            updateNotification("partId"+partId);

    }

    private void updateFromSharedData() {
        dataManager = SharedDataManager.getInstance();
        this.token = dataManager.getToken();
        this.user = dataManager.getUser();
        this.currentAudioPath = dataManager.getAudioPath();
        this.projectId = dataManager.getProjectId();
        this.partId = dataManager.getPartId();
        this.turbineId = dataManager.getTurbineId();
        this.ChooseImageSource = dataManager.getChooseImageSource();
        this.isUploading=dataManager.getisUploading();
        this.lastKnownLocation=dataManager.getLocation();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null && "start_monitoring".equals(intent.getStringExtra("command"))) {
            startMonitoring();
        }

        startForeground(NOTIFICATION_ID, buildNotification("服务正在运行", "监听照片变化中"));

        return START_STICKY;
    }

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

    @Override
    public void onDestroy() {
        stopMonitoring();
        super.onDestroy();
    }

    public void startMonitoring() {
        synchronized (monitoringLock) {
            if (isMonitoring) return;

            lastPhotoId = getLastPhotoId();

            contentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
                @Override
                public void onChange(boolean selfChange, Uri uri) {
                    super.onChange(selfChange, uri);
                    if (!isRecording && uri != null && uri.toString().contains("images/media")) {
                        checkNewPhotos();
                    }
                }
            };

            getContentResolver().registerContentObserver(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                    true,
                    contentObserver
            );

            isMonitoring = true;

            executor.execute(() -> {
                List<ImageEntity> history = db2.imageDao().getAll();
                if (history != null && !history.isEmpty()) {
                    synchronized (uploadLock) {
                        for (ImageEntity image : history) {
                            uploadPhoto(image.path, image.time, lastKnownLocation, image.user,
                                    image.audioPath, image.project, image.turbineId, image.partId,
                                    image.imageSource);
                        }
                    }
                }
                db2.imageDao().deleteAll();
            });
        }
    }

    public void stopMonitoring() {
        synchronized (monitoringLock) {
            if (!isMonitoring) return;

            if (contentObserver != null) {
                getContentResolver().unregisterContentObserver(contentObserver);
                contentObserver = null;
            }

            isMonitoring=false;
        }
    }

    private void checkNewPhotos() {
        String[] projection = {
                MediaStore.Images.Media._ID,
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media.DATE_ADDED,
                MediaStore.Images.Media.DATE_TAKEN,
                MediaStore.Images.Media.LATITUDE,
                MediaStore.Images.Media.LONGITUDE
        };

        String selection = MediaStore.Images.Media._ID + " > ? AND " +
                MediaStore.Images.Media.DATE_TAKEN + " > 0 AND " +
                "(" + MediaStore.Images.Media.DATA + " LIKE '%/DCIM/%' OR " +
                MediaStore.Images.Media.DATA + " LIKE '%/Camera/%')";
        String[] selectionArgs = new String[]{String.valueOf(lastPhotoId)};

        try (Cursor cursor = getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                selection,
                selectionArgs,
                MediaStore.Images.Media._ID + " DESC"
        )) {
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    processNewPhoto(cursor);
                }
            }
        } catch (Exception e) {
            Log.e("PhotoMonitoringService", "Error checking new photos", e);
        }
    }

    private void processNewPhoto(Cursor cursor) {
        long id = cursor.getLong(0);
        String path = cursor.getString(1);
        imgpath = path;

        long time = cursor.getLong(2) * 1000;
        double latitude = cursor.getDouble(3);
        double longitude = cursor.getDouble(4);
        double altitude = 0.0;

        if (lastKnownLocation != null) {
            latitude = lastKnownLocation.getLatitude();
            longitude = lastKnownLocation.getLongitude();
            altitude = lastKnownLocation.getAltitude();
        }

        try {
            ExifInterface exif = new ExifInterface(path);
            String altitudeStr = exif.getAttribute(ExifInterface.TAG_GPS_ALTITUDE);
            if (altitudeStr != null) {
                altitude = Double.parseDouble(altitudeStr);
            }
        } catch (Exception e) {
            Log.e("PhotoMonitoringService", "Error reading EXIF data", e);
        }

        String audioPath = currentAudioPath;
        lastPhotoId = Math.max(lastPhotoId, id);

        if (isNetworkAvailable() && !isRecording) {
            uploadNewPhoto(path, time, audioPath);
        } else {
            queuePhotoForLater(path, time, audioPath, latitude, longitude, altitude);
        }
    }

    private void uploadNewPhoto(String path, long time, String audioPath) {
        executor.execute(() -> {
            List<ImageEntity> history = db2.imageDao().getAll();
            if (history != null && !history.isEmpty()) {
                synchronized (uploadLock) {
                    for (ImageEntity image : history) {
                        uploadPhoto(image.path, image.time, lastKnownLocation,
                                image.user, image.audioPath, image.project,
                                image.turbineId, image.partId, image.imageSource);
                    }
                }
            }
            db2.imageDao().deleteAll();

            uploadPhoto(path, time, lastKnownLocation, user,
                    audioPath, projectId, turbineId, partId, ChooseImageSource);
        });
    }

    private void queuePhotoForLater(String path, long time, String audioPath,
                                    double latitude, double longitude, double altitude) {
        executor.execute(() -> {
            db2.imageDao().insert(new ImageEntity(path, time, latitude, longitude, altitude,
                    user, audioPath, projectId, partId, partName, turbineId, turbineName, false,
                    Temperator, Humidity, Weather, ChooseImageSource));
        });
    }

    private void uploadPhoto(String filePath, long time, Location location, String user,
                             String audioPath, String project, String turbineId,
                             String partId, String imageSource) {
        synchronized (uploadLock) {
            if (isUploading) {
                queuePhotoForLater(filePath, time, audioPath,
                        location != null ? location.getLatitude() : 0,
                        location != null ? location.getLongitude() : 0,
                        location != null ? location.getAltitude() : 0);
                return;
            }
        }

        executor.execute(() -> {
            try {
                File imageFile = new File(filePath);
                if (!imageFile.exists()) {
                    return;
                }

                double latitude = location != null ? location.getLatitude() : 0;
                double longitude = location != null ? location.getLongitude() : 0;
                double altitude = location != null ? location.getAltitude() : 0;

//            未设置部件id时调用批量上传项目文件的接口
                HttpUrl httpUrl = null;
                if (partId.isEmpty()) {
                    httpUrl = HttpUrl.parse(RetrofitClient.BASE_URL + "image/" + project + "/" + imageSource + "/upload");
                } else {
                    httpUrl = HttpUrl.parse(RetrofitClient.BASE_URL + "image/" + imageSource + "/upload/" + partId);
                }
                // 构建请求URL
                HttpUrl.Builder urlBuilder = httpUrl
                        .newBuilder()
                        .addQueryParameter("collectorId",UserId)
                        .addQueryParameter("collectorName", user)
                        .addQueryParameter("humidness", String.valueOf(Humidity))
                        .addQueryParameter("shootingDistance", String.valueOf(0)) // 根据需要设置实际值
                        .addQueryParameter("temperatureMax", String.valueOf(Temperator))
                        .addQueryParameter("temperatureMin", String.valueOf(Temperator))
                        .addQueryParameter("weather", Weather)
                        .addQueryParameter("windLevel", String.valueOf(0)); // 根据需要设置实际值

                // 创建请求体
                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("file", imageFile.getName(),
                                RequestBody.create(imageFile, MediaType.parse("image/*")))
                        .build();

                Request request = new Request.Builder()
                        .url(urlBuilder.build())
                        .post(requestBody)
                        .addHeader("Authorization", token)
                        .addHeader("Content-Type", "application/x-www-form-urlencoded")
                        .build();

                try (Response response = httpClient.newCall(request).execute()) {
                    if (response.isSuccessful()) {
                        // 解析响应数据
                        String responseData = response.body().string();
                        JSONObject jsonResponse = new JSONObject(responseData);
                        JSONObject data = jsonResponse.optJSONObject("data");
                        System.out.println(responseData);
                        String imageId = data != null ? data.optString("imageId") : "";
                        dataManager.setImageId(imageId);
                        dataManager.setOthermsg("partid:"+partId+"\n"+"imageid:"+imageId+"\n"+"response:"+responseData);
                        db.imageDao().insert(new ImageEntity(filePath, time, latitude, longitude, altitude,
                                user, audioPath, project, partId, partName, turbineId, turbineName, true,
                                Temperator, Humidity, Weather, ChooseImageSource));

                        totalUploadedCount++;
                        updateNotification(imageId);
                        Intent intent = new Intent("RESPONSE_ACTION");
                        intent.putExtra("response", response.toString());
                        sendBroadcast(intent);
                        long currentTime = System.currentTimeMillis();
                        if (currentTime - lastSuccessToastTime > TOAST_THROTTLE_INTERVAL) {
                            BackgroundToast.show(this, "图片上传成功，已上传" + totalUploadedCount + "张");
                            lastSuccessToastTime = currentTime;
                        }
                    } else {
                        db2.imageDao().insert(new ImageEntity(filePath, time, latitude, longitude, altitude,
                                user, audioPath, project, partId, partName, turbineId, turbineName, true,
                                Temperator, Humidity, Weather, ChooseImageSource));
                        dataManager.setImageId("-1");
                    }
                }
            } catch (Exception e) {
                db2.imageDao().insert(new ImageEntity(filePath, time, 0, 0, 0,
                        user, audioPath, project, partId, partName, turbineId, turbineName, true,
                        Temperator, Humidity, Weather, ChooseImageSource));
                dataManager.setImageId("-1");
            }
        });
    }

    private void updateNotification(String msg) {
        String content = "已成功上传 " + totalUploadedCount + " 张照片"+msg;
        Notification notification = buildNotification("照片上传服务运行中", content);
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        if (manager != null) {
            manager.notify(NOTIFICATION_ID, notification);
        }
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm == null) return false;

        NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
        return capabilities != null &&
                (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                        capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                        capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    CHANNEL_ID,
                    "照片上传服务",
                    NotificationManager.IMPORTANCE_HIGH
            );
            channel.setDescription("显示照片上传状态和进度");
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }

    private Notification buildNotification(String title, String content) {
        return new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle(title)
                .setContentText(content)
                .setSmallIcon(R.drawable.ic_upload)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setOngoing(true)
                .setOnlyAlertOnce(true)
                .addAction(createStopAction())
                .build();
    }

    private NotificationCompat.Action createStopAction() {
        Intent stopIntent = new Intent(this, NotificationReceiver.class);
        stopIntent.setAction("ACTION_STOP_SERVICE");
        PendingIntent stopPendingIntent = PendingIntent.getBroadcast(
                this,
                0,
                stopIntent,
                PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);

        return new NotificationCompat.Action(
                R.drawable.ic_stop, "停止", stopPendingIntent);
    }

    private long getLastPhotoId() {
        long id = -1;
        Cursor cursor = getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[]{"MAX(" + MediaStore.Images.Media._ID + ")"},
                null,
                null,
                null
        );

        if (cursor != null && cursor.moveToFirst()) {
            id = cursor.getLong(0);
            cursor.close();
        }
        return id;
    }
}