import type { ColumnDef } from '@tanstack/react-table';
import { format, isBefore, startOfDay } from 'date-fns';
import { CreditCard, Pencil, Trash2 } from 'lucide-react';
import { RowActions } from '@/components/row-actions';
import { Badge } from '@/components/ui/badge';
import { formatRupiah } from '@/lib/currency';
import { cn } from '@/lib/utils';
import { index as paymentsIndex } from '@/routes/admin/finances/tuition-invoices/payments';
import { formatAcademicTermLabel } from '@/types/academic-term';
import type { TuitionInvoice } from '@/types/tuition-invoice';

export type { TuitionInvoice } from '@/types/tuition-invoice';

type CreateColumnsParams = {
    handleEdit: (invoice: TuitionInvoice) => void;
    handleDeleteClick: (invoice: TuitionInvoice) => void;
    canUpdate: boolean;
    canDelete: boolean;
    canViewPayments: boolean;
};

export function createTuitionInvoiceColumns(
    params: CreateColumnsParams,
): ColumnDef<TuitionInvoice>[] {
    const {
        handleEdit,
        handleDeleteClick,
        canUpdate,
        canDelete,
        canViewPayments,
    } = params;

    const columns: ColumnDef<TuitionInvoice>[] = [
        {
            accessorKey: 'student.student_number',
            header: () => <span>Mahasiswa</span>,
            cell: ({ row }) => {
                const student = row.original.student;

                return (
                    <div>
                        <p className="font-medium">
                            {student?.user?.profile?.full_name ?? 'N/A'}
                        </p>
                        <p className="text-xs text-muted-foreground">
                            {student?.student_number} &middot;{' '}
                            {student?.department?.name ?? '-'}
                        </p>
                    </div>
                );
            },
        },
        {
            accessorKey: 'academic_term.name',
            header: () => <span>Periode</span>,
            cell: ({ row }) => {
                const term = row.original.academic_term;

                return term ? formatAcademicTermLabel(term) : '-';
            },
        },
        {
            accessorKey: 'amount_due',
            header: () => <span>Tagihan</span>,
            cell: ({ row }) => formatRupiah(row.getValue('amount_due')),
        },
        {
            accessorKey: 'paid_total',
            header: () => <span>Status Bayar</span>,
            cell: ({ row }) => {
                const invoice = row.original;
                const paidTotal = Number(invoice.paid_total ?? 0);
                const amountDue = Number(invoice.amount_due);

                const variant =
                    paidTotal >= amountDue && amountDue > 0
                        ? 'default'
                        : paidTotal > 0
                          ? 'secondary'
                          : 'outline';
                const label =
                    paidTotal >= amountDue && amountDue > 0
                        ? 'Lunas'
                        : paidTotal > 0
                          ? 'Sebagian'
                          : 'Belum Bayar';

                return (
                    <div className="flex flex-col gap-1">
                        <Badge variant={variant} className="w-fit">
                            {label}
                        </Badge>
                        <span className="text-xs text-muted-foreground">
                            {formatRupiah(paidTotal)} /{' '}
                            {formatRupiah(amountDue)}
                        </span>
                    </div>
                );
            },
        },
        {
            accessorKey: 'due_date',
            header: () => <span>Jatuh Tempo</span>,
            cell: ({ row }) => {
                const invoice = row.original;
                const dueDate = row.getValue('due_date') as string | null;

                if (!dueDate) {
                    return '-';
                }

                const paidTotal = Number(invoice.paid_total ?? 0);
                const amountDue = Number(invoice.amount_due);
                const isOverdue =
                    paidTotal < amountDue &&
                    isBefore(new Date(dueDate), startOfDay(new Date()));

                return (
                    <span
                        className={cn(
                            isOverdue && 'font-medium text-destructive',
                        )}
                    >
                        {format(new Date(dueDate), 'd MMM yyyy')}
                    </span>
                );
            },
        },
    ];

    if (canViewPayments || canUpdate || canDelete) {
        columns.push({
            id: 'actions',
            header: () => <span className="block text-center">Aksi</span>,
            meta: {
                className: 'w-[130px] text-center',
                headerClassName: 'w-[130px] text-center',
            },
            cell: ({ row }) => {
                const invoice = row.original;

                return (
                    <RowActions
                        actions={[
                            {
                                label: 'Pembayaran',
                                icon: <CreditCard className="h-4 w-4" />,
                                show: canViewPayments,
                                href: paymentsIndex.url(invoice.id),
                            },
                            {
                                label: 'Edit',
                                icon: <Pencil className="h-4 w-4" />,
                                show: canUpdate,
                                onClick: () => handleEdit(invoice),
                            },
                            {
                                label: 'Hapus',
                                icon: (
                                    <Trash2 className="h-4 w-4 text-destructive" />
                                ),
                                show: canDelete,
                                onClick: () => handleDeleteClick(invoice),
                            },
                        ]}
                    />
                );
            },
        });
    }

    return columns;
}
