import { Images, UploadCloud, X } from 'lucide-react';
import { useState } from 'react';
import { MediaPickerDialog } from '@/components/admin/media-picker-dialog';
import type { MediaPickerItem } from '@/components/admin/media-picker-dialog';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import { cn } from '@/lib/utils';

export type SelectedMedia = { id: number; url: string };

type Props = {
    label: string;
    onChange: (file: File | null) => void;
    onSelectMedia?: (media: SelectedMedia | null) => void;
    selectedMedia?: SelectedMedia | null;
    existingUrl?: string | null;
    hint?: string;
    error?: string;
    onClear?: () => void;
    showLibraryButton?: boolean;
    showClearButton?: boolean;
    aspectRatio?: 'video' | 'auto';
};

/**
 * Komponen media reusable — terintegrasi dengan
 * react-hook-form via Controller. `existingUrl` dipakai saat edit (preview lama).
 * Tombol hapus: icon X merah circular di pojok kanan atas image (Sesi 37).
 *
 * Semua pilihan media, termasuk upload file lokal, melewati MediaPickerDialog.
 */
export default function FormImageUpload({
    label,
    onChange,
    onSelectMedia,
    selectedMedia = null,
    existingUrl = null,
    hint,
    error,
    onClear,
    showLibraryButton = true,
    showClearButton = true,
    aspectRatio = 'auto',
}: Props) {
    const [preview, setPreview] = useState<string | null>(null);
    const [cleared, setCleared] = useState(false);
    const [pickerOpen, setPickerOpen] = useState(false);

    const currentPreview = cleared
        ? null
        : (preview ?? selectedMedia?.url ?? existingUrl);

    const handleSelectMedia = (media: MediaPickerItem | MediaPickerItem[]) => {
        if (Array.isArray(media)) {
            return;
        }

        if (preview) {
            URL.revokeObjectURL(preview);
        }

        setPreview(null);
        setCleared(false);
        onChange(null);
        onSelectMedia?.({ id: media.id, url: media.url });
    };

    const handleClear = () => {
        if (preview) {
            URL.revokeObjectURL(preview);
        }

        setPreview(null);
        setCleared(true);
        onChange(null);
        onSelectMedia?.(null);
        onClear?.();
    };

    return (
        <div className="space-y-2">
            <Label>{label}</Label>

            <div
                role="button"
                tabIndex={0}
                onClick={() => setPickerOpen(true)}
                onKeyDown={(event) => {
                    if (event.key === 'Enter' || event.key === ' ') {
                        setPickerOpen(true);
                    }
                }}
                className={cn(
                    'flex min-h-28 cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-4 text-center transition-colors hover:border-primary/50 hover:bg-muted/50 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none',
                    aspectRatio === 'video' &&
                        'mx-auto aspect-video min-h-0 w-full max-w-3xl',
                    currentPreview && 'border-0 p-3',
                )}
            >
                {currentPreview ? (
                    <div className="relative isolate h-full w-full">
                        <img
                            src={currentPreview}
                            alt={label}
                            className={cn(
                                'max-h-full max-w-full object-contain',
                                aspectRatio === 'video'
                                    ? 'h-full w-full'
                                    : 'max-h-40',
                            )}
                        />

                        <button
                            type="button"
                            aria-label={`Hapus ${label.toLowerCase()}`}
                            title="Hapus gambar"
                            onClick={(event) => {
                                event.stopPropagation();
                                event.preventDefault();
                                handleClear();
                            }}
                            className="absolute top-0 right-0 z-20 flex size-6 items-center justify-center rounded-full bg-destructive text-white shadow-md transition-transform hover:scale-110 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none"
                        >
                            <X className="size-3.5" />
                        </button>
                    </div>
                ) : (
                    <>
                        <UploadCloud className="size-8 text-muted-foreground" />
                        <p className="text-sm text-muted-foreground">
                            Klik untuk memilih dari Library Media
                        </p>
                    </>
                )}
            </div>

            <div className="flex items-center gap-2">
                {showLibraryButton && (
                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={() => setPickerOpen(true)}
                    >
                        <Images className="size-4" />
                        Pilih dari Library
                    </Button>
                )}
                {showClearButton && currentPreview && (
                    <Button
                        type="button"
                        variant="ghost"
                        size="sm"
                        onClick={handleClear}
                    >
                        <X className="size-4" />
                        Hapus
                    </Button>
                )}
            </div>

            {hint && <p className="text-xs text-muted-foreground">{hint}</p>}
            {error && <p className="text-sm text-destructive">{error}</p>}

            {pickerOpen && (
                <MediaPickerDialog
                    open
                    onOpenChange={setPickerOpen}
                    onSelect={handleSelectMedia}
                />
            )}
        </div>
    );
}
