"use client";

import { useState, useMemo } from "react";

import {
    ColumnDef,
    ColumnFiltersState,
    SortingState,
    VisibilityState,
    flexRender,
    getCoreRowModel,
    getFilteredRowModel,
    getPaginationRowModel,
    getSortedRowModel,
    useReactTable,
    Row,
} from "@tanstack/react-table";
import {
    ChevronLeft,
    ChevronRight,
    CreditCard,
    Download,
    Edit,
    Eye,
    Filter,
    MoreHorizontal,
    Plus,
    RefreshCw,
    Search,
    Settings,
} from "lucide-react";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
    DropdownMenu,
    DropdownMenuCheckboxItem,
    DropdownMenuContent,
    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, formatCurrency } from "@/lib/utils";
import { BankingAccount } from "@/types/banking";

import { StatusBadge } from "./status-badge";

interface AccountsTableProps {
    readonly accounts: BankingAccount[];
    readonly loading?: boolean;
    readonly onCreateAccount?: () => void;
    readonly onViewAccount?: (accountId: string) => void;
    readonly onEditAccount?: (accountId: string) => void;
    readonly onRefresh?: () => void;
    readonly onExport?: () => void;
    readonly className?: string;
}

interface AccountFilters {
    search: string;
    account_type: string;
    status: string;
    client_id: string;
}

const accountTypeOptions = [
    { value: "all", label: "Tous les types" },
    { value: "savings", label: "Épargne" },
    { value: "checking", label: "Courant" },
    { value: "credit", label: "Crédit" },
    { value: "pso", label: "Parts Sociales" },
    { value: "loan", label: "Prêt" },
];

const statusOptions = [
    { value: "all", label: "Tous les statuts" },
    { value: "active", label: "Actif" },
    { value: "inactive", label: "Inactif" },
    { value: "frozen", label: "Gelé" },
    { value: "closed", label: "Fermé" },
];

// Move component definitions outside to avoid re-creation on each render
const AccountNumberCell = ({ row }: { row: Row<BankingAccount> }) => (
    <div className="space-y-1">
        <div className="font-medium">{row.getValue("account_number")}</div>
        <div className="text-muted-foreground text-xs">{row.original.account_name}</div>
    </div>
);

const ClientInfoCell = ({ row }: { row: Row<BankingAccount> }) => (
    <div className="space-y-1">
        <div className="font-medium">{row.original.client_name ?? "N/A"}</div>
        <div className="text-muted-foreground text-xs">{row.original.client_email ?? ""}</div>
    </div>
);

const AccountTypeCell = ({ row }: { row: Row<BankingAccount> }) => {
    const typeConfig = {
        savings: { label: "Épargne", color: "bg-green-100 text-green-700", icon: "💰" },
        checking: { label: "Courant", color: "bg-blue-100 text-blue-700", icon: "🏦" },
        credit: { label: "Crédit", color: "bg-purple-100 text-purple-700", icon: "💳" },
        pso: { label: "Parts Sociales", color: "bg-orange-100 text-orange-700", icon: "📊" },
        loan: { label: "Prêt", color: "bg-red-100 text-red-700", icon: "🏠" },
    } as const;

    const accountType = row.getValue("account_type");

    // Type guard to ensure accountType is a valid key
    if (typeof accountType === "string" && accountType in typeConfig) {
        const config = typeConfig[accountType as keyof typeof typeConfig];
        return (
            <Badge variant="secondary" className={cn("text-xs", config.color)}>
                <span className="mr-1">{config.icon}</span>
                {config.label}
            </Badge>
        );
    }

    return <Badge variant="secondary">{String(accountType)}</Badge>;
};

const BalanceCell = ({ row }: { row: Row<BankingAccount> }) => (
    <div className="text-right font-medium tabular-nums">{formatCurrency(row.getValue("balance"))}</div>
);

const LastActivityCell = ({ row }: { row: Row<BankingAccount> }) => {
    const date = row.getValue("last_transaction_date");

    if (!date) {
        return <span className="text-muted-foreground">Aucune</span>;
    }

    // Ensure date is a valid type for Date constructor
    const dateValue = typeof date === "string" || typeof date === "number" || date instanceof Date ? date : null;

    if (!dateValue) {
        return <span className="text-muted-foreground">Aucune</span>;
    }

    try {
        return <div className="text-sm">{new Date(dateValue).toLocaleDateString("fr-FR")}</div>;
    } catch {
        return <span className="text-muted-foreground">Aucune</span>;
    }
};

const ActionsCell = ({
    row,
    onViewAccount,
    onEditAccount,
}: {
    row: Row<BankingAccount>;
    onViewAccount?: (accountId: string) => void;
    onEditAccount?: (accountId: string) => void;
}) => {
    const account = row.original;

    return (
        <DropdownMenu>
            <DropdownMenuTrigger asChild>
                <Button variant="ghost" className="h-8 w-8 p-0">
                    <span className="sr-only">Ouvrir le menu</span>
                    <MoreHorizontal className="h-4 w-4" />
                </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
                <DropdownMenuCheckboxItem onClick={() => onViewAccount?.(account.id)}>
                    <Eye className="mr-2 h-4 w-4" />
                    Voir les détails
                </DropdownMenuCheckboxItem>
                <DropdownMenuCheckboxItem onClick={() => onEditAccount?.(account.id)}>
                    <Edit className="mr-2 h-4 w-4" />
                    Modifier
                </DropdownMenuCheckboxItem>
            </DropdownMenuContent>
        </DropdownMenu>
    );
};

const StatusCell = ({ row }: { row: Row<BankingAccount> }) => (
    <StatusBadge status={row.getValue("status")} variant="account" />
);

// Actions cell component that receives callbacks as props
const ActionsCellWithCallbacks = ({
    row,
    onViewAccount,
    onEditAccount,
}: {
    row: Row<BankingAccount>;
    onViewAccount?: (accountId: string) => void;
    onEditAccount?: (accountId: string) => void;
}) => <ActionsCell row={row} onViewAccount={onViewAccount} onEditAccount={onEditAccount} />;

// Helper to create the actions column  
const createActionsColumn = (
    onViewAccount?: (accountId: string) => void,
    onEditAccount?: (accountId: string) => void,
): ColumnDef<BankingAccount> => ({
    id: "actions",
    enableHiding: false,
    cell: ({ row }) => (
        <ActionsCellWithCallbacks row={row} onViewAccount={onViewAccount} onEditAccount={onEditAccount} />
    ),
});

export function AccountsTable({
    accounts,
    loading = false,
    onCreateAccount,
    onViewAccount,
    onEditAccount,
    onRefresh,
    onExport,
    className,
}: AccountsTableProps) {
    const [sorting, setSorting] = useState<SortingState>([]);
    const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
    const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
    const [rowSelection, setRowSelection] = useState({});

    const [filters, setFilters] = useState<AccountFilters>({
        search: "",
        account_type: "all",
        status: "all",
        client_id: "all",
    });

    const columns: ColumnDef<BankingAccount>[] = [
        {
            accessorKey: "account_number",
            header: "Numéro de compte",
            cell: AccountNumberCell,
        },
        {
            accessorKey: "client_name",
            header: "Client",
            cell: ClientInfoCell,
        },
        {
            accessorKey: "account_type",
            header: "Type",
            cell: AccountTypeCell,
            filterFn: (row, id, value) => {
                return value === "all" || row.getValue(id) === value;
            },
        },
        {
            accessorKey: "balance",
            header: "Solde",
            cell: BalanceCell,
        },
        {
            accessorKey: "status",
            header: "Statut",
            cell: StatusCell,
            filterFn: (row, id, value) => {
                return value === "all" || row.getValue(id) === value;
            },
        },
        {
            accessorKey: "last_transaction_date",
            header: "Dernière activité",
            cell: LastActivityCell,
        },
        {
            id: "actions",
            enableHiding: false,
            cell: ({ row }) => (
                <ActionsCellWithCallbacks row={row} onViewAccount={onViewAccount} onEditAccount={onEditAccount} />
            ),
        },
    ];

    const filteredData = useMemo(() => {
        return accounts.filter((account) => {
            const searchMatch =
                !filters.search ||
                account.account_name.toLowerCase().includes(filters.search.toLowerCase()) ||
                account.account_number.toLowerCase().includes(filters.search.toLowerCase()) ||
                account.client_name?.toLowerCase().includes(filters.search.toLowerCase());

            const typeMatch = filters.account_type === "all" || account.account_type === filters.account_type;
            const statusMatch = filters.status === "all" || account.status === filters.status;

            return searchMatch && typeMatch && statusMatch;
        });
    }, [accounts, filters]);

    const table = useReactTable({
        data: filteredData,
        columns,
        onSortingChange: setSorting,
        onColumnFiltersChange: setColumnFilters,
        getCoreRowModel: getCoreRowModel(),
        getPaginationRowModel: getPaginationRowModel(),
        getSortedRowModel: getSortedRowModel(),
        getFilteredRowModel: getFilteredRowModel(),
        onColumnVisibilityChange: setColumnVisibility,
        onRowSelectionChange: setRowSelection,
        state: {
            sorting,
            columnFilters,
            columnVisibility,
            rowSelection,
        },
        initialState: {
            pagination: {
                pageSize: 10,
            },
        },
    });

    const handleFilterChange = (key: keyof AccountFilters, value: string) => {
        setFilters((prev) => ({ ...prev, [key]: value }));
    };

    const resetFilters = () => {
        setFilters({
            search: "",
            account_type: "all",
            status: "all",
            client_id: "all",
        });
    };

    // Calculs des statistiques
    const totalAccounts = filteredData.length;
    const totalBalance = filteredData.reduce((sum, account) => sum + account.balance, 0);
    const activeAccounts = filteredData.filter((account) => account.status === "active").length;

    return (
        <Card className={className}>
            <CardHeader>
                <div className="flex items-center justify-between">
                    <div>
                        <CardTitle className="flex items-center gap-2">
                            <CreditCard className="h-5 w-5" />
                            Comptes Bancaires
                        </CardTitle>
                        <CardDescription>Gestion des comptes bancaires des clients</CardDescription>
                    </div>
                    <div className="flex items-center space-x-2">
                        <Button onClick={onRefresh} variant="outline" size="sm" disabled={loading}>
                            <RefreshCw className={cn("mr-2 h-4 w-4", loading && "animate-spin")} />
                            Actualiser
                        </Button>
                        <Button onClick={onExport} variant="outline" size="sm">
                            <Download className="mr-2 h-4 w-4" />
                            Exporter
                        </Button>
                        <Button onClick={onCreateAccount} size="sm">
                            <Plus className="mr-2 h-4 w-4" />
                            Nouveau compte
                        </Button>
                    </div>
                </div>
            </CardHeader>

            <CardContent className="space-y-4">
                {/* Statistiques rapides */}
                <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
                    <Card>
                        <CardContent className="p-4">
                            <div className="text-2xl font-bold">{totalAccounts}</div>
                            <p className="text-muted-foreground text-xs">Total des comptes</p>
                        </CardContent>
                    </Card>
                    <Card>
                        <CardContent className="p-4">
                            <div className="text-2xl font-bold">{formatCurrency(totalBalance)}</div>
                            <p className="text-muted-foreground text-xs">Solde total</p>
                        </CardContent>
                    </Card>
                    <Card>
                        <CardContent className="p-4">
                            <div className="text-2xl font-bold">{activeAccounts}</div>
                            <p className="text-muted-foreground text-xs">Comptes actifs</p>
                        </CardContent>
                    </Card>
                </div>

                {/* Filtres */}
                <div className="flex flex-col space-y-4 md:flex-row md:items-center md:space-y-0 md:space-x-4">
                    <div className="flex flex-1 items-center space-x-2">
                        <Search className="text-muted-foreground h-4 w-4" />
                        <Input
                            placeholder="Rechercher par nom, numéro de compte ou client..."
                            value={filters.search}
                            onChange={(event) => handleFilterChange("search", event.target.value)}
                            className="max-w-sm"
                        />
                    </div>

                    <Select value={filters.account_type} onValueChange={(value) => handleFilterChange("account_type", value)}>
                        <SelectTrigger className="w-48">
                            <SelectValue placeholder="Type de compte" />
                        </SelectTrigger>
                        <SelectContent>
                            {accountTypeOptions.map((option) => (
                                <SelectItem key={option.value} value={option.value}>
                                    {option.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>

                    <Select value={filters.status} onValueChange={(value) => handleFilterChange("status", value)}>
                        <SelectTrigger className="w-48">
                            <SelectValue placeholder="Statut" />
                        </SelectTrigger>
                        <SelectContent>
                            {statusOptions.map((option) => (
                                <SelectItem key={option.value} value={option.value}>
                                    {option.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>

                    <Button variant="outline" onClick={resetFilters} size="sm">
                        <Filter className="mr-2 h-4 w-4" />
                        Réinitialiser
                    </Button>

                    <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                            <Button variant="outline" size="sm">
                                <Settings className="mr-2 h-4 w-4" />
                                Colonnes
                            </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                            {table
                                .getAllColumns()
                                .filter((column) => column.getCanHide())
                                .map((column) => {
                                    return (
                                        <DropdownMenuCheckboxItem
                                            key={column.id}
                                            className="capitalize"
                                            checked={column.getIsVisible()}
                                            onCheckedChange={(value) => column.toggleVisibility(!!value)}
                                        >
                                            {column.id}
                                        </DropdownMenuCheckboxItem>
                                    );
                                })}
                        </DropdownMenuContent>
                    </DropdownMenu>
                </div>

                {/* Tableau */}
                <div className="rounded-md border">
                    <Table>
                        <TableHeader>
                            {table.getHeaderGroups().map((headerGroup) => (
                                <TableRow key={headerGroup.id}>
                                    {headerGroup.headers.map((header) => {
                                        return (
                                            <TableHead key={header.id}>
                                                {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())}
                                            </TableHead>
                                        );
                                    })}
                                </TableRow>
                            ))}
                        </TableHeader>
                        <TableBody>
                            {loading ? (
                                <TableRow>
                                    <TableCell colSpan={columns.length} className="h-24 text-center">
                                        <div className="flex items-center justify-center">
                                            <RefreshCw className="mr-2 h-4 w-4 animate-spin" />
                                            Chargement...
                                        </div>
                                    </TableCell>
                                </TableRow>
                            ) : table.getRowModel().rows.length ? (
                                table.getRowModel().rows.map((row) => (
                                    <TableRow key={row.id} data-state={row.getIsSelected() && "selected"} className="hover:bg-muted/50">
                                        {row.getVisibleCells().map((cell) => (
                                            <TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
                                        ))}
                                    </TableRow>
                                ))
                            ) : (
                                <TableRow>
                                    <TableCell colSpan={columns.length} className="h-24 text-center">
                                        Aucun compte trouvé.
                                    </TableCell>
                                </TableRow>
                            )}
                        </TableBody>
                    </Table>
                </div>

                {/* Pagination */}
                <div className="flex items-center justify-between space-x-2 py-4">
                    <div className="text-muted-foreground text-sm">
                        {table.getFilteredSelectedRowModel().rows.length} sur {table.getFilteredRowModel().rows.length} ligne(s)
                        sélectionnée(s).
                    </div>
                    <div className="flex items-center space-x-2">
                        <p className="text-sm font-medium">
                            Page {table.getState().pagination.pageIndex + 1} sur {table.getPageCount()}
                        </p>
                        <div className="flex items-center space-x-2">
                            <Button
                                variant="outline"
                                size="sm"
                                onClick={() => table.previousPage()}
                                disabled={!table.getCanPreviousPage()}
                            >
                                <ChevronLeft className="h-4 w-4" />
                                Précédent
                            </Button>
                            <Button variant="outline" size="sm" onClick={() => table.nextPage()} disabled={!table.getCanNextPage()}>
                                Suivant
                                <ChevronRight className="h-4 w-4" />
                            </Button>
                        </div>
                    </div>
                </div>
            </CardContent>
        </Card>
    );
}
