"use client";

import { useMemo } from "react";
import { Bar, BarChart, XAxis, YAxis, CartesianGrid, ResponsiveContainer, Area, AreaChart } from "recharts";

import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { ChartContainer, ChartTooltip, ChartTooltipContent } from "@/components/ui/chart";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { formatCurrency } from "@/lib/utils";
import { BankingTransaction, TransactionType } from "@/types/banking";

interface TransactionTrendsProps {
    transactions: BankingTransaction[];
    timeRange?: "7d" | "30d" | "90d" | "1y";
    onTimeRangeChange?: (range: "7d" | "30d" | "90d" | "1y") => void;
    className?: string;
}

const chartConfig = {
    deposits: {
        label: "Dépôts",
        color: "var(--chart-1)",
    },
    withdrawals: {
        label: "Retraits",
        color: "var(--chart-2)",
    },
    transfers: {
        label: "Transferts",
        color: "var(--chart-3)",
    },
    fees: {
        label: "Frais",
        color: "var(--chart-4)",
    },
    net: {
        label: "Solde net",
        color: "var(--chart-5)",
    },
};

const timeRangeOptions = [
    { value: "7d", label: "7 jours", days: 7 },
    { value: "30d", label: "30 jours", days: 30 },
    { value: "90d", label: "3 mois", days: 90 },
    { value: "1y", label: "1 an", days: 365 },
];

export function TransactionTrends({
    transactions,
    timeRange = "30d",
    onTimeRangeChange,
    className,
}: TransactionTrendsProps) {
    const filteredTransactions = useMemo(() => {
        const range = timeRangeOptions.find(option => option.value === timeRange);
        const days = range?.days || 30;
        const startDate = new Date();
        startDate.setDate(startDate.getDate() - days);

        return transactions.filter(transaction =>
            new Date(transaction.transaction_date) >= startDate
        );
    }, [transactions, timeRange]);

    const chartData = useMemo(() => {
        const range = timeRangeOptions.find(option => option.value === timeRange);
        const days = range?.days || 30;

        // Grouper les transactions par période
        const groupByPeriod = (transactions: BankingTransaction[]) => {
            const groups: { [key: string]: BankingTransaction[] } = {};

            transactions.forEach(transaction => {
                const date = new Date(transaction.transaction_date);
                let key: string;

                if (days <= 7) {
                    // Par jour pour 7 jours
                    key = date.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit' });
                } else if (days <= 30) {
                    // Par jour pour 30 jours
                    key = date.toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' });
                } else if (days <= 90) {
                    // Par semaine pour 3 mois
                    const weekStart = new Date(date);
                    weekStart.setDate(date.getDate() - date.getDay());
                    key = weekStart.toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' });
                } else {
                    // Par mois pour 1 an
                    key = date.toLocaleDateString('fr-FR', { month: 'short', year: '2-digit' });
                }

                if (!groups[key]) groups[key] = [];
                groups[key].push(transaction);
            });

            return groups;
        };

        const groups = groupByPeriod(filteredTransactions);

        return Object.entries(groups).map(([period, periodTransactions]) => {
            const deposits = periodTransactions
                .filter(t => ['deposit', 'interest'].includes(t.transaction_type))
                .reduce((sum, t) => sum + t.amount, 0);

            const withdrawals = periodTransactions
                .filter(t => ['withdrawal', 'loan_payment'].includes(t.transaction_type))
                .reduce((sum, t) => sum + t.amount, 0);

            const transfers = periodTransactions
                .filter(t => t.transaction_type === 'transfer')
                .reduce((sum, t) => sum + t.amount, 0);

            const fees = periodTransactions
                .filter(t => t.transaction_type === 'fee')
                .reduce((sum, t) => sum + t.amount, 0);

            const net = deposits - withdrawals - fees;

            return {
                period,
                deposits: Math.round(deposits * 100) / 100,
                withdrawals: Math.round(withdrawals * 100) / 100,
                transfers: Math.round(transfers * 100) / 100,
                fees: Math.round(fees * 100) / 100,
                net: Math.round(net * 100) / 100,
            };
        }).sort((a, b) => a.period.localeCompare(b.period));
    }, [filteredTransactions, timeRange]);

    const stats = useMemo(() => {
        const totalDeposits = filteredTransactions
            .filter(t => ['deposit', 'interest'].includes(t.transaction_type))
            .reduce((sum, t) => sum + t.amount, 0);

        const totalWithdrawals = filteredTransactions
            .filter(t => ['withdrawal', 'loan_payment'].includes(t.transaction_type))
            .reduce((sum, t) => sum + t.amount, 0);

        const totalFees = filteredTransactions
            .filter(t => t.transaction_type === 'fee')
            .reduce((sum, t) => sum + t.amount, 0);

        const netFlow = totalDeposits - totalWithdrawals - totalFees;

        return {
            totalDeposits,
            totalWithdrawals,
            totalFees,
            netFlow,
            transactionCount: filteredTransactions.length,
        };
    }, [filteredTransactions]);

    return (
        <Card className={className}>
            <CardHeader>
                <div className="flex items-center justify-between">
                    <div>
                        <CardTitle>Tendances des transactions</CardTitle>
                        <CardDescription>
                            Analyse des flux financiers par période
                        </CardDescription>
                    </div>
                    <Select value={timeRange} onValueChange={onTimeRangeChange}>
                        <SelectTrigger className="w-32">
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            {timeRangeOptions.map((option) => (
                                <SelectItem key={option.value} value={option.value}>
                                    {option.label}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>
            </CardHeader>

            <CardContent className="space-y-6">
                {/* Statistiques rapides */}
                <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                    <div className="space-y-1">
                        <p className="text-xs text-muted-foreground uppercase">Dépôts totaux</p>
                        <p className="text-lg font-semibold text-green-600">{formatCurrency(stats.totalDeposits)}</p>
                    </div>
                    <div className="space-y-1">
                        <p className="text-xs text-muted-foreground uppercase">Retraits totaux</p>
                        <p className="text-lg font-semibold text-red-600">{formatCurrency(stats.totalWithdrawals)}</p>
                    </div>
                    <div className="space-y-1">
                        <p className="text-xs text-muted-foreground uppercase">Frais totaux</p>
                        <p className="text-lg font-semibold text-orange-600">{formatCurrency(stats.totalFees)}</p>
                    </div>
                    <div className="space-y-1">
                        <p className="text-xs text-muted-foreground uppercase">Flux net</p>
                        <p className={`text-lg font-semibold ${stats.netFlow >= 0 ? 'text-green-600' : 'text-red-600'
                            }`}>
                            {formatCurrency(stats.netFlow)}
                        </p>
                    </div>
                </div>

                {/* Graphiques */}
                <Tabs defaultValue="volume" className="w-full">
                    <TabsList className="grid w-full grid-cols-2">
                        <TabsTrigger value="volume">Volume des transactions</TabsTrigger>
                        <TabsTrigger value="flow">Flux net</TabsTrigger>
                    </TabsList>

                    <TabsContent value="volume" className="space-y-4">
                        <div className="h-80">
                            <ChartContainer config={chartConfig} className="h-full w-full">
                                <ResponsiveContainer width="100%" height="100%">
                                    <BarChart data={chartData} margin={{ top: 20, right: 30, left: 20, bottom: 20 }}>
                                        <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
                                        <XAxis
                                            dataKey="period"
                                            axisLine={false}
                                            tickLine={false}
                                            className="text-xs"
                                        />
                                        <YAxis
                                            axisLine={false}
                                            tickLine={false}
                                            tickFormatter={(value) => formatCurrency(value, { noDecimals: true })}
                                            className="text-xs"
                                        />
                                        <ChartTooltip
                                            content={({ active, payload, label }) => {
                                                if (active && payload && payload.length) {
                                                    return (
                                                        <div className="rounded-lg border bg-background p-3 shadow-md">
                                                            <p className="font-medium mb-2">{label}</p>
                                                            <div className="space-y-1 text-sm">
                                                                {payload.map((entry, index) => (
                                                                    <div key={index} className="flex items-center justify-between gap-4">
                                                                        <span style={{ color: entry.color }}>
                                                                            {chartConfig[entry.dataKey as keyof typeof chartConfig]?.label || entry.dataKey}:
                                                                        </span>
                                                                        <span className="font-medium">{formatCurrency(entry.value as number)}</span>
                                                                    </div>
                                                                ))}
                                                            </div>
                                                        </div>
                                                    );
                                                }
                                                return null;
                                            }}
                                        />
                                        <Bar dataKey="deposits" stackId="a" fill="var(--color-deposits)" />
                                        <Bar dataKey="withdrawals" stackId="a" fill="var(--color-withdrawals)" />
                                        <Bar dataKey="transfers" stackId="a" fill="var(--color-transfers)" />
                                        <Bar dataKey="fees" stackId="a" fill="var(--color-fees)" />
                                    </BarChart>
                                </ResponsiveContainer>
                            </ChartContainer>
                        </div>
                    </TabsContent>

                    <TabsContent value="flow" className="space-y-4">
                        <div className="h-80">
                            <ChartContainer config={chartConfig} className="h-full w-full">
                                <ResponsiveContainer width="100%" height="100%">
                                    <AreaChart data={chartData} margin={{ top: 20, right: 30, left: 20, bottom: 20 }}>
                                        <CartesianGrid strokeDasharray="3 3" className="stroke-muted" />
                                        <XAxis
                                            dataKey="period"
                                            axisLine={false}
                                            tickLine={false}
                                            className="text-xs"
                                        />
                                        <YAxis
                                            axisLine={false}
                                            tickLine={false}
                                            tickFormatter={(value) => formatCurrency(value, { noDecimals: true })}
                                            className="text-xs"
                                        />
                                        <ChartTooltip
                                            content={({ active, payload, label }) => {
                                                if (active && payload && payload.length) {
                                                    const data = payload[0].payload;
                                                    return (
                                                        <div className="rounded-lg border bg-background p-3 shadow-md">
                                                            <p className="font-medium mb-2">{label}</p>
                                                            <div className="space-y-1 text-sm">
                                                                <div className="flex items-center justify-between gap-4">
                                                                    <span className="text-green-600">Entrées:</span>
                                                                    <span className="font-medium text-green-600">+{formatCurrency(data.deposits)}</span>
                                                                </div>
                                                                <div className="flex items-center justify-between gap-4">
                                                                    <span className="text-red-600">Sorties:</span>
                                                                    <span className="font-medium text-red-600">-{formatCurrency(data.withdrawals + data.fees)}</span>
                                                                </div>
                                                                <div className="flex items-center justify-between gap-4 border-t pt-1">
                                                                    <span className="font-medium">Flux net:</span>
                                                                    <span className={`font-medium ${data.net >= 0 ? 'text-green-600' : 'text-red-600'
                                                                        }`}>
                                                                        {data.net >= 0 ? '+' : ''}{formatCurrency(data.net)}
                                                                    </span>
                                                                </div>
                                                            </div>
                                                        </div>
                                                    );
                                                }
                                                return null;
                                            }}
                                        />
                                        <Area
                                            type="monotone"
                                            dataKey="net"
                                            stroke="var(--color-net)"
                                            strokeWidth={2}
                                            fill="var(--color-net)"
                                            fillOpacity={0.1}
                                        />
                                    </AreaChart>
                                </ResponsiveContainer>
                            </ChartContainer>
                        </div>
                    </TabsContent>
                </Tabs>

                {/* Résumé */}
                <div className="rounded-lg border p-4 bg-muted/20">
                    <h4 className="font-medium mb-2">Résumé de la période</h4>
                    <div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
                        <div>
                            <p className="text-muted-foreground">Nombre de transactions: <span className="font-medium text-foreground">{stats.transactionCount}</span></p>
                            <p className="text-muted-foreground">Moyenne par transaction: <span className="font-medium text-foreground">{formatCurrency((stats.totalDeposits + stats.totalWithdrawals) / Math.max(stats.transactionCount, 1))}</span></p>
                        </div>
                        <div>
                            <p className="text-muted-foreground">Taux de frais: <span className="font-medium text-foreground">{((stats.totalFees / Math.max(stats.totalDeposits + stats.totalWithdrawals, 1)) * 100).toFixed(2)}%</span></p>
                            <p className="text-muted-foreground">Évolution: <span className={`font-medium ${stats.netFlow >= 0 ? 'text-green-600' : 'text-red-600'
                                }`}>
                                {stats.netFlow >= 0 ? 'Positive' : 'Négative'}
                            </span></p>
                        </div>
                    </div>
                </div>
            </CardContent>
        </Card>
    );
}
