package com.auto.clicker.autoclicker.view;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
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.EventViewBinder;
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;

    private int mode;

    private int touchPointSize;

    private int controlBarWidth;

    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 final FloatingTabDialogManager floatingTabDialogManager;
    private final FloatingSettingDialogManager floatingSettingDialogManager;

    private final EventRepository eventRepository;

    private static final String PREFS_NAME = "AutoClickerPrefs";
    private static final String KEY_TOUCH_POINT_SIZE = "touch_point_size";
    private static final String KEY_CONTROL_BAR_WIDTH = "control_bar_width";

    private static final int DEFAULT_TOUCH_POINT_SIZE = 100;
    private static final int DEFAULT_CONTROL_BAR_WIDTH_DP = 50;

    private ImageView playButton;

    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.floatingSettingDialogManager = new FloatingSettingDialogManager(context);
        this.floatingTabDialogManager.setFloatingViewManager(this);
        this.eventRepository = new EventRepository(context.getApplicationContext());
        this.touchPointSize = 100;

        loadSettings();

        registerBroadcastReceiver();
    }

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

        this.mode = mode;

        removeAllFloatingViews();
        showMultipleModeViews(mode);

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

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

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

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

    private void initMultipleControlBar(int mode) {
        if (multipleControlBarView != null) {
            safeRemoveView(multipleControlBarView);
            multipleControlBarView = null;
        }

        multipleControlBarView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.multiple_control_bar, null);
        multipleControlBarParams = createControlBarParams();

        multipleControlBarParams.width = this.controlBarWidth;
        multipleControlBarParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

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

        updateControlBarImageViews(multipleControlBarView, this.controlBarWidth);
    }

    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;
    }

    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,int mode) {
        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);

        if (mode == 1){
            addButton.setVisibility(View.GONE);
            removeButton.setVisibility(View.GONE);
            slideButton.setVisibility(View.GONE);
            addPointEvent();
        }

        AutoClickService service = AutoClickService.getInstance();
        boolean serviceIsRunning = (service != null && service.isClicking());
        updatePlayButtonImage(serviceIsRunning);

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

        saveButton.setOnClickListener(v -> {
            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 -> {
            floatingSettingDialogManager.showFloatingTabDialog();
        });
        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());

        updatePlayButtonImage(isMultipleRunning);
    }

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

        PointEvent pointEvent = new PointEvent(eventOrderCounter, screenWidth / 2 - touchPointSize / 2,
                screenHeight / 2 - touchPointSize / 2);

        float currentTextSize = calculateTextSizeForPointSize(this.touchPointSize);

        EventViewBinder.bindPoint(context, windowManager, pointEvent,
                this.touchPointSize, screenWidth, screenHeight,
                (x, y) -> updateServicePositions(), eventOrderCounter, currentTextSize);

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

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

        PointEvent startPoint = new PointEvent(eventOrderCounter, screenWidth / 2 - 100, screenHeight / 2 - 50);
        PointEvent endPoint = new PointEvent(eventOrderCounter, screenWidth / 2 + 100, screenHeight / 2 - 50);
        SlideEvent slideEvent = new SlideEvent(eventOrderCounter, startPoint, endPoint);

        float currentTextSize = calculateTextSizeForPointSize(this.touchPointSize);

        EventViewBinder.bindSlide(context, windowManager, slideEvent,
                this.touchPointSize, screenWidth, screenHeight,
                (x, y) -> updateServicePositions(), eventOrderCounter, currentTextSize);

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

    public void toggleEventsVisibility(boolean show) {
        for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
            // 获取事件的视图
            View viewToToggle = null;
            if (wrapper.getType() == EventWrapper.EventType.POINT) {
                viewToToggle = EventViewBinder.createTouchPointView(context, 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 = EventViewBinder.createTouchPointView(context, String.valueOf(slideEvent.getStartPoint().getId()));
        View endPointView = EventViewBinder.createTouchPointView(context, String.valueOf(slideEvent.getEndPoint().getId()));
        View lineView = new ConnectingLineView(context);

        if (show) {
            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();
        }

        removeAllFloatingViews();

        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", 0);
        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 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 removeAllFloatingViews() {
        removeAllEventViews();

        removeMultipleControlBarView();

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

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

        Log.d(TAG, "所有浮动视图（包括控制栏和事件）已移除");
    }

    public void removeAllEventViews() {
        try {
            for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
                if (wrapper.getType() == EventWrapper.EventType.POINT) {
                    PointEvent pe = (PointEvent) wrapper.getEvent();
                    safeRemoveView(pe.getView());
                } else if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
                    SlideEvent se = (SlideEvent) wrapper.getEvent();
                    safeRemoveView(se.getStartPoint().getView());
                    safeRemoveView(se.getEndPoint().getView());
                    safeRemoveView(se.getLineView());
                }
            }
            runtimeEvents.clear();
            Log.d(TAG, "所有事件悬浮窗已移除");
        } catch (Exception e) {
            Log.e(TAG, "移除事件悬浮窗失败", e);
        }
    }

    public void removeMultipleControlBarView() {
        try {
            if (multipleControlBarView != null) {
                safeRemoveView(multipleControlBarView);
                multipleControlBarView = null;
                isMultipleRunning = false;
                Log.d(TAG, "多选控制栏悬浮窗已移除");
            }
        } catch (Exception e) {
            Log.e(TAG, "移除多选控制栏悬浮窗失败", e);
        }
    }

    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 void updateServicePositions() {
        AutoClickService service = AutoClickService.getInstance();
        if (service != null) {
            service.addMultipleClickEvents(runtimeEvents);
        }
    }

    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();
            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,mode);
        eventRepository.insertSolutionWithEvents(newSolution, runtimeEvents, new EventRepository.RepositoryCallback<Long>() {
            @Override
            public void onComplete(Long solutionId) {
                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) {
                new Handler(Looper.getMainLooper()).post(() -> {
                    if (solutionData != null && solutionData.events != null) {
                        removeAllEventViews();
                        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);

                                    float currentTextSize = calculateTextSizeForPointSize(FloatingViewManager.this.touchPointSize);

                                    EventViewBinder.bindPoint(context, windowManager,
                                            pointEvent,
                                            FloatingViewManager.this.touchPointSize,
                                            screenWidth, screenHeight,
                                            (x, y) -> updateServicePositions(), eventEntity.orderInSolution, currentTextSize);

                                    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);

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

                                    float currentTextSize = calculateTextSizeForPointSize(FloatingViewManager.this.touchPointSize);

                                    EventViewBinder.bindSlide(context, windowManager,
                                            slideEvent,
                                            FloatingViewManager.this.touchPointSize,
                                            screenWidth, screenHeight,
                                            (x, y) -> updateServicePositions(), eventEntity.orderInSolution, currentTextSize);

                                    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);
                new Handler(Looper.getMainLooper()).post(() ->
                        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."));
        }
    }

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

    private void loadSettings() {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        this.touchPointSize = prefs.getInt(KEY_TOUCH_POINT_SIZE, DEFAULT_TOUCH_POINT_SIZE);


        int defaultControlBarWidthPx = dpToPx(DEFAULT_CONTROL_BAR_WIDTH_DP);
        this.controlBarWidth = prefs.getInt(KEY_CONTROL_BAR_WIDTH, defaultControlBarWidthPx);

        Log.d(TAG, "设置已加载：触摸点大小=" + this.touchPointSize + ", 控制栏宽度=" + this.controlBarWidth);
    }

    public void setTouchPointSize(int newSize) {
        if (this.touchPointSize == newSize || newSize <= 0) {
            return;
        }
        this.touchPointSize = newSize;
        saveTouchPointSize(newSize);

        for (EventWrapper wrapper : new ArrayList<>(runtimeEvents)) {
            if (wrapper.getType() == EventWrapper.EventType.POINT) {
                PointEvent pe = (PointEvent) wrapper.getEvent();
                updatePointViewSize(pe);
            } else if (wrapper.getType() == EventWrapper.EventType.SLIDE) {
                SlideEvent se = (SlideEvent) wrapper.getEvent();
                updateSlideViewSize(se);
            }
        }
    }

    private void updatePointViewSize(PointEvent pointEvent) {
        if (pointEvent.getView() != null && pointEvent.getLayoutParams() != null) {
            TextView pointView = pointEvent.getView();
            WindowManager.LayoutParams params = pointEvent.getLayoutParams();

            params.width = touchPointSize;
            params.height = touchPointSize;

            float newTextSize = calculateTextSizeForPointSize(touchPointSize);

            pointView.setTextSize(TypedValue.COMPLEX_UNIT_SP, newTextSize);

            try {
                windowManager.updateViewLayout(pointView, params);
            } catch (IllegalArgumentException e) {
                Log.w(TAG, "尝试更新不存在的点击点视图", e);
            }
        }
    }

    private void updateSlideViewSize(SlideEvent slideEvent) {
        float newTextSize = calculateTextSizeForPointSize(touchPointSize); // 调用新方法计算

        if (slideEvent.getStartPoint().getView() != null && slideEvent.getStartPoint().getLayoutParams() != null) {
            TextView startView = slideEvent.getStartPoint().getView();
            WindowManager.LayoutParams startParams = slideEvent.getStartPoint().getLayoutParams();
            startParams.width = touchPointSize;
            startParams.height = touchPointSize;
            startView.setTextSize(TypedValue.COMPLEX_UNIT_SP, newTextSize);
            try {
                windowManager.updateViewLayout(startView, startParams);
            } catch (IllegalArgumentException e) {
                Log.w(TAG, "尝试更新不存在的滑动起点视图", e);
            }
        }

        if (slideEvent.getEndPoint().getView() != null && slideEvent.getEndPoint().getLayoutParams() != null) {
            TextView endView =  slideEvent.getEndPoint().getView();
            WindowManager.LayoutParams endParams = slideEvent.getEndPoint().getLayoutParams();
            endParams.width = touchPointSize;
            endParams.height = touchPointSize;
            endView.setTextSize(TypedValue.COMPLEX_UNIT_SP, newTextSize);
            try {
                windowManager.updateViewLayout(endView, endParams);
            } catch (IllegalArgumentException e) {
                Log.w(TAG, "尝试更新不存在的滑动终点视图", e);
            }
        }

        EventViewBinder.updateLinePosition(slideEvent, touchPointSize);
    }

    private float calculateTextSizeForPointSize(int pointSize) {
        final int MIN_POINT_SIZE_FOR_CALC = 50;
        final int MAX_POINT_SIZE_FOR_CALC = 200;
        final float MIN_TEXT_SIZE_SP = 10f;
        final float MAX_TEXT_SIZE_SP = 30f;

        float ratio = (float) (pointSize - MIN_POINT_SIZE_FOR_CALC) / (MAX_POINT_SIZE_FOR_CALC - MIN_POINT_SIZE_FOR_CALC);
        return MIN_TEXT_SIZE_SP + (MAX_TEXT_SIZE_SP - MIN_TEXT_SIZE_SP) * ratio;
    }

    private void saveTouchPointSize(int size) {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        prefs.edit().putInt(KEY_TOUCH_POINT_SIZE, size).apply();
        Log.d(TAG, "触摸点大小已保存: " + size);
    }

    private void saveControlBarWidth(int width) {
        SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        prefs.edit().putInt(KEY_CONTROL_BAR_WIDTH, width).apply();
        Log.d(TAG, "控制栏宽度已保存: " + width);
    }

    public int getTouchPointSize() {
        return this.touchPointSize;
    }

    private void updateControlBarImageViews(ViewGroup parentView, int newBarWidthPx) {
        float scaleFactor = (float) newBarWidthPx / dpToPx(DEFAULT_CONTROL_BAR_WIDTH_DP);

        for (int i = 0; i < parentView.getChildCount(); i++) {
            View child = parentView.getChildAt(i);
            if (child instanceof ViewGroup) {
                // 递归处理嵌套的 ViewGroup
                updateControlBarImageViews((ViewGroup) child, newBarWidthPx);
            } else if (child instanceof ImageView) {
                ImageView imageView = (ImageView) child;
                ViewGroup.LayoutParams params = imageView.getLayoutParams();

                if (imageView.getId() == R.id.cut_off) {
                    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
                    params.height = dpToPx(1);

                    imageView.setLayoutParams(params);
                    continue;
                }

                int originalImgWidthDp = 0;
                int originalImgHeightDp = 0;

                if (imageView.getId() == R.id.play_button || imageView.getId() == R.id.add_button || imageView.getId() == R.id.remove_button || imageView.getId() == R.id.close_button) {
                    originalImgWidthDp = 13;
                    if (imageView.getId() == R.id.remove_button) {
                        originalImgHeightDp = 2;
                    } else {
                        originalImgHeightDp = 13;
                    }
                } else if (imageView.getId() == R.id.slide_button) {
                    originalImgWidthDp = 17;
                    originalImgHeightDp = 17;
                } else if (imageView.getId() == R.id.save_button) {
                    originalImgWidthDp = 15;
                    originalImgHeightDp = 15;
                } else if (imageView.getId() == R.id.eye_button) {
                    originalImgWidthDp = 16;
                    originalImgHeightDp = 9;
                } else if (imageView.getId() == R.id.settings_button) {
                    originalImgWidthDp = 14;
                    originalImgHeightDp = 14;
                }

                if (originalImgWidthDp > 0) {
                    // 根据原始 dp 值和缩放因子计算新的像素尺寸
                    params.width = (int) (dpToPx(originalImgWidthDp) * scaleFactor);
                    params.height = (int) (dpToPx(originalImgHeightDp) * scaleFactor);
                    imageView.setLayoutParams(params);
                } else {
                    if (params.width > 0) {
                        params.width = (int) (dpToPx(params.width) * scaleFactor);
                    }
                    if (params.height > 0) {
                        params.height = (int) (dpToPx(params.height) * scaleFactor);
                    }
                    imageView.setLayoutParams(params);
                }
            }
        }
    }

    private int dpToPx(int dp) {
        if (context == null) return dp;
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
    }

    public void setControlBarSize(int newWidth) {
        if (this.controlBarWidth == newWidth || newWidth <= 0) {
            return;
        }
        this.controlBarWidth = newWidth;
        saveControlBarWidth(newWidth);

        if (multipleControlBarView != null && multipleControlBarParams != null) {
            multipleControlBarParams.width = this.controlBarWidth;
            multipleControlBarParams.height = WindowManager.LayoutParams.WRAP_CONTENT;

            try {
                windowManager.updateViewLayout(multipleControlBarView, multipleControlBarParams);
                updateControlBarImageViews(multipleControlBarView, this.controlBarWidth);
            } catch (IllegalArgumentException e) {
                Log.w(TAG, "尝试更新不存在的控制栏视图", e);
            }
        }
    }

    public int getControlBarWidth() {
        return controlBarWidth;
    }

    private void updatePlayButtonImage(boolean isRunning) {
        if (playButton == null) {
            return;
        }

        if (isRunning) {
            playButton.setImageResource(R.drawable.pause);
        } else {
            playButton.setImageResource(R.drawable.play);
        }
    }

    public EventRepository getEventRepository() {
        return eventRepository;
    }
}