import {
    Folder,
    FolderOpen,
    Loader2,
    Pencil,
    Plus,
    Trash2,
} from 'lucide-react';
import { useState } from 'react';
import { toast } from 'sonner';
import {
    AlertDialog,
    AlertDialogAction,
    AlertDialogCancel,
    AlertDialogContent,
    AlertDialogDescription,
    AlertDialogFooter,
    AlertDialogHeader,
    AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import collectionsRoutes from '@/routes/admin/media/collections';

/**
 * Shared headers untuk fetch API ke endpoint koleksi.
 * Kirim cookies (session + XSRF-TOKEN) supaya CSRF valid.
 */
function collectionHeaders(): Record<string, string> {
    return {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        Accept: 'application/json',
    };
}

type Props = {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    collections: string[];
    onSuccess?: () => void;
};

/**
 * Dialog manajemen koleksi media — tambah, rename, dan hapus koleksi.
 */
export function CollectionManagerDialog({
    open,
    onOpenChange,
    collections,
    onSuccess,
}: Props) {
    const [newName, setNewName] = useState('');
    const [editingCollection, setEditingCollection] = useState<string | null>(
        null,
    );
    const [editName, setEditName] = useState('');
    const [deletingCollection, setDeletingCollection] = useState<string | null>(
        null,
    );
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState('');

    const handleCreate = async () => {
        if (!newName.trim()) {
return;
}

        setLoading(true);
        setError('');

        try {
            const response = await fetch(collectionsRoutes.store().url, {
                method: 'POST',
                credentials: 'same-origin',
                headers: collectionHeaders(),
                body: JSON.stringify({ name: newName.trim() }),
            });

            if (response.ok) {
                toast.success('Koleksi berhasil dibuat.', {
                    id: 'collection-create-success',
                });
                setNewName('');
                onSuccess?.();
            } else if (response.status === 422) {
                const data = await response.json();
                setError(data.errors?.name?.[0] || 'Gagal membuat koleksi.');
            } else {
                setError('Gagal membuat koleksi.');
            }
        } catch {
            setError('Gagal membuat koleksi.');
        } finally {
            setLoading(false);
        }
    };

    const handleUpdate = async () => {
        if (!editingCollection || !editName.trim()) {
return;
}

        setLoading(true);
        setError('');

        try {
            const response = await fetch(
                collectionsRoutes.update(editingCollection).url,
                {
                    method: 'PUT',
                    credentials: 'same-origin',
                    headers: collectionHeaders(),
                    body: JSON.stringify({ name: editName.trim() }),
                },
            );

            if (response.ok) {
                toast.success('Koleksi berhasil di-rename.', {
                    id: 'collection-update-success',
                });
                setEditingCollection(null);
                setEditName('');
                onSuccess?.();
            } else if (response.status === 422) {
                const data = await response.json();
                setError(data.errors?.name?.[0] || 'Gagal rename koleksi.');
            } else {
                setError('Gagal rename koleksi.');
            }
        } catch {
            setError('Gagal rename koleksi.');
        } finally {
            setLoading(false);
        }
    };

    const handleDelete = async () => {
        if (!deletingCollection) {
return;
}

        setLoading(true);

        try {
            const response = await fetch(
                collectionsRoutes.destroy(deletingCollection).url,
                {
                    method: 'DELETE',
                    credentials: 'same-origin',
                    headers: collectionHeaders(),
                },
            );

            if (response.ok) {
                toast.success('Koleksi berhasil dihapus.', {
                    id: 'collection-delete-success',
                });
                setDeletingCollection(null);
                onSuccess?.();
            } else {
                setError('Gagal menghapus koleksi.');
            }
        } catch {
            setError('Gagal menghapus koleksi.');
        } finally {
            setLoading(false);
        }
    };

    const startEdit = (collection: string) => {
        setEditingCollection(collection);
        setEditName(collection);
        setError('');
    };

    const cancelEdit = () => {
        setEditingCollection(null);
        setEditName('');
        setError('');
    };

    const confirmDelete = (collection: string) => {
        setDeletingCollection(collection);
        setError('');
    };

    const cancelDelete = () => {
        setDeletingCollection(null);
    };

    return (
        <>
            <Dialog open={open} onOpenChange={onOpenChange}>
                <DialogContent className="sm:max-w-2xl">
                    <DialogHeader>
                        <DialogTitle>Kelola Koleksi</DialogTitle>
                        <DialogDescription>
                            Tambah, rename, atau hapus koleksi media.
                        </DialogDescription>
                    </DialogHeader>

                    {/* Form tambah koleksi baru */}
                    <div className="flex items-center gap-2">
                        <Input
                            value={newName}
                            onChange={(e) => setNewName(e.target.value)}
                            placeholder="Nama koleksi baru..."
                            disabled={loading}
                            onKeyDown={(e) => {
                                if (e.key === 'Enter') {
                                    handleCreate();
                                }
                            }}
                        />
                        <Button
                            onClick={handleCreate}
                            disabled={loading || !newName.trim()}
                            size="sm"
                        >
                            {loading ? (
                                <Loader2 className="size-4 animate-spin" />
                            ) : (
                                <Plus className="size-4" />
                            )}
                            Tambah
                        </Button>
                    </div>

                    {error && (
                        <p className="rounded-md bg-destructive/10 px-3 py-2 text-sm text-destructive">
                            {error}
                        </p>
                    )}

                    {/* Daftar koleksi — scrollable jika banyak */}
                    <div className="max-h-40 space-y-1 overflow-y-auto rounded-md border p-1">
                        {collections.length === 0 ? (
                            <p className="py-4 text-center text-sm text-muted-foreground">
                                Belum ada koleksi.
                            </p>
                        ) : (
                            collections.map((collection) => (
                                <div
                                    key={collection}
                                    className="flex items-center gap-2 rounded-md border px-3 py-2"
                                >
                                    {editingCollection === collection ? (
                                        <>
                                            <FolderOpen className="size-4 shrink-0 text-muted-foreground" />
                                            <Input
                                                value={editName}
                                                onChange={(e) =>
                                                    setEditName(e.target.value)
                                                }
                                                className="h-8"
                                                disabled={loading}
                                                onKeyDown={(e) => {
                                                    if (e.key === 'Enter') {
                                                        handleUpdate();
                                                    } else if (
                                                        e.key === 'Escape'
                                                    ) {
                                                        cancelEdit();
                                                    }
                                                }}
                                                autoFocus
                                            />
                                            <Button
                                                size="sm"
                                                variant="ghost"
                                                onClick={handleUpdate}
                                                disabled={
                                                    loading || !editName.trim()
                                                }
                                            >
                                                Simpan
                                            </Button>
                                            <Button
                                                size="sm"
                                                variant="ghost"
                                                onClick={cancelEdit}
                                                disabled={loading}
                                            >
                                                Batal
                                            </Button>
                                        </>
                                    ) : (
                                        <>
                                            <Folder className="size-4 shrink-0 text-muted-foreground" />
                                            <span className="flex-1 truncate text-sm">
                                                {collection}
                                            </span>
                                            <Button
                                                size="sm"
                                                variant="ghost"
                                                onClick={() =>
                                                    startEdit(collection)
                                                }
                                            >
                                                <Pencil className="size-3.5" />
                                            </Button>
                                            <Button
                                                size="sm"
                                                variant="ghost"
                                                onClick={() =>
                                                    confirmDelete(collection)
                                                }
                                            >
                                                <Trash2 className="size-3.5 text-destructive" />
                                            </Button>
                                        </>
                                    )}
                                </div>
                            ))
                        )}
                    </div>

                    <DialogFooter>
                        <Button
                            variant="outline"
                            onClick={() => onOpenChange(false)}
                        >
                            Tutup
                        </Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>

            <AlertDialog
                open={!!deletingCollection}
                onOpenChange={(open) => {
                    if (!open) {
                        cancelDelete();
                    }
                }}
            >
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle>Hapus koleksi?</AlertDialogTitle>
                        <AlertDialogDescription>
                            Koleksi <strong>{deletingCollection}</strong> akan
                            dihapus. Media di dalamnya akan dipindahkan ke
                            koleksi General.
                        </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel disabled={loading}>
                            Batal
                        </AlertDialogCancel>
                        <AlertDialogAction
                            disabled={loading}
                            onClick={(event) => {
                                event.preventDefault();
                                void handleDelete();
                            }}
                            className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
                        >
                            {loading ? (
                                <Loader2 className="size-4 animate-spin" />
                            ) : (
                                'Hapus koleksi'
                            )}
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </>
    );
}
