import { Head, router, setLayoutProps } from '@inertiajs/react';
import {
    Archive,
    MoreHorizontal,
    RefreshCw,
    RotateCcw,
    Search,
    Trash2,
    X,
} from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';

import {
    destroy as archiveDestroy,
    index as adminArchivesIndex,
    restore as archiveRestore,
} from '@/actions/App/Domains/Shared/Http/Controllers/Admin/ArchivedProjectController';

import { ConfirmActionDialog } from '@/components/ConfirmActionDialog';
import { DataPagination } from '@/components/DataPagination';
import { DateFilter, parseIsoDate } from '@/components/DateFilter';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Input } from '@/components/ui/input';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { cn, formatDate } from '@/lib/utils';
import type { AdminArchivedProject, DivisionOption } from '@/types/admin';
import type { PaginationData } from '@/types/pagination';

const FILTER_DEBOUNCE_MS = 300;

const ALL = 'all';

interface AdminArchivesPageProps {
    projects: AdminArchivedProject[];
    pagination: PaginationData;
    filters: {
        search: string;
        division_id: number | null;
        from: string | null;
        to: string | null;
    };
    divisions: DivisionOption[];
}

export default function AdminArchivesIndex({
    projects,
    pagination,
    filters,
    divisions,
}: AdminArchivesPageProps) {
    const [searchQuery, setSearchQuery] = useState(filters.search);
    const [divisionFilter, setDivisionFilter] = useState(
        filters.division_id ? String(filters.division_id) : ALL,
    );
    const [fromDate, setFromDate] = useState(filters.from ?? '');
    const [toDate, setToDate] = useState(filters.to ?? '');

    const [restoringProject, setRestoringProject] =
        useState<AdminArchivedProject | null>(null);
    const [purgingProject, setPurgingProject] =
        useState<AdminArchivedProject | null>(null);
    const [processingAction, setProcessingAction] = useState(false);
    const [refreshing, setRefreshing] = useState(false);

    const isInitialFilterSync = useRef(true);

    const hasActiveFilters =
        searchQuery !== '' ||
        divisionFilter !== ALL ||
        fromDate !== '' ||
        toDate !== '';

    /**
     * Kosongkan seluruh filter sekaligus.
     *
     * Tidak memanggil router sendiri: efek debounce di bawah sudah memantau
     * keempat state ini, jadi perubahannya berangkat sebagai satu request.
     */
    const clearFilters = () => {
        setSearchQuery('');
        setDivisionFilter(ALL);
        setFromDate('');
        setToDate('');
    };

    /**
     * Muat ulang isi tabel tanpa memuat ulang halaman.
     *
     * Hanya prop tabel yang diminta ke server; filter, posisi scroll, dan state
     * komponen lain tetap seperti apa adanya. `divisions` ikut diminta supaya
     * divisi yang baru pertama kali punya project terarsip langsung muncul di
     * dropdown filter.
     */
    const refresh = () =>
        router.reload({
            only: ['projects', 'pagination', 'divisions'],
            onStart: () => setRefreshing(true),
            onFinish: () => setRefreshing(false),
        });

    // Batas saling kunci antar kedua kalender; undefined berarti tanpa batas.
    const lowerBound = parseIsoDate(fromDate);
    const upperBound = parseIsoDate(toDate);

    const queryParams = useMemo(
        () => ({
            search: searchQuery || undefined,
            division_id: divisionFilter !== ALL ? divisionFilter : undefined,
            from: fromDate || undefined,
            to: toDate || undefined,
        }),
        [searchQuery, divisionFilter, fromDate, toDate],
    );

    useEffect(() => {
        if (isInitialFilterSync.current) {
            isInitialFilterSync.current = false;

            return;
        }

        const request = window.setTimeout(() => {
            router.get(adminArchivesIndex().url, queryParams, {
                preserveScroll: true,
                preserveState: true,
                replace: true,
            });
        }, FILTER_DEBOUNCE_MS);

        return () => window.clearTimeout(request);
    }, [queryParams]);

    setLayoutProps({
        breadcrumbs: [{ title: 'Archives' }],
    });

    const confirmRestore = () => {
        if (!restoringProject) {
            return;
        }

        setProcessingAction(true);

        router.patch(
            archiveRestore({ project: restoringProject.id }).url,
            {},
            {
                preserveScroll: true,
                onFinish: () => {
                    setProcessingAction(false);
                    setRestoringProject(null);
                },
            },
        );
    };

    const confirmPurge = () => {
        if (!purgingProject) {
            return;
        }

        setProcessingAction(true);

        router.delete(archiveDestroy({ project: purgingProject.id }).url, {
            preserveScroll: true,
            onFinish: () => {
                setProcessingAction(false);
                setPurgingProject(null);
            },
        });
    };

    return (
        <>
            <Head title="Archives" />

            <div className="flex min-h-full flex-col gap-4 p-4 md:p-6">
                <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                    <div>
                        <h1 className="text-xl font-bold tracking-tight text-foreground">
                            Archives
                        </h1>
                        <p className="text-sm text-muted-foreground">
                            {pagination.total} deleted project
                            {pagination.total === 1 ? '' : 's'} waiting to be
                            restored or removed for good
                        </p>
                    </div>

                    <Button
                        variant="outline"
                        className="h-9"
                        disabled={refreshing}
                        onClick={refresh}
                    >
                        <RefreshCw
                            className={cn(
                                'mr-1 h-4 w-4',
                                refreshing && 'animate-spin',
                            )}
                        />
                        Refresh
                    </Button>
                </div>

                <div className="flex flex-col gap-2 sm:flex-row sm:flex-wrap sm:items-center">
                    {/* Search memakan sisa baris supaya tidak ada ruang kosong
                        di antara filter; sisanya tetap lebar tetap. */}
                    <div className="relative w-full sm:min-w-56 sm:flex-1">
                        <Search
                            className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground"
                            size={16}
                        />
                        <Input
                            placeholder="Search name or description..."
                            className="h-9 rounded-lg bg-background pl-9"
                            value={searchQuery}
                            onChange={(e) => setSearchQuery(e.target.value)}
                        />
                    </div>

                    <Select
                        value={divisionFilter}
                        onValueChange={setDivisionFilter}
                    >
                        <SelectTrigger className="h-9 w-full sm:w-44">
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value={ALL}>All divisions</SelectItem>
                            {divisions.map((division) => (
                                <SelectItem
                                    key={division.id}
                                    value={String(division.id)}
                                >
                                    {division.name}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>

                    {/* Rentang tanggal penghapusan; batasnya saling mengunci
                        supaya tidak bisa memilih rentang terbalik. */}
                    <div className="flex items-center gap-2">
                        <DateFilter
                            label="Deleted from"
                            value={fromDate}
                            onChange={setFromDate}
                            disabled={upperBound && { after: upperBound }}
                        />
                        <span className="text-sm text-muted-foreground">–</span>
                        <DateFilter
                            label="Until"
                            value={toDate}
                            onChange={setToDate}
                            disabled={lowerBound && { before: lowerBound }}
                        />
                    </div>

                    {/* Hanya muncul saat ada yang bisa dibersihkan; tombol yang
                        selalu tampil tapi tidak melakukan apa-apa cuma bikin
                        ragu apakah filternya sedang aktif. */}
                    {hasActiveFilters && (
                        <Button
                            variant="outline"
                            className="h-9 shrink-0"
                            onClick={clearFilters}
                        >
                            <X className="mr-1 h-4 w-4" />
                            Clear filters
                        </Button>
                    )}
                </div>

                <div className="overflow-x-auto rounded-lg border bg-background">
                    <Table>
                        <TableHeader>
                            <TableRow className="hover:bg-transparent">
                                <TableHead className="w-12 text-center">
                                    NO.
                                </TableHead>
                                <TableHead>Project</TableHead>
                                <TableHead>Division</TableHead>
                                <TableHead>Tasks</TableHead>
                                <TableHead>Deleted</TableHead>
                                <TableHead className="w-12" />
                            </TableRow>
                        </TableHeader>
                        <TableBody>
                            {projects.length === 0 && (
                                <TableRow>
                                    <TableCell
                                        colSpan={6}
                                        className="py-10 text-center text-sm text-muted-foreground"
                                    >
                                        No deleted project matches the current
                                        filter.
                                    </TableCell>
                                </TableRow>
                            )}

                            {projects.map((project, index) => (
                                <TableRow key={project.id}>
                                    <TableCell className="text-center text-muted-foreground">
                                        {(pagination.from ?? 0) + index}
                                    </TableCell>

                                    <TableCell>
                                        <div className="font-medium text-foreground">
                                            {project.name}
                                        </div>
                                        <div className="line-clamp-1 text-xs text-muted-foreground">
                                            Created by{' '}
                                            {project.creator_name ?? 'unknown'}
                                        </div>
                                    </TableCell>

                                    <TableCell className="text-sm text-foreground">
                                        {project.division_name ?? '—'}
                                    </TableCell>

                                    <TableCell>
                                        <Badge
                                            variant="outline"
                                            className="font-normal"
                                        >
                                            {project.task_count} task
                                            {project.task_count === 1
                                                ? ''
                                                : 's'}
                                        </Badge>
                                    </TableCell>

                                    <TableCell>
                                        <div className="text-sm text-foreground">
                                            {formatDate(project.deleted_at, {
                                                withTime: true,
                                            })}
                                        </div>
                                        <div className="text-xs text-muted-foreground">
                                            by {project.deleted_by ?? 'unknown'}
                                        </div>
                                    </TableCell>

                                    <TableCell>
                                        <DropdownMenu>
                                            <DropdownMenuTrigger asChild>
                                                <Button
                                                    variant="ghost"
                                                    size="icon"
                                                    aria-label={`Actions for ${project.name}`}
                                                >
                                                    <MoreHorizontal className="h-4 w-4" />
                                                </Button>
                                            </DropdownMenuTrigger>
                                            <DropdownMenuContent align="end">
                                                <DropdownMenuItem
                                                    onSelect={() =>
                                                        setRestoringProject(
                                                            project,
                                                        )
                                                    }
                                                >
                                                    <RotateCcw className="mr-2 h-4 w-4" />
                                                    Restore project
                                                </DropdownMenuItem>
                                                <DropdownMenuSeparator />
                                                <DropdownMenuItem
                                                    onSelect={() =>
                                                        setPurgingProject(
                                                            project,
                                                        )
                                                    }
                                                >
                                                    <Trash2 className="mr-2 h-4 w-4" />
                                                    Delete permanently
                                                </DropdownMenuItem>
                                            </DropdownMenuContent>
                                        </DropdownMenu>
                                    </TableCell>
                                </TableRow>
                            ))}
                        </TableBody>
                    </Table>
                </div>

                <DataPagination
                    pagination={pagination}
                    only={['projects', 'pagination']}
                />
            </div>

            <ConfirmActionDialog
                open={restoringProject !== null}
                onOpenChange={(open) => !open && setRestoringProject(null)}
                onConfirm={confirmRestore}
                processing={processingAction}
                title="Restore this project?"
                description={
                    <>
                        <span className="font-medium text-foreground">
                            {restoringProject?.name}
                        </span>{' '}
                        will return to the project list with its{' '}
                        {restoringProject?.task_count ?? 0} task
                        {restoringProject?.task_count === 1 ? '' : 's'}, and its
                        members get access back.
                    </>
                }
                confirmLabel="Restore"
                cancelLabel="Cancel"
                tone="neutral"
                icon={RotateCcw}
            />

            <ConfirmActionDialog
                open={purgingProject !== null}
                onOpenChange={(open) => !open && setPurgingProject(null)}
                onConfirm={confirmPurge}
                processing={processingAction}
                title="Delete this project permanently?"
                description={
                    <>
                        <span className="font-medium text-foreground">
                            {purgingProject?.name}
                        </span>{' '}
                        and its {purgingProject?.task_count ?? 0} task
                        {purgingProject?.task_count === 1 ? '' : 's'} — along
                        with every comment, proof, and attachment — will be
                        erased. This cannot be undone.
                    </>
                }
                confirmLabel="Delete permanently"
                cancelLabel="Cancel"
                tone="danger"
                icon={Archive}
            />
        </>
    );
}
