"use client";

import { useEffect, useRef, useState } from "react";

type ConfirmSlideModalProps = {
    isOpen: boolean;
    title: string;
    description?: string;
    confirmLabel?: string;
    onClose: () => void;
    onConfirm: () => void;
};

export default function ConfirmSlideModal({
    isOpen,
    title,
    description,
    confirmLabel = "Confirm",
    onClose,
    onConfirm
}: ConfirmSlideModalProps) {
    const trackRef = useRef<HTMLDivElement | null>(null);
    const endFlashTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
    const reachedEndRef = useRef(false);
    const [dragX, setDragX] = useState(0);
    const [dragging, setDragging] = useState(false);
    const [isAtEnd, setIsAtEnd] = useState(false);
    const [endFlash, setEndFlash] = useState(false);
    const handleSize = 40;

    function getDragPositionFromClientX(clientX: number) {
        const track = trackRef.current;
        if (!track) return 0;
        const rect = track.getBoundingClientRect();
        return Math.min(Math.max(0, clientX - rect.left - handleSize / 2), rect.width - handleSize);
    }

    function isEndPosition(position: number) {
        const track = trackRef.current;
        if (!track) return false;
        const maxDrag = track.clientWidth - handleSize;
        const endTolerancePx = 1;
        return position >= maxDrag - endTolerancePx;
    }

    function triggerEndFeedback() {
        setEndFlash(true);
        if (endFlashTimeoutRef.current) clearTimeout(endFlashTimeoutRef.current);
        endFlashTimeoutRef.current = setTimeout(() => setEndFlash(false), 140);

        if (typeof navigator !== "undefined" && typeof navigator.vibrate === "function") {
            navigator.vibrate(16);
        }
    }

    function handlePointerDown(event: React.PointerEvent<HTMLButtonElement>) {
        event.preventDefault();
        setDragging(true);
        reachedEndRef.current = false;
        setIsAtEnd(false);
        (event.currentTarget as HTMLElement).setPointerCapture(event.pointerId);
    }

    function handlePointerMove(event: React.PointerEvent<HTMLButtonElement>) {
        if (!dragging) return;
        const next = getDragPositionFromClientX(event.clientX);
        const nextAtEnd = isEndPosition(next);

        setDragX(next);
        setIsAtEnd(prev => (prev === nextAtEnd ? prev : nextAtEnd));

        if (nextAtEnd && !reachedEndRef.current) {
            reachedEndRef.current = true;
            triggerEndFeedback();
        }
        if (!nextAtEnd) reachedEndRef.current = false;
    }

    function handlePointerUp(event: React.PointerEvent<HTMLButtonElement>) {
        if (!dragging) return;
        setDragging(false);
        (event.currentTarget as HTMLElement).releasePointerCapture(event.pointerId);
        const track = trackRef.current;
        if (!track) return;
        const releaseX = getDragPositionFromClientX(event.clientX);
        const releaseAtEnd = isEndPosition(releaseX);

        setIsAtEnd(prev => (prev ? false : prev));

        if (releaseAtEnd && !reachedEndRef.current) {
            triggerEndFeedback();
        }

        if (releaseAtEnd) {
            setDragX(0);
            onConfirm();
        } else {
            setDragX(0);
        }
    }

    function handlePointerCancel(event: React.PointerEvent<HTMLButtonElement>) {
        if (!dragging) return;
        setDragging(false);
        (event.currentTarget as HTMLElement).releasePointerCapture(event.pointerId);
        setIsAtEnd(prev => (prev ? false : prev));
        setDragX(0);
    }

    useEffect(() => () => {
        if (endFlashTimeoutRef.current) clearTimeout(endFlashTimeoutRef.current);
    }, []);

    useEffect(() => {
        if (!isOpen) return;
        function handleKeyDown(event: KeyboardEvent) {
            if (event.key === "Escape") onClose();
        }
        window.addEventListener("keydown", handleKeyDown);
        return () => window.removeEventListener("keydown", handleKeyDown);
    }, [isOpen, onClose]);

    if (!isOpen) return null;

    return (
        <div className="fixed inset-0 z-[70] flex items-center justify-center bg-black/60 p-4 !mt-0" onClick={onClose}>
            <div className="w-full max-w-sm rounded-2xl border border-accent-weak bg-panel p-5" onClick={event => event.stopPropagation()}>
                <div className="text-lg font-semibold">{title}</div>
                {description ? <p className="mt-2 text-sm text-muted">{description}</p> : null}
                <div className="mt-4">
                    <div className="text-xs text-soft">Slide to confirm</div>
                    <div
                        ref={trackRef}
                        className={`relative mx-auto mt-2 h-10 w-4/5 overflow-hidden rounded-full border touch-none select-none transition-colors ${isAtEnd || endFlash ? "border-accent bg-accent-soft" : "border-accent-weak bg-surface"}`}
                    >
                        <div
                            className="absolute inset-y-0 left-0 rounded-full bg-accent-soft"
                            style={{ width: dragX + handleSize }}
                        />
                        <div
                            className={`pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-[color:var(--color-accent)] transition-all ${isAtEnd || endFlash ? "scale-100 opacity-100" : "scale-90 opacity-0"}`}
                            aria-hidden="true"
                        >
                            click
                        </div>
                        <button
                            type="button"
                            className={`absolute left-0 top-0 h-10 w-10 rounded-full border bg-panel text-lg font-semibold leading-none text-[color:var(--color-text)] touch-none select-none will-change-transform transition-[border-color,box-shadow] duration-100 ${isAtEnd || endFlash ? "border-accent-strong shadow-[0_0_0_2px_var(--color-accent-focus)]" : "border-accent"}`}
                            style={{ transform: `translateX(${dragX}px)` }}
                            onPointerDown={handlePointerDown}
                            onPointerMove={handlePointerMove}
                            onPointerUp={handlePointerUp}
                            onPointerCancel={handlePointerCancel}
                            aria-label="Slide to confirm"
                        >
                            ▸
                        </button>
                    </div>
                </div>
                <div className="mt-4 flex items-center justify-between">
                    <div className="text-xs text-soft">{confirmLabel}</div>
                    <button type="button" className="rounded-lg btn-outline-accent px-3 py-1.5 text-sm" onClick={onClose}>
                        Cancel
                    </button>
                </div>
            </div>
        </div>
    );
}
