import {
    FileText,
    Image as ImageIcon,
    Loader2,
    UploadCloud,
    X,
} from 'lucide-react';
import { useId, useRef, useState } from 'react';

import { formatFileSize } from '@/lib/task-proof-utils';
import { cn } from '@/lib/utils';

interface ProofFileInputProps {
    /** File yang sedang terpilih (sudah dioptimasi untuk image). */
    file: File | null;
    /** Dipanggil dengan file mentah hasil pilihan/drop user (belum divalidasi). */
    onSelect: (file: File | null) => void;
    /** Nilai atribut accept untuk dialog file. */
    accept?: string;
    /** True ketika gambar sedang dioptimasi agar tampil indikator loading. */
    isProcessing?: boolean;
    /** Menentukan ikon & teks bantuan (image vs dokumen). */
    variant: 'image' | 'file';
    /** Teks bantuan tambahan, mis. batas ukuran. */
    hint?: string;
    disabled?: boolean;
}

/**
 * Dropzone file modern untuk bukti penyelesaian task.
 *
 * Menggantikan input file bawaan browser dengan area drag & drop yang
 * konsisten lintas browser, menampilkan file terpilih beserta ukurannya,
 * dan tombol untuk menghapus pilihan.
 */
export function ProofFileInput({
    file,
    onSelect,
    accept,
    isProcessing = false,
    variant,
    hint,
    disabled = false,
}: ProofFileInputProps) {
    const inputRef = useRef<HTMLInputElement>(null);
    const inputId = useId();
    const [isDragging, setIsDragging] = useState(false);

    const openPicker = () => {
        if (disabled || isProcessing) {
            return;
        }

        inputRef.current?.click();
    };

    const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
        event.preventDefault();
        setIsDragging(false);

        if (disabled || isProcessing) {
            return;
        }

        const dropped = event.dataTransfer.files?.[0] ?? null;

        onSelect(dropped);
    };

    const clearSelection = () => {
        onSelect(null);

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

    const FileIcon = variant === 'image' ? ImageIcon : FileText;
    const displayName = file
        ? variant === 'image'
            ? file.name.replace(/\.webp$/, '')
            : file.name
        : '';

    return (
        <div className="w-full max-w-full">
            <input
                ref={inputRef}
                id={inputId}
                type="file"
                accept={accept}
                className="sr-only"
                disabled={disabled}
                onChange={(event) => {
                    onSelect(event.target.files?.[0] ?? null);
                    // Reset agar pilih file yang sama berturut-turut tetap memicu onChange.
                    event.target.value = '';
                }}
            />

            {file ? (
                <div className="flex min-w-0 items-center gap-3 rounded-lg border border-amber-200/80 bg-background/80 px-3 py-2.5 dark:border-amber-900/40">
                    <div className="shrink-0 rounded-md bg-amber-100 p-2 text-amber-600 dark:bg-amber-900/50 dark:text-amber-400">
                        {isProcessing ? (
                            <Loader2 className="h-4 w-4 animate-spin" />
                        ) : (
                            <FileIcon className="h-4 w-4" />
                        )}
                    </div>
                    <div className="min-w-0 flex-1">
                        <p className="truncate text-xs font-medium text-foreground">
                            {displayName}
                        </p>
                        <p className="text-[11px] text-muted-foreground">
                            {isProcessing
                                ? 'Processing image...'
                                : `${formatFileSize(file.size)} • Ready to send`}
                        </p>
                    </div>
                    <div className="flex shrink-0 items-center gap-1">
                        <button
                            type="button"
                            onClick={openPicker}
                            disabled={disabled || isProcessing}
                            className="cursor-pointer rounded-md px-2 py-1 text-[11px] font-medium text-amber-700 transition-colors hover:bg-amber-100 disabled:cursor-not-allowed disabled:opacity-50 dark:text-amber-400 dark:hover:bg-amber-900/40"
                        >
                            Replace
                        </button>
                        <button
                            type="button"
                            onClick={clearSelection}
                            disabled={disabled || isProcessing}
                            aria-label="Remove selected file"
                            className="cursor-pointer rounded-md p-1 text-muted-foreground transition-colors hover:bg-muted hover:text-red-600 disabled:cursor-not-allowed disabled:opacity-50"
                        >
                            <X className="h-3.5 w-3.5" />
                        </button>
                    </div>
                </div>
            ) : (
                <div
                    role="button"
                    tabIndex={disabled ? -1 : 0}
                    onClick={openPicker}
                    onKeyDown={(event) => {
                        if (event.key === 'Enter' || event.key === ' ') {
                            event.preventDefault();
                            openPicker();
                        }
                    }}
                    onDragOver={(event) => {
                        event.preventDefault();

                        if (!disabled && !isProcessing) {
                            setIsDragging(true);
                        }
                    }}
                    onDragLeave={() => setIsDragging(false)}
                    onDrop={handleDrop}
                    className={cn(
                        'flex w-full cursor-pointer flex-col items-center justify-center gap-1.5 rounded-lg border border-dashed px-4 py-5 text-center transition-colors',
                        'border-amber-300 bg-background/60 hover:border-amber-400 hover:bg-amber-50/50 dark:border-amber-900/50 dark:bg-background/40 dark:hover:border-amber-800 dark:hover:bg-amber-900/20',
                        isDragging &&
                            'border-amber-500 bg-amber-100/70 dark:border-amber-600 dark:bg-amber-900/30',
                        (disabled || isProcessing) &&
                            'pointer-events-none opacity-60',
                    )}
                >
                    <div className="rounded-full bg-amber-100 p-2 text-amber-600 dark:bg-amber-900/50 dark:text-amber-400">
                        {isProcessing ? (
                            <Loader2 className="h-4 w-4 animate-spin" />
                        ) : (
                            <UploadCloud className="h-4 w-4" />
                        )}
                    </div>
                    <p className="text-xs font-medium text-amber-900 dark:text-amber-200">
                        {isProcessing ? (
                            'Processing image...'
                        ) : (
                            <>
                                <span className="underline decoration-amber-400 underline-offset-2">
                                    Choose file
                                </span>{' '}
                                or drag it here
                            </>
                        )}
                    </p>
                    {hint && !isProcessing && (
                        <p className="text-[11px] text-amber-700/80 dark:text-amber-400/70">
                            {hint}
                        </p>
                    )}
                </div>
            )}
        </div>
    );
}
