import { Head, Link } from '@inertiajs/react';
import {
    AlertCircle,
    ArrowLeft,
    Calendar,
    CheckCircle,
    ChevronLeft,
    ChevronRight,
    Clock,
    Download,
    FileText,
    PackageIcon,
} from 'lucide-react';
import { useCallback, useMemo, useState } from 'react';

import { Button } from '@/components/ui/button';
import {
    Card,
    CardAction,
    CardContent,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectGroup,
    SelectItem,
    SelectLabel,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';

import { StatusBadge } from '@/components/ui/status-badge';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import AppLayout from '@/layouts/app-layout';
import { exportToCSV } from '@/lib/exportToCSV';
import { formatDateID, formatIDR } from '@/lib/formatters';
import financingsRoutes from '@/routes/financing';
import type { BreadcrumbItem, PaginatedData } from '@/types';
import type { Financing, FinancingInstallment } from '@/types/financing';

interface PageProps {
    financing: Financing;
    installments?: PaginatedData<FinancingInstallment>;
    filters?: {
        status?: string;
        from?: string;
        to?: string;
    };
}

export default function Installments({
    financing,
    installments,
    filters = {},
}: PageProps) {
    const breadcrumbs: BreadcrumbItem[] = [
        {
            title: 'Pembiayaan',
            href: financingsRoutes.index().url,
        },
        {
            title: 'Jadwal Angsuran',
            href: '',
        },
    ];

    // Filter state (synced with URL)
    const [statusFilter, setStatusFilter] = useState(filters.status || 'all');
    const [fromDate, setFromDate] = useState(filters.from || '');
    const [toDate, setToDate] = useState(filters.to || '');

    // Calculate two-days-ago date for overdue check
    const twoDaysAgo = useMemo(() => {
        const date = new Date();
        date.setDate(date.getDate() - 2);
        return date;
    }, []); // Only recalculate on mount

    // Helper to check if installment is 2+ days overdue
    const isOverdueByDate = useCallback(
        (dueDate: string) => {
            return new Date(dueDate) < twoDaysAgo;
        },
        [twoDaysAgo],
    );

    // Client-side filtering for display only (backend returns all data)
    const filteredInstallments = useMemo(() => {
        if (!installments) return [];
        return installments.data.filter((installment) => {
            // Status filter
            if (statusFilter !== 'all') {
                const isOverdue =
                    isOverdueByDate(installment.due_date) &&
                    installment.status !== 'paid';

                if (statusFilter === 'overdue' && !isOverdue) return false;
                if (statusFilter === 'paid' && installment.status !== 'paid')
                    return false;
                if (
                    statusFilter === 'pending' &&
                    (installment.status === 'paid' || isOverdue)
                )
                    return false;
            }

            // Date range filter
            if (fromDate) {
                const from = new Date(fromDate);
                const due = new Date(installment.due_date);
                if (due < from) return false;
            }

            if (toDate) {
                const to = new Date(toDate);
                const due = new Date(installment.due_date);
                if (due > to) return false;
            }

            return true;
        });
    }, [installments, statusFilter, fromDate, toDate, isOverdueByDate]);

    // Calculate stats based on all installments
    const stats = useMemo(() => {
        const total = financing.installment_count;
        const paid =
            financing.installments?.filter((i) => i.status === 'paid').length ||
            0;
        const pending =
            financing.installments?.filter(
                (i) => i.status === 'pending' || i.status === 'partial',
            ).length || 0;
        const overdue =
            financing.installments?.filter(
                (i) => isOverdueByDate(i.due_date) && i.status !== 'paid',
            ).length || 0;

        return { total, paid, pending, overdue };
    }, [financing.installment_count, financing.installments, isOverdueByDate]);

    // Check if due date is Sunday
    const isSunday = (dateString: string) => {
        const date = new Date(dateString);
        return date.getDay() === 0;
    };

    // Get installment status for badge
    const getInstallmentStatus = (installment: FinancingInstallment) => {
        if (installment.status === 'paid') return 'paid';
        if (installment.status === 'overdue') return 'overdue';
        if (installment.status === 'partial') {
            const isOverdueDate = isOverdueByDate(installment.due_date);
            return isOverdueDate ? 'partial-overdue' : 'partial';
        }

        // For pending status, check if overdue by date (2+ days)
        const isOverdueDate = isOverdueByDate(installment.due_date);
        if (installment.status === 'pending' && isOverdueDate) {
            return 'overdue';
        }

        return 'pending';
    };

    // Export CSV
    const handleExportCSV = () => {
        const filename = `jadwal-angsuran-${financing.account_number}.csv`;

        exportToCSV(
            [
                'No',
                'Tanggal Jatuh Tempo',
                'Pokok',
                'Margin',
                'Total',
                'Dibayar',
                'Sisa',
                'Status',
            ],
            filteredInstallments.map((installment) => ({
                No: installment.sequence_number.toString(),
                'Tanggal Jatuh Tempo': installment.due_date,
                Pokok: installment.principal_amount.toString(),
                Margin: installment.margin_amount.toString(),
                Total: installment.total_amount.toString(),
                Dibayar: installment.paid_total.toString(),
                Sisa: (
                    installment.total_amount - installment.paid_total
                ).toString(),
                Status: installment.status,
            })),
            filename,
        );
    };

    // Print schedule
    const handlePrint = () => {
        window.print();
    };

    return (
        <AppLayout breadcrumbs={breadcrumbs}>
            <Head title={`Jadwal Angsuran - ${financing.account_number}`} />

            <div className="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
                {/* Header */}
                <div className="flex items-center justify-between">
                    <div className="flex items-center gap-4">
                        <Button variant="outline" size="icon" asChild>
                            <Link
                                href={
                                    financingsRoutes.show({
                                        financing: financing.id,
                                    }).url
                                }
                            >
                                <ArrowLeft className="h-4 w-4" />
                            </Link>
                        </Button>
                        <div className="flex flex-col gap-1">
                            <h1 className="text-2xl font-black">
                                Jadwal Angsuran
                            </h1>
                            <span className="text-sm text-muted-foreground">
                                {financing.account_number} •{' '}
                                {financing.member?.name || 'Unknown'}
                            </span>
                        </div>
                    </div>

                    <div className="no-print flex gap-2">
                        <Button variant="outline" onClick={handlePrint}>
                            <Calendar className="mr-2 h-4 w-4" />
                            Cetak
                        </Button>
                        <Button variant="outline" onClick={handleExportCSV}>
                            <Download className="mr-2 h-4 w-4" />
                            Export CSV
                        </Button>
                    </div>
                </div>

                {/* Stats Cards */}
                <div className="grid gap-4 md:grid-cols-3">
                    <Card>
                        <CardHeader>
                            <CardTitle>Sudah Dibayar</CardTitle>
                            <CardAction>
                                <CheckCircle className="h-4 w-4" />
                            </CardAction>
                        </CardHeader>
                        <CardContent>
                            <div className="text-2xl font-bold text-green-600">
                                {stats.paid}
                            </div>
                            <p className="text-xs text-muted-foreground">
                                {((stats.paid / stats.total) * 100).toFixed(1)}%
                                selesai
                            </p>
                        </CardContent>
                    </Card>

                    <Card>
                        <CardHeader>
                            <CardTitle>Belum Dibayar</CardTitle>
                            <CardAction>
                                <Clock className="h-4 w-4" />
                            </CardAction>
                        </CardHeader>
                        <CardContent>
                            <div className="text-2xl font-bold">
                                {stats.pending}
                            </div>
                            <p className="text-xs text-muted-foreground">
                                {stats.pending > 0
                                    ? `${formatIDR(
                                          stats.pending *
                                              financing.installment_amount,
                                      )} outstanding`
                                    : 'Tidak ada'}
                            </p>
                        </CardContent>
                    </Card>

                    <Card>
                        <CardHeader>
                            <CardTitle>Telat Bayar</CardTitle>
                            <CardAction>
                                <AlertCircle className="h-4 w-4" />
                            </CardAction>
                        </CardHeader>
                        <CardContent>
                            <div className="text-2xl font-bold text-destructive">
                                {stats.overdue}
                            </div>
                            <p className="text-xs text-muted-foreground">
                                {stats.overdue > 0
                                    ? 'Perlu ditagih'
                                    : 'Tidak ada'}
                            </p>
                        </CardContent>
                    </Card>
                </div>

                {/* Filters */}
                <Card className="no-print">
                    <CardHeader>
                        <CardTitle className="flex items-center gap-2">
                            <PackageIcon className="h-5 w-5" />
                            Filter
                        </CardTitle>
                    </CardHeader>
                    <CardContent>
                        <div className="grid gap-4 md:grid-cols-3">
                            {/* Status Filter */}
                            <div className="space-y-2">
                                <Label htmlFor="status">Status</Label>
                                <Select
                                    value={statusFilter}
                                    onValueChange={setStatusFilter}
                                >
                                    <SelectTrigger>
                                        <SelectValue placeholder="Semua Status" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectGroup>
                                            <SelectLabel>Status</SelectLabel>
                                            <SelectItem value="all">
                                                Semua
                                            </SelectItem>
                                            <SelectItem value="paid">
                                                Lunas
                                            </SelectItem>
                                            <SelectItem value="pending">
                                                Belum Dibayar
                                            </SelectItem>
                                            <SelectItem value="overdue">
                                                Telat Bayar
                                            </SelectItem>
                                        </SelectGroup>
                                    </SelectContent>
                                </Select>
                            </div>

                            {/* From Date */}
                            <div className="space-y-2">
                                <Label htmlFor="from">Dari Tanggal</Label>
                                <Input
                                    id="from"
                                    type="date"
                                    value={fromDate}
                                    onChange={(e) =>
                                        setFromDate(e.target.value)
                                    }
                                />
                            </div>

                            {/* To Date */}
                            <div className="space-y-2">
                                <Label htmlFor="to">Sampai Tanggal</Label>
                                <Input
                                    id="to"
                                    type="date"
                                    value={toDate}
                                    onChange={(e) => setToDate(e.target.value)}
                                />
                            </div>
                        </div>
                    </CardContent>
                </Card>

                {/* Installments Table */}
                <Card>
                    <CardHeader>
                        <CardTitle className="flex items-center gap-2 pb-2">
                            <FileText className="h-4 w-4" />
                            Daftar Angsuran
                            <span className="ml-2 text-sm font-normal text-muted-foreground">
                                ({filteredInstallments.length} dari{' '}
                                {stats.total})
                            </span>
                            {installments?.current_page && (
                                <span className="ml-2 text-sm font-normal text-muted-foreground">
                                    Halaman {installments?.current_page} dari{' '}
                                    {installments?.last_page || 1}
                                </span>
                            )}
                        </CardTitle>
                    </CardHeader>
                    <CardContent>
                        <Table>
                            <TableHeader>
                                <TableRow>
                                    <TableHead className="w-12">No</TableHead>
                                    <TableHead>Tanggal Jatuh Tempo</TableHead>
                                    <TableHead className="text-right">
                                        Pokok
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Margin
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Total
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Dibayar
                                    </TableHead>
                                    <TableHead className="text-right">
                                        Sisa
                                    </TableHead>
                                    <TableHead className="text-center">
                                        Status
                                    </TableHead>
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {filteredInstallments.map((installment) => {
                                    const outstanding =
                                        installment.total_amount -
                                        installment.paid_total;

                                    const sunday = isSunday(
                                        installment.due_date,
                                    );

                                    return (
                                        <TableRow
                                            key={installment.id}
                                            className={
                                                sunday
                                                    ? 'bg-yellow-50 dark:bg-yellow-950/20'
                                                    : ''
                                            }
                                        >
                                            <TableCell>
                                                <div className="flex items-center gap-2">
                                                    <span className="font-medium">
                                                        {
                                                            installment.sequence_number
                                                        }
                                                    </span>
                                                    {sunday && (
                                                        <span className="rounded bg-yellow-200 px-2 py-0.5 text-xs font-medium text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200">
                                                            Minggu
                                                        </span>
                                                    )}
                                                </div>
                                            </TableCell>
                                            <TableCell>
                                                {formatDateID(
                                                    installment.due_date,
                                                )}
                                            </TableCell>
                                            <TableCell className="text-right">
                                                {formatIDR(
                                                    installment.principal_amount,
                                                )}
                                            </TableCell>
                                            <TableCell className="text-right">
                                                {formatIDR(
                                                    installment.margin_amount,
                                                )}
                                            </TableCell>
                                            <TableCell className="text-right font-medium">
                                                {formatIDR(
                                                    installment.total_amount,
                                                )}
                                            </TableCell>
                                            <TableCell className="text-right">
                                                <span
                                                    className={
                                                        installment.paid_total >
                                                        0
                                                            ? 'font-medium text-green-600'
                                                            : 'text-muted-foreground'
                                                    }
                                                >
                                                    {formatIDR(
                                                        installment.paid_total,
                                                    )}{' '}
                                                </span>
                                            </TableCell>
                                            <TableCell className="text-right">
                                                <span
                                                    className={
                                                        outstanding > 0
                                                            ? 'font-medium text-destructive'
                                                            : 'text-muted-foreground'
                                                    }
                                                >
                                                    {formatIDR(outstanding)}
                                                </span>
                                            </TableCell>
                                            <TableCell className="text-center">
                                                <StatusBadge
                                                    type="installment"
                                                    status={getInstallmentStatus(
                                                        installment,
                                                    )}
                                                />
                                            </TableCell>
                                        </TableRow>
                                    );
                                })}
                            </TableBody>
                        </Table>

                        {filteredInstallments.length === 0 && (
                            <div className="py-8 text-center text-muted-foreground">
                                Tidak ada angsuran yang cocok dengan filter
                            </div>
                        )}

                        {/* Pagination */}
                        {installments?.last_page &&
                            installments.last_page > 1 && (
                                <div className="mt-4 flex items-center justify-between border-t pt-4">
                                    <div className="text-sm text-muted-foreground">
                                        Menampilkan{' '}
                                        <span className="font-medium">
                                            {installments?.from}
                                        </span>{' '}
                                        sampai{' '}
                                        <span className="font-medium">
                                            {installments?.to}
                                        </span>{' '}
                                        dari{' '}
                                        <span className="font-medium">
                                            {installments?.total}
                                        </span>{' '}
                                        angsuran
                                    </div>

                                    <div className="flex items-center gap-2">
                                        {installments?.prev_page_url && (
                                            <Link
                                                href={
                                                    installments.prev_page_url
                                                }
                                                className="inline-flex"
                                            >
                                                <Button
                                                    variant="outline"
                                                    size="sm"
                                                    type="button"
                                                >
                                                    <ChevronLeft className="h-4 w-4" />
                                                    Sebelumnya
                                                </Button>
                                            </Link>
                                        )}

                                        <div className="flex gap-1">
                                            {Array.from(
                                                {
                                                    length:
                                                        installments?.last_page ||
                                                        0,
                                                },
                                                (_, i) => {
                                                    const page = i + 1;
                                                    // Show first 2, last 2, and current page with surrounding pages
                                                    if (
                                                        page <= 2 ||
                                                        page >
                                                            (installments?.last_page ||
                                                                0) -
                                                                2 ||
                                                        (page >=
                                                            (installments?.current_page ||
                                                                0) -
                                                                1 &&
                                                            page <=
                                                                (installments?.current_page ||
                                                                    0) +
                                                                    1)
                                                    ) {
                                                        return (
                                                            <Link
                                                                key={page}
                                                                href={
                                                                    installments
                                                                        ?.links?.[
                                                                        page
                                                                    ]?.url ||
                                                                    '#'
                                                                }
                                                                className={
                                                                    !installments
                                                                        ?.links?.[
                                                                        page
                                                                    ]?.url
                                                                        ? 'pointer-events-none'
                                                                        : ''
                                                                }
                                                            >
                                                                <Button
                                                                    variant={
                                                                        installments?.current_page ===
                                                                        page
                                                                            ? 'default'
                                                                            : 'outline'
                                                                    }
                                                                    size="sm"
                                                                    className="h-8 w-8 p-0"
                                                                    disabled={
                                                                        !installments
                                                                            ?.links?.[
                                                                            page
                                                                        ]?.url
                                                                    }
                                                                    type="button"
                                                                >
                                                                    {page}
                                                                </Button>
                                                            </Link>
                                                        );
                                                    } else if (
                                                        page === 3 ||
                                                        page ===
                                                            (installments?.last_page ||
                                                                0) -
                                                                2
                                                    ) {
                                                        return (
                                                            <span
                                                                key={page}
                                                                className="flex h-8 items-center px-1 text-muted-foreground"
                                                            >
                                                                ...
                                                            </span>
                                                        );
                                                    }
                                                    return null;
                                                },
                                            )}
                                        </div>

                                        {installments?.next_page_url && (
                                            <Link
                                                href={
                                                    installments.next_page_url
                                                }
                                                className="inline-flex"
                                            >
                                                <Button
                                                    variant="outline"
                                                    size="sm"
                                                    type="button"
                                                >
                                                    Selanjutnya
                                                    <ChevronRight className="h-4 w-4" />
                                                </Button>
                                            </Link>
                                        )}
                                    </div>
                                </div>
                            )}
                    </CardContent>
                </Card>
            </div>
        </AppLayout>
    );
}
