package com.auto.clicker.autoclicker.service;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
import android.content.Intent;
import android.graphics.Path;
import android.graphics.Point;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;

import androidx.localbroadcastmanager.content.LocalBroadcastManager;


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.SlideEvent;
import com.auto.clicker.autoclicker.util.ScreenUtils;

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

public class AutoClickService extends AccessibilityService {
    private static final String TAG = "AutoClickService";
    private static AutoClickService instance;

    private static final long MIN_CLICK_INTERVAL = 40;
    private static final long MAX_CLICK_INTERVAL = 10000;
    private static final int MIN_CLICK_DURATION = 50;
    private static final int MAX_CLICK_DURATION = 1000;
    private static final int MIN_SLIDE_DURATION = 100;
    private static final int MAX_SLIDE_DURATION = 2000;

    private List<EventWrapper> runtimeEvents = new ArrayList<>();

    private final Handler handler = new Handler(Looper.getMainLooper());
    private boolean isRunning = false;

    private long clickInterval = 1000;
    private int clickDuration = 200;
    private int slideDuration = 500;
    private int currentEventIndex = 0;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        Point screenSize = ScreenUtils.getScreenSize(this);
        int screenWidth = screenSize.x;
        int screenHeight = screenSize.y;
        logDebug("屏幕尺寸: " + screenWidth + "x" + screenHeight);
    }

    public static AutoClickService getInstance() {
        return instance;
    }

    @Override
    public void onServiceConnected() {
        super.onServiceConnected();
        logDebug("无障碍服务已连接");
    }

    @Override
    public void onInterrupt() {
        stopClicking();
        logDebug("无障碍服务中断");
    }

    public void clearEvents() {
        runtimeEvents.clear();
        logDebug("清除所有事件");
    }

    public void addMultipleClickEvents(List<EventWrapper> eventWrapperList) {
        clearEvents();

        runtimeEvents = new ArrayList<>(eventWrapperList);
        logDebug("设置多点点击事件: " + eventWrapperList.size() + " 个点");
    }

    public void setClickInterval(long interval) {
        if (interval < MIN_CLICK_INTERVAL || interval > MAX_CLICK_INTERVAL) {
            Log.w(TAG, "点击间隔超出范围: " + interval + "ms");
            return;
        }
        this.clickInterval = interval;
        logDebug("设置点击间隔: " + interval + "ms");
    }

    public void setClickDuration(int duration) {
        if (duration < MIN_CLICK_DURATION || duration > MAX_CLICK_DURATION) {
            Log.w(TAG, "点击时长超出范围: " + duration + "ms");
            return;
        }
        this.clickDuration = duration;
        logDebug("设置点击时长: " + duration + "ms");
    }

    public void setSlideDuration(int duration) {
        if (duration < MIN_SLIDE_DURATION || duration > MAX_SLIDE_DURATION) {
            Log.w(TAG, "滑动时长超出范围: " + duration + "ms");
            return;
        }
        this.slideDuration = duration;
        logDebug("设置滑动时长: " + duration + "ms");
    }

    public void startClicking() {
        if (!isRunning) {
            if (runtimeEvents.isEmpty()) {
                Log.w(TAG, "无事件队列，忽略开始");
                return;
            }

            isRunning = true;
            currentEventIndex = 0;
            logDebug("开始执行事件队列 - 共 " + runtimeEvents.size() + " 个事件");
            executeEventsByType();
        }
    }

    public void stopClicking() {
        if (isRunning) {
            isRunning = false;
            handler.removeCallbacksAndMessages(null);
            logDebug("停止执行事件");
        }
    }

    public boolean isClicking() {
        return isRunning;
    }

    private void executeEventsByType() {
        if (!isRunning || runtimeEvents.isEmpty()) {
            logDebug("跳过执行：服务未运行或事件队列为空");
            return;
        }

        runtimeEvents.sort(Comparator.comparingInt(EventWrapper::getOrder));

        if (currentEventIndex >= runtimeEvents.size()) {
            currentEventIndex = 0;
        }

        EventWrapper wrapper = runtimeEvents.get(currentEventIndex);
        Event event = wrapper.getEvent();

        if (wrapper.getType() == EventWrapper.EventType.POINT && event instanceof PointEvent) {
            performSingleClick((PointEvent) event);
        } else if (wrapper.getType() == EventWrapper.EventType.SLIDE && event instanceof SlideEvent) {
            performSlide((SlideEvent) event);
        } else {
            logDebug("未知或不匹配的事件类型，跳过执行: " + wrapper.getType());
            currentEventIndex++;
            handler.postDelayed(this::executeEventsByType, clickInterval);
        }
    }

    private void performSingleClick(PointEvent pointEvent) {
        int x = pointEvent.getX();
        int y = pointEvent.getY();

        logDebug("执行点击: (" + x + ", " + y + ")");

        Path path = new Path();
        path.moveTo(x, y);
        GestureDescription.StrokeDescription stroke =
                new GestureDescription.StrokeDescription(path, 0, clickDuration);
        GestureDescription gesture =
                new GestureDescription.Builder().addStroke(stroke).build();

        dispatchGesture(gesture, new GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription) {
                logDebug("点击完成");
                if (isRunning) {
                    int feedbackIndex = currentEventIndex;
                    currentEventIndex++;
                    handler.postDelayed(() -> executeEventsByType(), clickInterval);
                    flashTouchFeedback(feedbackIndex);
                }
            }

            @Override
            public void onCancelled(GestureDescription gestureDescription) {
                Log.e(TAG, "点击被取消");
                if (isRunning) {
                    currentEventIndex++;
                    handler.postDelayed(() -> executeEventsByType(), clickInterval + 300);
                }
            }
        }, null);
    }

    private void performSlide(SlideEvent slideEvent) {
        PointEvent start = slideEvent.getStartPoint();
        PointEvent end = slideEvent.getEndPoint();
        int startX = start.getX();
        int startY = start.getY();
        int endX = end.getX();
        int endY = end.getY();

        logDebug("执行滑动: 从 (" + startX + ", " + startY + ") 到 (" + endX + ", " + endY + ")");

        Path path = new Path();
        path.moveTo(startX, startY);
        path.lineTo(endX, endY);
        GestureDescription.StrokeDescription stroke =
                new GestureDescription.StrokeDescription(path, 0, slideDuration);
        GestureDescription gesture =
                new GestureDescription.Builder().addStroke(stroke).build();

        dispatchGesture(gesture, new GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription) {
                logDebug("滑动完成");
                if (isRunning) {
                    int feedbackIndex = currentEventIndex;
                    currentEventIndex++;
                    handler.postDelayed(() -> executeEventsByType(), clickInterval);
                    flashTouchFeedback(feedbackIndex);
                }
            }

            @Override
            public void onCancelled(GestureDescription gestureDescription) {
                Log.e(TAG, "滑动被取消");
                if (isRunning) {
                    currentEventIndex++;
                    handler.postDelayed(() -> executeEventsByType(), clickInterval + 300);
                }
            }
        }, null);
    }

    private void flashTouchFeedback(int index) {
        Intent intent = new Intent("com.auto.clicker.autoclicker.FLASH_TOUCH_POINT");
        intent.putExtra("index", index);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
    }

    private void logDebug(String message) {
        Log.d(TAG, message);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        instance = null;
        stopClicking();
        Intent intent = new Intent("com.auto.clicker.autoclicker.SERVICE_DESTROYED");
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
        logDebug("无障碍服务已销毁");
    }
}