import { Eraser } from 'lucide-react';
import { useEffect, useRef } from 'react';
import SignatureCanvasImport from 'react-signature-canvas';
import InputError from '@/components/input-error';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';

// react-signature-canvas ships as a CommonJS/UMD bundle. Vite's dev-server
// pre-bundling wraps its `module.exports` (itself `{ __esModule: true,
// default: SignatureCanvas }`) as the ESM default export, so the default
// import resolves one layer too shallow. Unwrap it before use.
const SignatureCanvas = ((
    SignatureCanvasImport as unknown as {
        default?: typeof SignatureCanvasImport;
    }
).default ?? SignatureCanvasImport) as typeof SignatureCanvasImport;

type SignaturePadProps = {
    name: string;
    error?: string;
    /** Renders a small, chrome-free pad sized to sit inline with other
     * compact signature placeholders (e.g. a document's signature row). */
    compact?: boolean;
    /** Fires with the captured signature file whenever the drawing changes,
     * for callers that submit it outside a native <form> (e.g. via router). */
    onCapture?: (file: File | null) => void;
};

export function SignaturePad({
    name,
    error,
    compact,
    onCapture,
}: SignaturePadProps) {
    const padRef = useRef<SignatureCanvasImport>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);

    // The canvas element's drawing-surface resolution (width/height
    // attributes) does not automatically follow its CSS-rendered size, so
    // without this, pointer coordinates drift from where ink is drawn —
    // worse on HiDPI screens. Size the backing buffer to match on mount and
    // whenever the layout might change.
    useEffect(() => {
        function resizeCanvas() {
            const canvas = padRef.current?.getCanvas();

            if (!canvas) {
                return;
            }

            const ratio = Math.max(window.devicePixelRatio || 1, 1);
            canvas.width = canvas.offsetWidth * ratio;
            canvas.height = canvas.offsetHeight * ratio;
            canvas.getContext('2d')?.scale(ratio, ratio);
            padRef.current?.clear();
        }

        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);

        return () => window.removeEventListener('resize', resizeCanvas);
    }, []);

    function syncFileInput() {
        const pad = padRef.current;
        const input = fileInputRef.current;

        if (!pad || !input || pad.isEmpty()) {
            return;
        }

        pad.getTrimmedCanvas().toBlob((blob: Blob | null) => {
            if (!blob) {
                return;
            }

            const file = new File([blob], 'signature.png', {
                type: 'image/png',
            });
            const dataTransfer = new DataTransfer();
            dataTransfer.items.add(file);
            input.files = dataTransfer.files;
            onCapture?.(file);
        }, 'image/png');
    }

    function handleClear() {
        padRef.current?.clear();

        if (fileInputRef.current) {
            fileInputRef.current.value = '';
        }

        onCapture?.(null);
    }

    if (compact) {
        return (
            <div className="grid gap-1">
                <div className="relative h-28 w-48 overflow-hidden rounded border bg-white">
                    <SignatureCanvas
                        ref={padRef}
                        penColor="#0f172a"
                        canvasProps={{
                            className:
                                'h-28 w-48 cursor-crosshair touch-none',
                        }}
                        onEnd={syncFileInput}
                    />
                    <button
                        type="button"
                        onClick={handleClear}
                        aria-label="Hapus tanda tangan"
                        className="absolute top-0.5 right-0.5 rounded bg-white/80 p-0.5 text-slate-500 hover:text-slate-900"
                    >
                        <Eraser className="h-3 w-3" />
                    </button>
                </div>
                <input
                    ref={fileInputRef}
                    type="file"
                    name={name}
                    className="hidden"
                />
                <InputError message={error} />
            </div>
        );
    }

    return (
        <div className="grid gap-2">
            <div className="flex items-center justify-between">
                <Label>
                    Tanda Tangan <span className="text-destructive">*</span>
                </Label>
                <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    onClick={handleClear}
                >
                    <Eraser className="h-4 w-4" />
                    Hapus
                </Button>
            </div>
            <div className="overflow-hidden rounded-md border bg-white">
                <SignatureCanvas
                    ref={padRef}
                    penColor="#0f172a"
                    canvasProps={{
                        className:
                            'h-[180px] w-full cursor-crosshair touch-none',
                    }}
                    onEnd={syncFileInput}
                />
            </div>
            <input
                ref={fileInputRef}
                type="file"
                name={name}
                className="hidden"
            />
            <p className="text-xs text-muted-foreground">
                Gambar tanda tangan Anda pada kotak di atas menggunakan mouse
                atau layar sentuh.
            </p>
            <InputError message={error} />
        </div>
    );
}
