// Region selection view - fullscreen transparent overlay for drawing a capture region
import { useState, useCallback, useEffect, useRef } from "react";
import { emit, listen } from "@tauri-apps/api/event";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { hideRegionSelector, setRegionSelectorPassthrough } from "../lib/api";

interface RegionBounds {
    x: number;
    y: number;
    width: number;
    height: number;
    // Optional debug/UX fields (used by the overlay to show logical vs physical size).
    logicalWidth?: number;
    logicalHeight?: number;
    scaleFactor?: number;
}

interface DragState {
    startX: number;
    startY: number;
    currentX: number;
    currentY: number;
}

function RegionSelectorView() {
    const [dragState, setDragState] = useState<DragState | null>(null);
    const [selectedRegion, setSelectedRegion] = useState<RegionBounds | null>(null);
    const [locked, setLocked] = useState(false);
    const containerRef = useRef<HTMLDivElement>(null);

    // Use physical screen pixels end-to-end.
    // - CGEventTap locations are in global display pixels
    // - CGDisplay bounds/pixels are in global display pixels
    // - screencapture -R/-D behaves consistently when fed display pixels
    //
    // Mouse events are in CSS pixels (logical). Convert to physical using scaleFactor.
    // Mouse events are relative to the webview content area (inner rect), not the outer window.
    const [windowOriginPx, setWindowOriginPx] = useState<{ x: number; y: number }>({
        x: 0,
        y: 0,
    });
    const [scaleFactor, setScaleFactor] = useState(1);

    useEffect(() => {
        let cancelled = false;

        (async () => {
            try {
                const w = getCurrentWindow();
                const [pos, scale] = await Promise.all([w.innerPosition(), w.scaleFactor()]);
                if (cancelled) return;
                setWindowOriginPx({ x: pos.x, y: pos.y });
                setScaleFactor(scale || 1);
            } catch {
                // Best-effort: fall back to assuming origin (0,0).
            }
        })();

        return () => {
            cancelled = true;
        };
    }, []);

    // When the backend reopens this window, reset back to interactive mode.
    useEffect(() => {
        let unlistenFn: (() => void) | undefined;

        const setup = async () => {
            unlistenFn = await listen("region-selector-reset", async () => {
                setLocked(false);
                setSelectedRegion(null);
                setDragState(null);
                // The backend may reposition this window per-monitor when reopening it.
                // Refresh the origin/scale so our logical->physical conversion stays correct.
                try {
                    const w = getCurrentWindow();
                    const [pos, scale] = await Promise.all([w.innerPosition(), w.scaleFactor()]);
                    setWindowOriginPx({ x: pos.x, y: pos.y });
                    setScaleFactor(scale || 1);
                } catch {
                    // ignore
                }
                try {
                    await setRegionSelectorPassthrough(false);
                } catch {
                    // ignore
                }
            });
        };

        setup();
        return () => {
            unlistenFn?.();
        };
    }, []);

    // This window is configured as `transparent: true` in Tauri, but our global CSS theme
    // sets an opaque body background. Override it here so the desktop is visible behind
    // the semi-transparent overlay while selecting a region.
    useEffect(() => {
        const prevHtmlBg = document.documentElement.style.background;
        const prevBodyBg = document.body.style.background;
        const prevBodyBgColor = document.body.style.backgroundColor;

        document.documentElement.style.background = "transparent";
        document.body.style.background = "transparent";
        document.body.style.backgroundColor = "transparent";

        return () => {
            document.documentElement.style.background = prevHtmlBg;
            document.body.style.background = prevBodyBg;
            document.body.style.backgroundColor = prevBodyBgColor;
        };
    }, []);

    // Calculate the actual region bounds from drag state
    const getRegionFromDrag = useCallback((drag: DragState): RegionBounds => {
        const x = Math.min(drag.startX, drag.currentX);
        const y = Math.min(drag.startY, drag.currentY);
        const width = Math.abs(drag.currentX - drag.startX);
        const height = Math.abs(drag.currentY - drag.startY);
        return { x, y, width, height };
    }, []);

    const handleMouseDown = useCallback(
        (e: React.MouseEvent) => {
            if (locked) return;
            // Use CSS pixels which correspond to "points" for our window.
            const x = e.clientX;
            const y = e.clientY;

            setDragState({
                startX: x,
                startY: y,
                currentX: x,
                currentY: y,
            });
            setSelectedRegion(null);
        },
        [locked]
    );

    const handleMouseMove = useCallback(
        (e: React.MouseEvent) => {
            if (!dragState) return;
            if (locked) return;

            // Use CSS pixels which correspond to "points" for our window.
            const x = e.clientX;
            const y = e.clientY;

            setDragState((prev) =>
                prev
                    ? {
                          ...prev,
                          currentX: x,
                          currentY: y,
                      }
                    : null
            );
        },
        [dragState, locked]
    );

    const handleMouseUp = useCallback(() => {
        if (!dragState) return;
        if (locked) return;

        const region = getRegionFromDrag(dragState);

        // Only accept regions with meaningful size (at least 50x50 pixels)
        if (region.width >= 50 && region.height >= 50) {
            setSelectedRegion(region);
        }

        setDragState(null);
    }, [dragState, getRegionFromDrag, locked]);

    const handleConfirm = useCallback(async () => {
        if (!selectedRegion) return;

        // Convert local CSS pixels (logical) to global physical pixels.
        const s = scaleFactor || 1;
        const globalRegion: RegionBounds = {
            x: Math.round(windowOriginPx.x + selectedRegion.x * s),
            y: Math.round(windowOriginPx.y + selectedRegion.y * s),
            width: Math.round(selectedRegion.width * s),
            height: Math.round(selectedRegion.height * s),
            logicalWidth: Math.round(selectedRegion.width),
            logicalHeight: Math.round(selectedRegion.height),
            scaleFactor: s,
        };

        // Emit the selected region back to the overlay window
        await emit("region-selected", globalRegion);

        // Keep the frame visible, but make the window click-through so the user can
        // keep working and hit Record in the recording overlay.
        setLocked(true);
        await setRegionSelectorPassthrough(true);
    }, [selectedRegion, scaleFactor, windowOriginPx.x, windowOriginPx.y]);

    const handleCancel = useCallback(async () => {
        await emit("region-cancelled", {});
        setLocked(false);
        try {
            await setRegionSelectorPassthrough(false);
        } catch {
            // ignore
        }
        await hideRegionSelector();
    }, []);

    // Handle escape key to cancel
    useEffect(() => {
        const handleKeyDown = (e: KeyboardEvent) => {
            if (e.key === "Escape") {
                handleCancel();
            } else if (e.key === "Enter" && selectedRegion) {
                handleConfirm();
            }
        };

        window.addEventListener("keydown", handleKeyDown);
        return () => window.removeEventListener("keydown", handleKeyDown);
    }, [handleCancel, handleConfirm, selectedRegion]);

    // Current drag region for display (in CSS pixels)
    const displayRegion = dragState ? getRegionFromDrag(dragState) : selectedRegion;
    const cssRegion = displayRegion ? { ...displayRegion } : null;

    return (
        <div
            ref={containerRef}
            onMouseDown={handleMouseDown}
            onMouseMove={handleMouseMove}
            onMouseUp={handleMouseUp}
            style={{
                position: "fixed",
                top: 0,
                left: 0,
                right: 0,
                bottom: 0,
                cursor: locked ? "default" : "crosshair",
                background: locked ? "transparent" : "rgba(0, 0, 0, 0.3)",
                userSelect: "none",
            }}
        >
            {/* Instructions overlay */}
            {!dragState && !selectedRegion && (
                <div
                    style={{
                        position: "absolute",
                        top: "50%",
                        left: "50%",
                        transform: "translate(-50%, -50%)",
                        background: "rgba(0, 0, 0, 0.8)",
                        color: "white",
                        padding: "24px 32px",
                        borderRadius: "12px",
                        textAlign: "center",
                        pointerEvents: "none",
                        zIndex: 10,
                    }}
                >
                    <div style={{ fontSize: "18px", fontWeight: 600, marginBottom: "8px" }}>
                        Select Recording Region
                    </div>
                    <div style={{ fontSize: "14px", color: "#aaa" }}>
                        Click and drag to select the area you want to record
                    </div>
                    <div style={{ fontSize: "12px", color: "#666", marginTop: "12px" }}>
                        Press ESC to cancel
                    </div>
                </div>
            )}

            {/* Selection rectangle */}
            {cssRegion && cssRegion.width > 0 && cssRegion.height > 0 && (
                <>
                    {/* Frame + outside mask */}
                    <div
                        style={{
                            position: "absolute",
                            left: cssRegion.x,
                            top: cssRegion.y,
                            width: cssRegion.width,
                            height: cssRegion.height,
                            // Darken everything outside the frame while selecting, but not while locked.
                            boxShadow: locked ? "none" : "0 0 0 9999px rgba(0, 0, 0, 0.65)",
                            background: "transparent",
                            // When locked (during recording), draw the frame outside the crop area
                            // so the recorded video (cropped to the region) doesn't include the border.
                            border: locked ? "none" : "2px solid #3b82f6",
                            outline: locked ? "2px solid #3b82f6" : "none",
                            outlineOffset: locked ? "2px" : "0",
                            boxSizing: "border-box",
                            zIndex: 2,
                        }}
                    />

                    {/* Dimension label */}
                    <div
                        style={{
                            position: "absolute",
                            left: cssRegion.x + cssRegion.width / 2,
                            top: cssRegion.y + cssRegion.height + 10,
                            transform: "translateX(-50%)",
                            background: locked ? "rgba(0, 0, 0, 0.65)" : "rgba(59, 130, 246, 0.9)",
                            color: "white",
                            padding: "4px 12px",
                            borderRadius: "6px",
                            fontSize: "14px",
                            fontWeight: 600,
                            fontVariantNumeric: "tabular-nums",
                            pointerEvents: "none",
                            whiteSpace: "nowrap",
                            zIndex: 3,
                        }}
                    >
                        {Math.round(displayRegion!.width)} x {Math.round(displayRegion!.height)}
                        {locked ? " (locked)" : ""}
                    </div>

                    {/* Corner handles */}
                    {!locked &&
                        [
                            { x: cssRegion.x, y: cssRegion.y },
                            { x: cssRegion.x + cssRegion.width, y: cssRegion.y },
                            { x: cssRegion.x, y: cssRegion.y + cssRegion.height },
                            { x: cssRegion.x + cssRegion.width, y: cssRegion.y + cssRegion.height },
                        ].map((corner, i) => (
                            <div
                                key={i}
                                style={{
                                    position: "absolute",
                                    left: corner.x - 4,
                                    top: corner.y - 4,
                                    width: 8,
                                    height: 8,
                                    background: "#3b82f6",
                                    borderRadius: "2px",
                                    pointerEvents: "none",
                                    zIndex: 3,
                                }}
                            />
                        ))}
                </>
            )}

            {/* Confirmation buttons */}
            {selectedRegion && !dragState && !locked && (
                <div
                    style={{
                        position: "absolute",
                        left: cssRegion!.x + cssRegion!.width / 2,
                        top: cssRegion!.y + cssRegion!.height + 50,
                        transform: "translateX(-50%)",
                        display: "flex",
                        gap: "12px",
                        zIndex: 10,
                    }}
                    onMouseDown={(e) => e.stopPropagation()}
                >
                    <button
                        onClick={handleConfirm}
                        style={{
                            padding: "10px 24px",
                            borderRadius: "8px",
                            border: "none",
                            background: "#3b82f6",
                            color: "white",
                            fontSize: "14px",
                            fontWeight: 600,
                            cursor: "pointer",
                        }}
                    >
                        Confirm Region
                    </button>
                    <button
                        onClick={handleCancel}
                        style={{
                            padding: "10px 24px",
                            borderRadius: "8px",
                            border: "1px solid rgba(255, 255, 255, 0.3)",
                            background: "rgba(0, 0, 0, 0.5)",
                            color: "white",
                            fontSize: "14px",
                            fontWeight: 600,
                            cursor: "pointer",
                        }}
                    >
                        Cancel
                    </button>
                </div>
            )}
        </div>
    );
}

export default RegionSelectorView;
