import { index as transactionsIndex } from '@/actions/App/Http/Controllers/TransactionController';
import { PercentageTrendIndicator } from '@/components/dashboard/percentage-trend-indicator';
import { AmountDisplay } from '@/components/ui/amount-display';
import {
    Card,
    CardContent,
    CardDescription,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import { Progress } from '@/components/ui/progress';
import { BreakdownData } from '@/hooks/use-cashflow-data';
import { useChartColors } from '@/hooks/use-chart-color-scheme';
import { cn } from '@/lib/utils';
import {
    type CategoryColor,
    type CategoryIcon,
    getCategoryColorClasses,
} from '@/types/category';
import { __ } from '@/utils/i18n';
import { Link } from '@inertiajs/react';
import { format } from 'date-fns';
import * as Icons from 'lucide-react';
import { LucideIcon } from 'lucide-react';

interface BreakdownCardProps {
    type: 'income' | 'expense';
    data: BreakdownData;
    loading?: boolean;
    currency?: string;
    period?: { from: Date; to: Date };
}

const fallbackCategory = {
    name: __('Uncategorized'),
    icon: 'HelpCircle' as CategoryIcon,
    color: 'gray' as CategoryColor,
};

export function BreakdownCard({
    type,
    data,
    loading,
    currency = 'USD',
    period,
}: BreakdownCardProps) {
    const { categoryBarColor } = useChartColors();
    const title =
        type === 'income' ? __('Income Sources') : __('Expense Categories');
    const description =
        type === 'income'
            ? __('Where your money comes from')
            : __('Where your money goes');
    const emptyMessage =
        type === 'income'
            ? __('No income this period')
            : __('No expenses this period');

    if (loading) {
        return (
            <Card>
                <CardHeader>
                    <CardTitle className="text-base">{title}</CardTitle>
                </CardHeader>
                <CardContent>
                    <div className="space-y-4">
                        {Array.from({ length: 4 }).map((_, i) => (
                            <div key={i} className="space-y-2">
                                <div className="flex items-center gap-3">
                                    <div className="size-6 animate-pulse rounded-full bg-gray-200 dark:bg-gray-700" />
                                    <div className="h-4 w-24 animate-pulse rounded bg-gray-200 dark:bg-gray-700" />
                                    <div className="ml-auto h-4 w-16 animate-pulse rounded bg-gray-200 dark:bg-gray-700" />
                                </div>
                                <div className="h-2 w-full animate-pulse rounded-full bg-gray-200 dark:bg-gray-700" />
                            </div>
                        ))}
                    </div>
                </CardContent>
            </Card>
        );
    }

    return (
        <Card>
            <CardHeader className="gap-1 pb-4">
                <div className="flex items-center justify-between">
                    <CardTitle className="text-base">{title}</CardTitle>
                    <AmountDisplay
                        amountInCents={data.total}
                        currencyCode={currency}
                        minimumFractionDigits={0}
                        maximumFractionDigits={0}
                        weight="semibold"
                        highlightPositive
                    />
                </div>
                <CardDescription>{description}</CardDescription>
            </CardHeader>
            <CardContent>
                <div className="space-y-4">
                    {data.data.map((item, index) => {
                        const category = item.category ?? fallbackCategory;
                        const Icon = (Icons[
                            category.icon as keyof typeof Icons
                        ] || Icons.HelpCircle) as LucideIcon;

                        const percentageChange =
                            item.previous_amount > 0
                                ? ((item.amount - item.previous_amount) /
                                      item.previous_amount) *
                                  100
                                : null;

                        const categoryColor = getCategoryColorClasses(
                            category.color,
                        );
                        const chartColor = categoryBarColor(
                            category.color,
                            index,
                        );

                        const categoryUrl = period
                            ? transactionsIndex({
                                  query: {
                                      category_ids: item.category_id,
                                      date_from: format(
                                          period.from,
                                          'yyyy-MM-dd',
                                      ),
                                      date_to: format(period.to, 'yyyy-MM-dd'),
                                  },
                              }).url
                            : null;

                        const rowContent = (
                            <>
                                <div className="flex min-w-0 items-center justify-between gap-2 overflow-hidden">
                                    <div className="flex max-w-[60%] grow gap-2">
                                        <div
                                            className={cn([
                                                'flex size-6 shrink-0 items-center justify-center rounded-full',
                                                `${categoryColor.bg} ${categoryColor.text}`,
                                            ])}
                                        >
                                            <Icon className="size-3.5" />
                                        </div>
                                        <span className="min-w-0 truncate text-sm font-medium">
                                            {category.name}
                                        </span>
                                    </div>
                                    <div className="flex gap-2">
                                        {percentageChange !== null && (
                                            <PercentageTrendIndicator
                                                trend={percentageChange}
                                                label=""
                                                previousAmount={
                                                    item.previous_amount
                                                }
                                                currentAmount={item.amount}
                                                currencyCode={currency}
                                                invertColors={
                                                    type === 'expense'
                                                }
                                                className="shrink-0 text-xs"
                                            />
                                        )}
                                        <div className="flex shrink-0 items-center gap-2">
                                            <span className="hidden text-xs text-muted-foreground sm:inline">
                                                {item.percentage.toFixed(0)}%
                                            </span>
                                            <AmountDisplay
                                                amountInCents={item.amount}
                                                currencyCode={currency}
                                                variant="compact"
                                                minimumFractionDigits={0}
                                                maximumFractionDigits={0}
                                            />
                                        </div>
                                    </div>
                                </div>
                                <Progress
                                    value={item.percentage}
                                    className="h-1.5"
                                    indicatorColor={chartColor}
                                />
                            </>
                        );

                        return categoryUrl ? (
                            <Link
                                key={item.category_id}
                                href={categoryUrl}
                                className="group -mx-1.5 my-1.5 block space-y-1.5 rounded-md px-1.5 py-1 transition-colors hover:bg-muted"
                            >
                                {rowContent}
                            </Link>
                        ) : (
                            <div key={item.category_id} className="space-y-1.5">
                                {rowContent}
                            </div>
                        );
                    })}
                    {data.data.length === 0 && (
                        <div className="py-6 text-center text-sm text-muted-foreground">
                            {emptyMessage}
                        </div>
                    )}
                </div>
            </CardContent>
        </Card>
    );
}
