package com.ttstd.controller.view;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

import com.ttstd.control.Action;
import com.ttstd.control.ControlMessage;

/**
 * 自定义SurfaceView，用于捕获触摸事件并转换为远端输入指令。
 * 触摸坐标会被转换为相对于视图的百分比坐标（0.0-1.0），
 * 以便在不同分辨率的设备间进行坐标换算。
 */
public class RemoteTouchView extends SurfaceView {

    private static final String TAG = "RemoteTouchView";
    private TouchEventListener listener;

    private float lastTouchX;
    private float lastTouchY;
    private long swipeStartTime;
    private boolean isLongPressed = false;
    private GestureDetector gestureDetector;

    public interface TouchEventListener {
        void onTouch(float relX, float relY);
        void onSwipe(float relX1, float relY1, float relX2, float relY2, long duration);
        void onKeyEvent(int keyCode, int action);
        void onLongPress(float relX, float relY);
        void onMotionEvent(int action, float relX, float relY);
    }

    public RemoteTouchView(Context context) {
        super(context);
        init();
    }

    public RemoteTouchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RemoteTouchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setFocusable(true);
        setFocusableInTouchMode(true);
        gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
            @Override
            public void onLongPress(@NonNull MotionEvent e) {
                if (listener != null) {
                    isLongPressed = true;
                    float relX = e.getX() / getWidth();
                    float relY = e.getY() / getHeight();
                    relX = Math.max(0, Math.min(1, relX));
                    relY = Math.max(0, Math.min(1, relY));
                    listener.onLongPress(relX, relY);
                    Log.d(TAG, "LongPress at: " + relX + ", " + relY);
                }
            }
        });
    }

    public void setTouchEventListener(TouchEventListener listener) {
        this.listener = listener;
    }

    @Override
    public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
        if (listener != null) {
            listener.onKeyEvent(keyCode, android.view.KeyEvent.ACTION_DOWN);
            Log.d(TAG, "KeyDown: " + keyCode);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, android.view.KeyEvent event) {
        if (listener != null) {
            listener.onKeyEvent(keyCode, android.view.KeyEvent.ACTION_UP);
            Log.d(TAG, "KeyUp: " + keyCode);
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        gestureDetector.onTouchEvent(event);
        if (listener == null) return super.onTouchEvent(event);

        float absX = event.getX();
        float absY = event.getY();

        float relX = absX / getWidth();
        float relY = absY / getHeight();

        // 确保坐标在 [0, 1] 范围内
        relX = Math.max(0, Math.min(1, relX));
        relY = Math.max(0, Math.min(1, relY));

        int action = event.getActionMasked();
        
        // 发送原始 MotionEvent 实现实时跟手
        listener.onMotionEvent(action, relX, relY);
        Log.d(TAG, "MotionEvent: " + action + ", " + relX + ", " + relY);

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                isLongPressed = false;
                lastTouchX = relX;
                lastTouchY = relY;
                swipeStartTime = System.currentTimeMillis();
                return true;

            case MotionEvent.ACTION_MOVE:
                return true;

            case MotionEvent.ACTION_UP:
                if (isLongPressed) {
                    return true;
                }
                long duration = System.currentTimeMillis() - swipeStartTime;
                float dx = Math.abs(relX - lastTouchX);
                float dy = Math.abs(relY - lastTouchY);

                // 保留旧的回调以防万一，但 MainActivity 现在应该忽略它们
                if (duration < 200 && dx < 0.02 && dy < 0.02) {
                    listener.onTouch(lastTouchX, lastTouchY);
                    Log.d(TAG, "Touch at: " + lastTouchX + ", " + lastTouchY);
                } else {
                    listener.onSwipe(lastTouchX, lastTouchY, relX, relY, duration);
                    Log.d(TAG, "Swipe from: " + lastTouchX + ", " + lastTouchY + " to: " + relX + ", " + relY + " duration: " + duration);
                }
                return true;
        }

        return super.onTouchEvent(event);
    }

    public ControlMessage createTouchCommand(float relX, float relY) {
        return ControlMessage.newBuilder()
                .setAction(Action.TOUCH)
                .setX(relX)
                .setY(relY)
                .build();
    }

    public ControlMessage createSwipeCommand(float relX1, float relY1, float relX2, float relY2, long duration) {
        return ControlMessage.newBuilder()
                .setAction(Action.SWIPE)
                .setX1(relX1)
                .setY1(relY1)
                .setX2(relX2)
                .setY2(relY2)
                .setDuration(duration)
                .build();
    }

    public ControlMessage createLongPressCommand(float relX, float relY) {
        return ControlMessage.newBuilder()
                .setAction(Action.LONG_PRESS)
                .setX(relX)
                .setY(relY)
                .build();
    }

    public ControlMessage createMotionEventCommand(int action, float relX, float relY) {
        return ControlMessage.newBuilder()
                .setAction(Action.MOTION_EVENT)
                .setMotionAction(action)
                .setX(relX)
                .setY(relY)
                .build();
    }
}
