package com.example.myapplication.Service;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Filter;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;

import com.example.myapplication.DataBase.AppDatabase;
import com.example.myapplication.DataBase.TurbineDao;
import com.example.myapplication.R;
import com.example.myapplication.api.TurbineApiService;
import com.example.myapplication.model.ApiResponse;
import com.example.myapplication.model.Turbine;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class FloatingWindowService extends Service {
    private static final String CHANNEL_ID = "FloatingWindowChannel";
    private static final int NOTIFICATION_ID = 1;
    private Handler mainHandler = new Handler(Looper.getMainLooper());

    private WindowManager windowManager;
    private View floatingView;

    private RadioGroup radioGroup;
    private static final String EXTRA_PROJECT_ID = "PROJECT_ID";
    private String lastUnit = "";
    private int lastBlade = -1;
    private String lastUnitName = "";
    private AppDatabase database;
    private TurbineDao turbineDao;
    private AutoCompleteTextView actvUnit;
    private ArrayAdapter<Turbine> turbineAdapter;
    private String projectID;
    public static boolean isFloatingWindowShowing = false;

    @SuppressLint("SetTextI18n")
    @Override
    public void onCreate() {
        super.onCreate();
        createNotificationChannel();
        database = AppDatabase.getDatabase(this);
        turbineDao = database.turbineDao();
        showFloatingWindow();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null && intent.hasExtra(EXTRA_PROJECT_ID)) {
            projectID = intent.getStringExtra(EXTRA_PROJECT_ID);
        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    CHANNEL_ID,
                    "悬浮窗服务通道",
                    NotificationManager.IMPORTANCE_LOW
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
    }

    private void showFloatingWindow() {
        // 创建前台服务通知
        isFloatingWindowShowing = true;
        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("悬浮窗服务运行中")
                .setContentText("正在显示悬浮提示框")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();

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

        // 创建悬浮窗视图
        floatingView = LayoutInflater.from(this).inflate(R.layout.floating_window, null);

        // 设置窗口参数
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                        WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                        WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.START;
        params.x = 100;
        params.y = 100;

        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        windowManager.addView(floatingView, params);

        // 初始化视图
        actvUnit = floatingView.findViewById(R.id.actvUnit);
        setupTurbineDropdown();
        radioGroup = floatingView.findViewById(R.id.radioGroup);

        // 设置关闭按钮点击事件
        View btnClose = floatingView.findViewById(R.id.btnClose);
        btnClose.setOnClickListener(v -> {
            // 震动反馈
            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            if (vibrator != null && vibrator.hasVibrator()) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    vibrator.vibrate(VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE));
                } else {
                    vibrator.vibrate(50);
                }
            }
            closeFloatingWindow();
        });

        setupDragListener(params);
        setupValueChangeListeners();
        setupAutoCompleteBehavior();
    }

    private void closeFloatingWindow() {
        if (floatingView != null && floatingView.getWindowToken() != null) {
            // 添加淡出动画
            floatingView.animate()
                    .alpha(0f)
                    .setDuration(200)
                    .withEndAction(() -> {
                        removeFloatingView();
                        stopSelf();
                    })
                    .start();
        } else {
            removeFloatingView();
            stopSelf();
        }
        isFloatingWindowShowing = false;
    }

    private synchronized void removeFloatingView() {
        try {
            if (windowManager != null && floatingView != null && floatingView.getWindowToken() != null) {
                windowManager.removeView(floatingView);
            }
        } catch (IllegalArgumentException e) {
            Log.e("FloatingWindow", "View already removed", e);
        } finally {
            floatingView = null;
        }
    }
    private void setupAutoCompleteBehavior() {
        actvUnit.setFocusableInTouchMode(true);
        actvUnit.setFocusable(true);
        actvUnit.setOnClickListener(v -> {
            if (turbineAdapter.getCount() > 0) {
                actvUnit.showDropDown();
            } else {
                actvUnit.requestFocus();
                showSoftInputDelayed(actvUnit);
            }
        });

        actvUnit.setOnFocusChangeListener((v, hasFocus) -> {
            if (hasFocus && !TextUtils.isEmpty(actvUnit.getText()) && turbineAdapter.getCount() > 0) {
                actvUnit.postDelayed(() -> actvUnit.showDropDown(), 100);
            }
        });

        actvUnit.setOnKeyListener((v, keyCode, event) -> {
            if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
                if (turbineAdapter.getCount() > 0) {
                    actvUnit.showDropDown();
                } else {
                    hideSoftInput(actvUnit);
                }
                return true;
            }
            return false;
        });
    }

    private void showSoftInputDelayed(View view) {
        view.postDelayed(() -> {
            InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            if (imm != null) {
                imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
            }
        }, 200);
    }

    private void hideSoftInput(View view) {
        InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }

    private void setupDragListener(WindowManager.LayoutParams params) {
        View dragHandle = floatingView.findViewById(R.id.floatingContainer);

        dragHandle.setOnTouchListener(new View.OnTouchListener() {
            private int initialX, initialY;
            private float initialTouchX, initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // 检查是否点击在关闭按钮上
                if (!isViewAttached()) {
                    return false;
                }
                Rect closeButtonRect = new Rect();
                floatingView.findViewById(R.id.btnClose).getGlobalVisibleRect(closeButtonRect);
                if (closeButtonRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                    return false;
                }

                // 检查是否点击在输入区域
                Rect inputRect = new Rect();
                actvUnit.getGlobalVisibleRect(inputRect);
                if (inputRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                    return false;
                }

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        initialX = params.x;
                        initialY = params.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        return true;

                    case MotionEvent.ACTION_MOVE:
                        params.x = initialX + (int)(event.getRawX() - initialTouchX);
                        params.y = initialY + (int)(event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(floatingView, params);
                        return true;

                    case MotionEvent.ACTION_UP:
                        return true;
                }
                return false;
            }
        });
    }

    private void setupTurbineDropdown() {
        turbineAdapter = new ArrayAdapter<Turbine>(this,
                R.layout.dropdown_item, R.id.text1) {
            @NonNull
            @Override
            public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                TextView textView = view.findViewById(R.id.text1);
                Turbine turbine = getItem(position);
                if (turbine != null) {
                    textView.setText(String.format(turbine.turbineName));
                    textView.setSingleLine(false);
                    textView.setMaxLines(3);
                }
                return view;
            }

            @Override
            public Filter getFilter() {
                return new Filter() {
                    @Override
                    protected FilterResults performFiltering(CharSequence constraint) {
                        FilterResults results = new FilterResults();
                        List<Turbine> filtered;
                        if (TextUtils.isEmpty(constraint)) {
                            filtered = turbineDao.getTurbinesByProject(projectID);
                        } else {
                            filtered = turbineDao.searchTurbines(projectID, "%" + constraint + "%");
                        }

                        results.values = filtered;
                        results.count = filtered.size();
                        return results;
                    }

                    @Override
                    protected void publishResults(CharSequence constraint, FilterResults results) {
                        clear();
                        if (results.count > 0) {
                            addAll((List<Turbine>) results.values);
                            notifyDataSetChanged();
                            if (actvUnit.hasFocus() && !TextUtils.isEmpty(constraint)) {
                                actvUnit.post(() -> actvUnit.showDropDown());
                            }
                        } else {
                            notifyDataSetInvalidated();
                        }
                    }
                };
            }
        };

        actvUnit.setAdapter(turbineAdapter);
        actvUnit.setThreshold(0);
        actvUnit.setDropDownHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        actvUnit.setDropDownVerticalOffset(10);

        actvUnit.addTextChangedListener(new TextWatcher() {
            @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override public void afterTextChanged(Editable s) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String input=s.toString().trim();
                lastUnit = input;
                lastUnitName = input;
                if (turbineAdapter.getCount() > 0 && !TextUtils.isEmpty(input)) {
                    for (int i = 0; i < turbineAdapter.getCount(); i++) {
                        Turbine turbine = turbineAdapter.getItem(i);
                        if (turbine != null && turbine.turbineName.equalsIgnoreCase(input)) {
                            lastUnit = turbine.turbineId;
                            lastUnitName = turbine.turbineName;
                            break;
                        }
                    }
                }
                checkAndSendUpdate();
            }
        });

        loadTurbines();
    }

    private void loadTurbines() {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {
            try {
                List<Turbine> localTurbines = turbineDao.getTurbinesByProject(projectID);

                if (localTurbines.isEmpty() || isNetworkAvailable()) {
                    fetchTurbinesFromApi();
                } else {
                    mainHandler.post(() -> updateTurbineList(localTurbines));
                }
            } catch (Exception e) {
                Log.e("TurbineLoad", "加载机组数据失败", e);
            }
        });
    }

    private void updateTurbineList(List<Turbine> turbines) {
        turbineAdapter.clear();
        if (!turbines.isEmpty()) {
            turbineAdapter.addAll(turbines);
        }

        if (!TextUtils.isEmpty(actvUnit.getText())) {
            turbineAdapter.getFilter().filter(actvUnit.getText());
        }
    }

    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 fetchTurbinesFromApi() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://pms.dtyx.net:9158/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        TurbineApiService service = retrofit.create(TurbineApiService.class);
        Call<ApiResponse<List<Turbine>>> call = service.getTurbineList(projectID);

        call.enqueue(new Callback<ApiResponse<List<Turbine>>>() {
            @Override
            public void onResponse(Call<ApiResponse<List<Turbine>>> call, Response<ApiResponse<List<Turbine>>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    ApiResponse<List<Turbine>> apiResponse = response.body();

                    if (apiResponse.getCode() == 200 && apiResponse.getData() != null) {
                        List<Turbine> turbines = apiResponse.getData();
                        Log.d("API_SUCCESS", "Fetched " + turbines.size() + " turbines");

                        new Thread(() -> {
                            try {
                                turbineDao.deleteByProjectId(projectID);
                                for (Turbine turbine : turbines) {
                                    turbine.projectId = projectID;
                                }
                                turbineDao.insertAll(turbines);

                                mainHandler.post(() -> {
                                    updateTurbineList(turbines);
                                    showToast("数据加载成功");
                                });
                            } catch (Exception e) {
                                Log.e("DB_ERROR", "保存数据失败", e);
                                mainHandler.post(() -> showToast("保存数据失败: " + e.getMessage()));
                            }
                        }).start();
                    } else {
                        String errorMsg = "服务器错误: " + apiResponse.getCode() + " - " + apiResponse.getMsg();
                        Log.e("API_ERROR", errorMsg);
                        mainHandler.post(() -> showToast(errorMsg));
                    }
                } else {
                    String errorMsg = "请求失败: HTTP " + response.code();
                    if (response.errorBody() != null) {
                        try {
                            errorMsg += "\n" + response.errorBody().string();
                        } catch (IOException e) {
                            Log.e("API_ERROR", "解析错误信息失败", e);
                        }
                    }
                    Log.e("API_ERROR", errorMsg);
                    String finalErrorMsg = errorMsg;
                    mainHandler.post(() -> showToast(finalErrorMsg));
                }
            }

            @Override
            public void onFailure(Call<ApiResponse<List<Turbine>>> call, Throwable t) {
                String errorMsg = "网络错误: " + t.getMessage();
                Log.e("NETWORK_ERROR", errorMsg, t);
                mainHandler.post(() -> showToast(errorMsg));
            }
        });
    }

    private void showToast(String message) {
        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
    }

    private void setupValueChangeListeners() {
        actvUnit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {}

            @Override
            public void afterTextChanged(Editable s) {}
        });

        actvUnit.setOnItemClickListener((parent, view, position, id) -> {
            Turbine selected = turbineAdapter.getItem(position);
            if (selected != null) {
                lastUnit = selected.turbineId;
                lastUnitName = selected.turbineName;
                actvUnit.setText(selected.turbineName);
                checkAndSendUpdate();
            }
        });

        radioGroup.setOnCheckedChangeListener((group, checkedId) -> {
            int currentBlade = 0;
            if (checkedId != -1) {
                RadioButton radioButton = floatingView.findViewById(checkedId);
                currentBlade = Integer.parseInt(radioButton.getText().toString());
            }

            if (currentBlade != lastBlade) {
                lastBlade = currentBlade;
                checkAndSendUpdate();
            }
        });
    }

    private void checkAndSendUpdate() {
        if (!lastUnit.isEmpty() && lastBlade != -1) {
            sendUpdateBroadcast();
            highlightChanges();
        }
    }

    private void sendUpdateBroadcast() {
        Intent intent = new Intent("com.example.myapplication.UPDATE_VALUES");
        intent.putExtra("unit", lastUnit);
        intent.putExtra("blade", lastBlade);
        intent.putExtra("unitName", lastUnitName);
        intent.setPackage(getPackageName());
        sendBroadcast(intent);
    }

    private void highlightChanges() {
        int originalColor = actvUnit.getSolidColor();
        actvUnit.setBackgroundColor(Color.YELLOW);
        radioGroup.setBackgroundColor(Color.YELLOW);

        new Handler().postDelayed(() -> {
            actvUnit.setBackgroundColor(originalColor);
            radioGroup.setBackgroundColor(Color.TRANSPARENT);
        }, 300);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        hideSoftInput(actvUnit);
        actvUnit.dismissDropDown();
        isFloatingWindowShowing = false;

        // 直接调用移除方法，不再重复执行stopSelf()
        removeFloatingView();

        mainHandler.removeCallbacksAndMessages(null);
    }
    private boolean isViewAttached() {
        return floatingView != null
                && floatingView.getWindowToken() != null
                && windowManager != null;
    }
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public static void closeFloatingWindow(Context context) {
        isFloatingWindowShowing = false;
        Intent serviceIntent = new Intent(context, FloatingWindowService.class);
        context.stopService(serviceIntent);
    }
}