package com.auto.clicker.autoclicker.view;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.text.InputType;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.auto.clicker.autoclicker.R;
import com.auto.clicker.autoclicker.data.Event;
import com.auto.clicker.autoclicker.data.EventWrapper;
import com.auto.clicker.autoclicker.data.PointEvent;
import com.auto.clicker.autoclicker.data.PositionUpdater;
import com.auto.clicker.autoclicker.data.SlideEvent;
import com.auto.clicker.autoclicker.room.SolutionWithEventsAndPoints;
import com.auto.clicker.autoclicker.room.entity.EventEntity;
import com.auto.clicker.autoclicker.room.entity.Solution;
import com.auto.clicker.autoclicker.room.entity.TouchPoint;
import com.auto.clicker.autoclicker.room.repository.EventRepository;
import com.auto.clicker.autoclicker.service.AutoClickService;
import com.auto.clicker.autoclicker.service.ForegroundService;
import com.auto.clicker.autoclicker.util.FloatingTabDialogManager;
import com.auto.clicker.autoclicker.util.PrefUtils;
import com.auto.clicker.autoclicker.util.ScreenUtils;
import com.auto.clicker.autoclicker.util.ViewUtils;

import java.util.ArrayList;
import java.util.List;

public class FloatingViewManager {
    private static final String TAG = "FloatingViewManager";
    public static final long DEBOUNCE_INTERVAL = 500;
    public static final int TOUCH_POINT_SIZE = 100;

    private final Context context;
    private final WindowManager windowManager;
    private final int screenWidth;
    private final int screenHeight;

    private final List<EventWrapper> runtimeEvents = new ArrayList<>();
    private int eventOrderCounter = 1;

    private LinearLayout multipleControlBarView;
    private WindowManager.LayoutParams multipleControlBarParams;

    private boolean isMultipleRunning = false;
    private long lastToggleTime = 0;

    private boolean areEventsVisible = true;

    private FloatingTabDialogManager floatingTabDialogManager;

    private EventRepository eventRepository;

    public FloatingViewManager(Context context) {
        this.context = context;
        this.windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Point screenSize = ScreenUtils.getScreenSize(context);
        this.screenWidth = screenSize.x;
        this.screenHeight = screenSize.y;
        this.floatingTabDialogManager = new FloatingTabDialogManager(context);
        this.floatingTabDialogManager.setFloatingViewManager(this);
        this.eventRepository = new EventRepository(context.getApplicationContext());
        registerBroadcastReceiver();
    }

    public void showFloatingViews(int mode) throws SecurityException {
        if (!Settings.canDrawOverlays(context)) {
            throw new SecurityException("需要悬浮窗许可");
        }

        removeFloatingViews();
        showMultipleModeViews(mode);

        Log.d(TAG, "添加悬浮窗, 模式 = " + mode);
    }

    private void showMultipleModeViews(int mode) {
        initMultipleTouchPointView();
        initMultipleControlBar();

        if (multipleControlBarView != null) {
            windowManager.addView(multipleControlBarView, multipleControlBarParams);
        }
    }

    private void initMultipleTouchPointView() {
        runtimeEvents.clear();
        eventOrderCounter = 1;
    }

    @SuppressLint("ClickableViewAccessibility")
    private void initMultipleControlBar() {
        multipleControlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.multiple_control_bar, null);
        multipleControlBarParams = createControlBarParams();

        setupDraggableView(multipleControlBarView, multipleControlBarParams, this::updateMoreControlBarPosition);

        setupControlButtons(multipleControlBarView);
    }

    private WindowManager.LayoutParams createControlBarParams() {
        // 创建控制栏的悬浮窗参数
        int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                WindowManager.LayoutParams.TYPE_PHONE;

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                overlayType,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                PixelFormat.TRANSLUCENT
        );
        params.gravity = Gravity.TOP | Gravity.START;
        params.x = 0;
        params.y = 200;
        return params;
    }

    @SuppressLint("ClickableViewAccessibility")
    private void setupDraggableView(View view, WindowManager.LayoutParams params, PositionUpdater positionUpdater) {
        view.setOnTouchListener(new View.OnTouchListener() {
            private float lastX, lastY;
            private float paramX, paramY;
            private boolean isDragging = false;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isMultipleRunning) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        v.performClick();
                        return true;
                    }
                    return false;
                }

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        lastX = event.getRawX();
                        lastY = event.getRawY();
                        paramX = params.x;
                        paramY = params.y;
                        isDragging = true;
                        return true;

                    case MotionEvent.ACTION_MOVE:
                        if (isDragging) {
                            float dx = event.getRawX() - lastX;
                            float dy = event.getRawY() - lastY;
                            positionUpdater.update(paramX, paramY, dx, dy);
                            return true;
                        }
                        break;

                    case MotionEvent.ACTION_UP:
                        isDragging = false;
                        v.performClick();
                        return true;
                }
                return false;
            }
        });
    }

    private void updateMoreControlBarPosition(float paramX, float paramY, float dx, float dy) {
        Point constrainedPoint = ViewUtils.constrainToScreen(
                paramX + dx, paramY + dy,
                screenWidth - multipleControlBarView.getWidth(),
                screenHeight - multipleControlBarView.getHeight());
        multipleControlBarParams.x = constrainedPoint.x;
        multipleControlBarParams.y = constrainedPoint.y;
        windowManager.updateViewLayout(multipleControlBarView, multipleControlBarParams);
    }

    private void setupControlButtons(LinearLayout controlBar) {
        ImageView playButton = controlBar.findViewById(R.id.play_button);
        ImageView addButton = controlBar.findViewById(R.id.add_button);
        ImageView removeButton = controlBar.findViewById(R.id.remove_button);
        ImageView slideButton = controlBar.findViewById(R.id.slide_button);
        ImageView saveButton = controlBar.findViewById(R.id.save_button);
        ImageView eyeButton = controlBar.findViewById(R.id.eye_button);
        ImageView settingButton = controlBar.findViewById(R.id.settings_button);
        ImageView closeButton = controlBar.findViewById(R.id.close_button);

        playButton.setOnClickListener(v -> toggleMultipleClicking());
        addButton.setOnClickListener(v -> addPointEvent());
        removeButton.setOnClickListener(v -> removeLastEvent());
        slideButton.setOnClickListener(v -> addSlideEvent());

        saveButton.setOnClickListener(v -> {
            // 直接调用 FloatingTabDialogManager 来显示悬浮弹窗
            // 记得要检查悬浮窗权限！
            if (!Settings.canDrawOverlays(context)) {
                Toast.makeText(context, "需要悬浮窗权限才能显示弹窗", Toast.LENGTH_LONG).show();
                // 引导用户去开启权限
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + context.getPackageName()));
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
            } else {
                floatingTabDialogManager.showFloatingTabDialog();
            }
        });

        eyeButton.setOnClickListener(v -> {
            areEventsVisible = !areEventsVisible;
            toggleEventsVisibility(areEventsVisible);
            if (areEventsVisible) {
                eyeButton.setImageResource(R.drawable.eye);
            } else {
                eyeButton.setImageResource(R.drawable.hide_eye);
            }
        });
        settingButton.setOnClickListener(v -> showInputDialog());
        closeButton.setOnClickListener(v -> closeFloatingViews());
    }

    private void toggleMultipleClicking() {
        if (isDebounced()) return;

        AutoClickService service = AutoClickService.getInstance();
        if (service == null) {
            handleMissingService(); // 无障碍服务未开启
            return;
        }

        if (runtimeEvents.isEmpty()) {
            Toast.makeText(context, "请添加一个触摸点或者滑动事件", Toast.LENGTH_SHORT).show();
            return;
        }

        if (isMultipleRunning) {
            stopMultiClicking(service); // 停止点击
        } else {
            startMultiClicking(service); // 开始点击
        }

        isMultipleRunning = !isMultipleRunning;
        Log.d(TAG, "多点点击服务状态: " + service.isClicking());
    }

    @SuppressLint("ClickableViewAccessibility")
    private void addPointEvent() {
        if (isMultipleRunning) {
            Toast.makeText(context, "请停止点击", Toast.LENGTH_SHORT).show();
            return;
        }

        // 创建点击点视图
        TextView pointView = createTouchPointView(String.valueOf(eventOrderCounter));

        // 设置位置居中
        WindowManager.LayoutParams params = createTouchPointParams();
        params.x = screenWidth / 2 - TOUCH_POINT_SIZE / 2;
        params.y = screenHeight / 2 - TOUCH_POINT_SIZE / 2;

        // 包装为事件对象
        PointEvent pointEvent = new PointEvent(eventOrderCounter, params.x, params.y);
        pointEvent.setView(pointView);
        pointEvent.setLayoutParams(params);

        runtimeEvents.add(new EventWrapper(EventWrapper.EventType.POINT, pointEvent, eventOrderCounter));
        eventOrderCounter++;

        Log.d(TAG, "addPoint runtimeEvents: " + runtimeEvents.size() + "   eventOrderCounter :" + eventOrderCounter);

        // 设置拖动功能并添加到窗口
        setupDraggablePoint(pointView, params, pointEvent);
        windowManager.addView(pointView, params);
        updateServicePositions();
    }

    @SuppressLint("ClickableViewAccessibility")
    private void addSlideEvent() {
        if (isMultipleRunning) {
            Toast.makeText(context, "请先停止点击", Toast.LENGTH_SHORT).show();
            return;
        }

        // 创建起点
        TextView startPointView = createTouchPointView(String.valueOf(eventOrderCounter));
        WindowManager.LayoutParams startParams = createTouchPointParams();
        startParams.x = screenWidth / 2 - 100;
        startParams.y = screenHeight / 2 - 50;
        PointEvent startPointEvent = new PointEvent(eventOrderCounter, startParams.x, startParams.y);
        startPointEvent.setView(startPointView);
        startPointEvent.setLayoutParams(startParams);

        // 创建终点
        TextView endPointView = createTouchPointView(String.valueOf(eventOrderCounter));
        WindowManager.LayoutParams endParams = createTouchPointParams();
        endParams.x = screenWidth / 2 + 100;
        endParams.y = screenHeight / 2 - 50;
        PointEvent endPointEvent = new PointEvent(eventOrderCounter, endParams.x, endParams.y);
        startPointEvent.setView(endPointView);
        startPointEvent.setLayoutParams(endParams);

        // 创建滑动连线
        ConnectingLineView lineView = new ConnectingLineView(context);
        WindowManager.LayoutParams lineParams = createLineViewParams();

        SlideEvent slideEvent = new SlideEvent(eventOrderCounter, startPointEvent, endPointEvent);
        slideEvent.setLineView(lineView);
        slideEvent.setLineParams(lineParams);

        runtimeEvents.add(new EventWrapper(EventWrapper.EventType.SLIDE, slideEvent, eventOrderCounter));
        eventOrderCounter++;

        Log.d(TAG, "addSlide runtimeEvents: " + runtimeEvents.size() + "   eventOrderCounter :" + eventOrderCounter);

        // 设置滑动点可拖动
        setupDraggableSlidePoint(startPointView, startParams, startPointEvent, slideEvent);
        setupDraggableSlidePoint(endPointView, endParams, endPointEvent, slideEvent);

        // 添加视图到窗口
        windowManager.addView(lineView, lineParams);
        windowManager.addView(startPointView, startParams);
        windowManager.addView(endPointView, endParams);

        updateLinePosition(slideEvent); // 更新线的位置
        updateServicePositions();
    }

    public void toggleEventsVisibility(boolean show) {
        for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
            // 获取事件的视图
            View viewToToggle = null;
            if (wrapper.getType() == EventWrapper.EventType.POINT) {
                viewToToggle = createTouchPointView(String.valueOf(wrapper.getEvent().getId()));
            } else if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
                View startPointView = getView(show, wrapper,context);

                WindowManager.LayoutParams startParams = (WindowManager.LayoutParams) startPointView.getLayoutParams();
                if (show) {
                    startParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                } else {
                    startParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                }
                windowManager.updateViewLayout(startPointView, startParams);
                continue;
            }

            if (viewToToggle != null) {
                if (show) {
                    viewToToggle.setAlpha(1.0f);
                } else {
                    viewToToggle.setAlpha(0.0f);
                }
                WindowManager.LayoutParams params = (WindowManager.LayoutParams) viewToToggle.getLayoutParams();
                if (show) {
                    params.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                } else {
                    params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
                }
                windowManager.updateViewLayout(viewToToggle, params);
            }
        }
    }

    @NonNull
    private View getView(boolean show, EventWrapper wrapper,Context context) {
        SlideEvent slideEvent = (SlideEvent) wrapper.getEvent();
        // 假设你只隐藏/显示点，线也需要同步
        View startPointView =  createTouchPointView(String.valueOf(slideEvent.getStartPoint().getId()));
        View endPointView = createTouchPointView(String.valueOf(slideEvent.getEndPoint().getId()));
        View lineView = new ConnectingLineView(context);

        if (show) {
            // 如果是显示，可能需要重新添加或设置可见性
            // 这里假设你只是更新透明度，如果之前移除了，则需要重新addView
            startPointView.setAlpha(1.0f);
            endPointView.setAlpha(1.0f);
            lineView.setAlpha(1.0f); // 如果线视图也需要隐藏/显示
        } else {
            startPointView.setAlpha(0.0f);
            endPointView.setAlpha(0.0f);
            lineView.setAlpha(0.0f); // 隐藏线视图
        }
        return startPointView;
    }

    private void removeLastEvent() {
        if (isMultipleRunning) {
            Toast.makeText(context, "请先停止点击", Toast.LENGTH_SHORT).show();
            return;
        }

        if (runtimeEvents.isEmpty()) {
            Toast.makeText(context, "没有更多的事件需要删除", Toast.LENGTH_SHORT).show();
            return;
        }

        // 移除最后一个事件
        Event lastEvent = runtimeEvents.remove(runtimeEvents.size() - 1).getEvent();
        removeEvent(lastEvent);
        eventOrderCounter--;
        updateServicePositions();
    }

    private void closeFloatingViews() {
        // 停止自动点击服务
        AutoClickService service = AutoClickService.getInstance();
        if (service != null) {
            service.stopClicking();
        } else {
            Log.d(TAG, "自动点击服务没有初始化");
            Toast.makeText(context, "请同意无障碍服务权限", Toast.LENGTH_SHORT).show();
        }

        updateTouchPointsBackground(R.drawable.ring_has_bg);
        removeFloatingViews(); // 移除所有悬浮窗

        context.stopService(new Intent(context, ForegroundService.class));
        PrefUtils.setFloatingShown(context, 0);

        // 发送浮窗关闭广播
        Intent intent = new Intent("com.auto.clicker.autoclicker.FLOATING_WINDOW_STATE_CHANGED");
        intent.putExtra("isShown", false);
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
    }

    private void startMultiClicking(AutoClickService service) {
        service.addMultipleClickEvents(runtimeEvents);
        service.startClicking();

        Log.d(TAG, "开始多点点击事件 " + runtimeEvents.size());
        Toast.makeText(context, "多点点击开始", Toast.LENGTH_SHORT).show();

        updateTouchPointsBackground(R.drawable.touch_point);
    }

    private void stopMultiClicking(AutoClickService service) {
        service.stopClicking();
        Toast.makeText(context, "多点点击停止", Toast.LENGTH_SHORT).show();

        updateTouchPointsBackground(R.drawable.ring_has_bg);
    }

    private WindowManager.LayoutParams createLineViewParams() {
        // 创建连接线（滑动路径）的参数，全屏不可点击
        int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                WindowManager.LayoutParams.TYPE_PHONE;

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                overlayType,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
                        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                PixelFormat.TRANSLUCENT
        );
        params.gravity = Gravity.TOP | Gravity.START;
        params.x = 0;
        params.y = 0;
        return params;
    }

    private void removeEvent(Event event) {
        try {
            // 判断类型并移除相关视图
            if (event instanceof PointEvent) {
                PointEvent pointEvent = (PointEvent) event;
                windowManager.removeView(pointEvent.getView());
            } else if (event instanceof SlideEvent) {
                SlideEvent slideEvent = (SlideEvent) event;
                windowManager.removeView(slideEvent.getStartPoint().getView());
                windowManager.removeView(slideEvent.getEndPoint().getView());
                windowManager.removeView(slideEvent.getLineView());
            }
        } catch (Exception e) {
            Log.w(TAG, "删除事件失败", e);
        }
    }

    public void removeFloatingViews() {
        try {
            // 移除点事件视图
            for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
                if (wrapper.getType() == EventWrapper.EventType.POINT) {
                    PointEvent pe = (PointEvent) wrapper.getEvent();
                    safeRemoveView(pe.getView());
                }
            }

            // 移除滑动事件视图
            for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
                if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
                    SlideEvent se = (SlideEvent) wrapper.getEvent();
                    safeRemoveView(se.getStartPoint().getView());
                    safeRemoveView(se.getEndPoint().getView());
                    safeRemoveView(se.getLineView());
                }
            }

            runtimeEvents.clear();

            if (multipleControlBarView != null) {
                safeRemoveView(multipleControlBarView);
                multipleControlBarView = null;
            }

            if (floatingTabDialogManager != null) {
                floatingTabDialogManager.removeFloatingTabDialog();
            }

            isMultipleRunning = false;
            Log.d(TAG, "悬浮窗已移除");
        } catch (Exception e) {
            Log.e(TAG, "移除悬浮窗失败", e);
            isMultipleRunning = false;
        }
    }

    private void safeRemoveView(View view) {
        try {
            windowManager.removeView(view);
        } catch (Exception e) {
            Log.w(TAG, "移除视图失败: " + view, e);
        }
    }

    private void updateTouchPointsBackground(int resourceId) {
        for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
            if (wrapper.getType() == EventWrapper.EventType.POINT) {
                PointEvent pe = (PointEvent) wrapper.getEvent();
                pe.getView().setBackgroundResource(resourceId);
            }
        }

        for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
            if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
                SlideEvent se = (SlideEvent) wrapper.getEvent();
                se.getStartPoint().getView().setBackgroundResource(resourceId);
                se.getEndPoint().getView().setBackgroundResource(resourceId);
            }
        }
    }

    private void handleMissingService() {
        Log.e(TAG, "自动点击服务没有初始化");
        Toast.makeText(context, "请在设置里同意无障碍服务", Toast.LENGTH_LONG).show();
        Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    private boolean isDebounced() {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastToggleTime < DEBOUNCE_INTERVAL) {
            return true;
        }
        lastToggleTime = currentTime;
        return false;
    }

    @SuppressLint("ClickableViewAccessibility")
    private void setupDraggablePoint(TextView point, WindowManager.LayoutParams params, PointEvent pointEvent) {
        point.setOnTouchListener(new View.OnTouchListener() {
            private float lastX, lastY;
            private float paramX, paramY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isMultipleRunning) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        v.performClick();
                        return true;
                    }
                    return false;
                }

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        lastX = event.getRawX();
                        lastY = event.getRawY();
                        paramX = params.x;
                        paramY = params.y;
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        float dx = event.getRawX() - lastX;
                        float dy = event.getRawY() - lastY;
                        Point constrainedPoint = ViewUtils.constrainToScreen(
                                paramX + dx, paramY + dy,
                                screenWidth - point.getWidth(), screenHeight - point.getHeight());
                        params.x = constrainedPoint.x;
                        params.y = constrainedPoint.y;
                        pointEvent.setX(params.x);
                        pointEvent.setY(params.y);
                        windowManager.updateViewLayout(point, params);
                        updateServicePositions();
                        return true;
                    case MotionEvent.ACTION_UP:
                        v.performClick();
                        return true;
                }
                return false;
            }
        });
    }

    @SuppressLint("ClickableViewAccessibility")
    private void setupDraggableSlidePoint(TextView point, WindowManager.LayoutParams params,
                                          PointEvent pointEvent, SlideEvent slideEvent) {
        point.setOnTouchListener(new View.OnTouchListener() {
            private float lastX, lastY;
            private float paramX, paramY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isMultipleRunning) {
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        v.performClick();
                        return true;
                    }
                    return false;
                }

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        lastX = event.getRawX();
                        lastY = event.getRawY();
                        paramX = params.x;
                        paramY = params.y;
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        float dx = event.getRawX() - lastX;
                        float dy = event.getRawY() - lastY;
                        Point constrainedPoint = ViewUtils.constrainToScreen(
                                paramX + dx, paramY + dy,
                                screenWidth - point.getWidth(), screenHeight - point.getHeight());
                        params.x = constrainedPoint.x;
                        params.y = constrainedPoint.y;
                        pointEvent.setX(params.x);
                        pointEvent.setY(params.y);
                        windowManager.updateViewLayout(point, params);

                        updateLinePosition(slideEvent);
                        updateServicePositions();
                        return true;
                    case MotionEvent.ACTION_UP:
                        v.performClick();
                        return true;
                }
                return false;
            }
        });
    }

    private void updateLinePosition(SlideEvent slideEvent) {
        PointEvent start = slideEvent.getStartPoint();
        PointEvent end = slideEvent.getEndPoint();
        ConnectingLineView lineView = slideEvent.getLineView();

        float startCenterX = start.getX() + (float) TOUCH_POINT_SIZE / 2;
        float startCenterY = start.getY() + (float) TOUCH_POINT_SIZE / 2;
        float endCenterX = end.getX() + (float) TOUCH_POINT_SIZE / 2;
        float endCenterY = end.getY() + (float) TOUCH_POINT_SIZE / 2;

        lineView.setPoints(startCenterX, startCenterY, endCenterX, endCenterY);
    }

    private TextView createTouchPointView(String label) {
        // 创建一个圆形点击点视图
        TextView touchPointView = new TextView(context);
        touchPointView.setBackgroundResource(R.drawable.ring_has_bg);
        touchPointView.setGravity(Gravity.CENTER);
        touchPointView.setText(label);
        touchPointView.setTextColor(Color.WHITE);
        touchPointView.setTextSize(19);
        return touchPointView;
    }

    private WindowManager.LayoutParams createTouchPointParams() {
        // 创建点击点的布局参数
        int overlayType = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                WindowManager.LayoutParams.TYPE_PHONE;

        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                TOUCH_POINT_SIZE, TOUCH_POINT_SIZE,
                overlayType,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
                        WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                PixelFormat.TRANSLUCENT
        );
        params.gravity = Gravity.TOP | Gravity.START;
        return params;
    }

    private void updateServicePositions() {
        // 更新服务中记录的位置
        AutoClickService service = AutoClickService.getInstance();
        if (service != null) {
            service.addMultipleClickEvents(runtimeEvents);
        }
    }

    public void showInputDialog() {
        EditText input = new EditText(context);
        input.setInputType(InputType.TYPE_CLASS_NUMBER);
        input.setHint("输入点击间隔（ms）");
        input.setFocusableInTouchMode(true);

        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        builder.setTitle("设置点击间隔")
                .setView(input)
                .setPositiveButton("确定", (dialog, which) -> {
                    String value = input.getText().toString();
                    try {
                        long interval = Long.parseLong(value);
                        AutoClickService service = AutoClickService.getInstance();
                        if (service != null) {
                            service.setClickInterval(interval);
                        } else {
                            Log.w("InputDialog", "AutoClickService 未初始化");
                        }
                    } catch (NumberFormatException e) {
                        Toast.makeText(context, "无效输入", Toast.LENGTH_SHORT).show();
                    }
                    dialog.dismiss();
                })
                .setNegativeButton("取消", (dialog, which) -> dialog.dismiss());

        AlertDialog dialog = builder.create();

        if (!(context instanceof Activity)) {
            if (dialog.getWindow() != null) {
                dialog.getWindow().setType(
                        Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
                                WindowManager.LayoutParams.TYPE_PHONE
                );
            }
        }

        dialog.show();

        input.requestFocus();
        input.post(() -> {
            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm != null) {
                imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
            }
        });
    }

    public void flashTouchPoint(int index) {
        if (index >= 0 && index < runtimeEvents.size()) {
            Event event = runtimeEvents.get(index).getEvent();
            Log.d(TAG, "index : " + index);

            if (event instanceof PointEvent) {
                flashView(((PointEvent) event).getView());
            } else if (event instanceof SlideEvent) {
                SlideEvent slide = (SlideEvent) event;
                flashView(slide.getStartPoint().getView());
                flashView(slide.getEndPoint().getView());
            }
        }
    }

    private void flashView(View view) {
        if (view != null) {
            view.animate()
                    .alpha(0.3f)
                    .setDuration(100)
                    .withEndAction(() -> view.animate()
                            .alpha(1.0f)
                            .setDuration(100)
                            .start())
                    .start();
        }
    }

    private void registerBroadcastReceiver() {
        LocalBroadcastManager.getInstance(context).registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        if ("com.auto.clicker.autoclicker.FLASH_TOUCH_POINT".equals(intent.getAction())) {
                            int index = intent.getIntExtra("index", -1);
                            flashTouchPoint(index);
                        }
                    }
                },
                new IntentFilter("com.auto.clicker.autoclicker.FLASH_TOUCH_POINT")
        );
    }

    public void saveCurrentEventsAsSolution(String solutionName, EventRepository.RepositoryCallback<Long> callback) {
        if (solutionName == null || solutionName.trim().isEmpty()) {
            Toast.makeText(context, "方案名称不能为空", Toast.LENGTH_SHORT).show();
            // 在这里调用回调的 onError，或者 onComplete 返回一个表示失败的值
            // 确保 FloatingTabDialogManager 收到反馈
            if (callback != null) {
                callback.onComplete(-1L); // 返回一个表示失败的值
            }
            return;
        }
        if (runtimeEvents.isEmpty()) {
            Toast.makeText(context, "当前没有事件可以保存", Toast.LENGTH_SHORT).show();
            if (callback != null) {
                callback.onComplete(-1L); // 返回一个表示失败的值
            }
            return;
        }

        Solution newSolution = new Solution(solutionName);
        eventRepository.insertSolutionWithEvents(newSolution, runtimeEvents, new EventRepository.RepositoryCallback<Long>() {
            @Override
            public void onComplete(Long solutionId) {
                // 成功保存，Toast 可以在这里显示，也可以在 FloatingTabDialogManager 中显示
                // 为了职责分离，建议在这里显示一个简单的"保存成功" Toast，然后让 FloatingTabDialogManager 决定是否关闭
                // Toast.makeText(context, "方案 '" + solutionName + "' 保存成功！", Toast.LENGTH_SHORT).show();
                // 保存失败，Toast 可以在这里显示
                // Toast.makeText(context, "保存方案失败。", Toast.LENGTH_SHORT).show();
                if (callback != null) {
                    callback.onComplete(solutionId); // 将结果传递给调用者
                }
            }

            @Override
            public void onError(Exception e) {
                Log.e(TAG, "保存方案失败: " + e.getMessage(), e);
                Toast.makeText(context, "保存方案失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                if (callback != null) {
                    callback.onError(e); // 将错误传递给调用者
                }
            }
        });
    }

    public void loadSolution(long solutionId) {
        eventRepository.getSolutionWithEventsAndPoints(solutionId, new EventRepository.RepositoryCallback<SolutionWithEventsAndPoints>() {
            @Override
            public void onComplete(SolutionWithEventsAndPoints solutionData) {
                if (solutionData != null && solutionData.events != null) {
                    removeFloatingViews();
                    runtimeEvents.clear();
                    eventOrderCounter = 1;

                    for (SolutionWithEventsAndPoints.EventWithPoints eventWithPoints : solutionData.events) {
                        EventEntity eventEntity = eventWithPoints.eventEntity;
                        EventWrapper.EventType type = EventWrapper.EventType.valueOf(eventEntity.eventType);

                        if (type == EventWrapper.EventType.POINT) {
                            TouchPoint clickPoint = eventWithPoints.clickTouchPoint;
                            if (clickPoint != null) {
                                PointEvent pointEvent = new PointEvent(eventEntity.orderInSolution, clickPoint.x, clickPoint.y);
                                TextView pointView = createTouchPointView(String.valueOf(pointEvent.getId()));
                                WindowManager.LayoutParams params = createTouchPointParams();
                                params.x = pointEvent.getX();
                                params.y = pointEvent.getY();
                                pointView.setLayoutParams(params);
                                pointEvent.setView(pointView);
                                setupDraggablePoint(pointView, params, pointEvent);
                                windowManager.addView(pointView, params);
                                runtimeEvents.add(new EventWrapper(type, pointEvent, pointEvent.getId()));
                            }
                        } else if (type == EventWrapper.EventType.SLIDE) {
                            TouchPoint startPointData = eventWithPoints.slideStartTouchPoint;
                            TouchPoint endPointData = eventWithPoints.slideEndTouchPoint;
                            if (startPointData != null && endPointData != null) {
                                PointEvent startPointEvent = new PointEvent(eventEntity.orderInSolution, startPointData.x, startPointData.y);
                                PointEvent endPointEvent = new PointEvent(eventEntity.orderInSolution, endPointData.x, endPointData.y);

                                TextView startPointView = createTouchPointView(String.valueOf(startPointEvent.getId()));
                                WindowManager.LayoutParams startParams = createTouchPointParams();
                                startParams.x = startPointEvent.getX();
                                startParams.y = startPointEvent.getY();
                                startPointView.setLayoutParams(startParams);

                                TextView endPointView = createTouchPointView(String.valueOf(endPointEvent.getId()));
                                WindowManager.LayoutParams endParams = createTouchPointParams();
                                endParams.x = endPointEvent.getX();
                                endParams.y = endPointEvent.getY();
                                endPointView.setLayoutParams(endParams);

                                ConnectingLineView lineView = new ConnectingLineView(context);
                                WindowManager.LayoutParams lineParams = createLineViewParams();

                                SlideEvent slideEvent = new SlideEvent(eventEntity.orderInSolution, startPointEvent, endPointEvent);

                                setupDraggableSlidePoint(startPointView, startParams, startPointEvent, slideEvent);
                                setupDraggableSlidePoint(endPointView, endParams, endPointEvent, slideEvent);

                                windowManager.addView(lineView, lineParams);
                                windowManager.addView(startPointView, startParams);
                                windowManager.addView(endPointView, endParams);

                                updateLinePosition(slideEvent);
                                runtimeEvents.add(new EventWrapper(type, slideEvent, slideEvent.getId()));
                            }
                        }
                        if (eventEntity.orderInSolution >= eventOrderCounter) {
                            eventOrderCounter = eventEntity.orderInSolution + 1;
                        }
                    }
                    updateServicePositions();
                    Toast.makeText(context, "方案 '" + solutionData.solution.solutionName + "' 加载成功！", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "加载方案失败或方案不存在。", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onError(Exception e) {
                Log.e(TAG, "加载方案失败: " + e.getMessage(), e);
                Toast.makeText(context, "加载方案失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void getAllSolutions(EventRepository.RepositoryCallback<List<Solution>> callback) {
        if (eventRepository != null) {
            eventRepository.getAllSolutions(callback);
        } else {
            callback.onError(new IllegalStateException("EventRepository not initialized."));
        }
    }
}