import { Head, router } from '@inertiajs/react';
import { ChartErrorBoundary } from '@/components/chart-error-boundary';
import type { ColumnDef } from '@tanstack/react-table';
import { BarChart3, MoreHorizontal, TrendingUp, Users } from 'lucide-react';
import { useMemo, useState } from 'react';
import type { DateRange } from 'react-day-picker';
import { Area, AreaChart, CartesianGrid, Label, Pie, PieChart, XAxis } from 'recharts';
import { DataTable } from '@/components/data-table';
import { ReportsActionBar } from '@/components/reporting/reports-action-bar';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
    Card,
    CardContent,
    CardDescription,
    CardFooter,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import {
    ChartContainer,
    ChartTooltip,
    ChartTooltipContent,
    type ChartConfig,
} from '@/components/ui/chart';
import { Button } from '@/components/ui/button';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import AppLayout from '@/layouts/app-layout';
import adminReports from '@/routes/admin/reports';

type RangeOption = {
    value: string;
    label: string;
};

type SalesByLocationRow = {
    name: string;
    bookings: number;
    sales_cents: number;
};

type DailySalesRow = {
    date: string;
    label: string;
    sales_cents: number;
};

type EmployeeLeaderboardRow = {
    name: string;
    bookings: number;
    sales_cents: number;
};

type TopCustomerRow = {
    name: string;
    email: string;
    bookings: number;
    sales_cents: number;
};

type TransactionRow = {
    receipt: string;
    scheduled_at: string;
    location: string;
    technician: string;
    customer: string;
    customer_email: string;
    payment_status: string;
    service_status: string;
    total_cents: number;
    amount_paid_cents: number;
};

type Props = {
    activeRange: string;
    rangeOptions: RangeOption[];
    customRange: {
        from: string | null;
        to: string | null;
    };
    report: {
        range: {
            start: string;
            end: string;
        };
        global: {
            total_sales_cents: number;
            total_bookings: number;
            average_ticket_cents: number;
            sales_by_location: SalesByLocationRow[];
            daily_sales_series: DailySalesRow[];
        };
        team: {
            employee_leaderboard: EmployeeLeaderboardRow[];
        };
        customer: {
            top_customers: TopCustomerRow[];
            repeat_rate_percent: number;
            transactions: TransactionRow[];
        };
    };
};

type ReportTab = 'global' | 'team' | 'customer';

const salesChartConfig = {
    sales_cents: {
        label: 'Sales',
        color: 'var(--chart-1)',
    },
} satisfies ChartConfig;

const repeatRateChartConfig = {
    customers: {
        label: 'Customers',
    },
    repeat: {
        label: 'Repeat',
        color: 'var(--chart-2)',
    },
    one_time: {
        label: 'One-time',
        color: 'var(--chart-5)',
    },
} satisfies ChartConfig;

function formatMoney(cents: number): string {
    return new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
    }).format(cents / 100);
}

function buildExportUrl(
    format: 'excel' | 'csv',
    range: string,
    customRange: { from: string | null; to: string | null },
    table = '',
): string {
    const query: Record<string, string> = {
        range,
        ...(table !== '' ? { table } : {}),
    };

    if (range === 'custom' && customRange.from && customRange.to) {
        query.start_date = customRange.from;
        query.end_date = customRange.to;
    }

    return adminReports.export.url(
        { format },
        {
            query,
        },
    );
}

function TableExportButton({
    onClick,
}: {
    onClick: () => void;
}) {
    return (
        <DropdownMenu>
            <DropdownMenuTrigger asChild>
                <Button size="icon" variant="ghost" className="size-8">
                    <MoreHorizontal className="size-4" />
                    <span className="sr-only">Export this table</span>
                </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
                <DropdownMenuItem onClick={onClick}>
                    Download this table only
                </DropdownMenuItem>
            </DropdownMenuContent>
        </DropdownMenu>
    );
}

export default function AdminReportsIndex({ activeRange, rangeOptions, customRange, report }: Props) {
    const [activeTab, setActiveTab] = useState<ReportTab>('global');
    const salesSeries = report.global.daily_sales_series;
    const firstSales = salesSeries[0]?.sales_cents ?? 0;
    const lastSales = salesSeries[salesSeries.length - 1]?.sales_cents ?? 0;
    const salesTrendPercent = firstSales > 0
        ? Math.round((((lastSales - firstSales) / firstSales) * 100) * 10) / 10
        : null;
    const rangeLabel = useMemo(
        () => rangeOptions.find((option) => option.value === activeRange)?.label ?? 'Last 30 Days',
        [activeRange, rangeOptions],
    );
    const repeatRateChartData = useMemo(
        () => [
            {
                segment: 'repeat',
                customers: report.customer.repeat_rate_percent,
                fill: 'var(--color-repeat)',
            },
            {
                segment: 'one_time',
                customers: Math.max(0, 100 - report.customer.repeat_rate_percent),
                fill: 'var(--color-one_time)',
            },
        ],
        [report.customer.repeat_rate_percent],
    );
    const transactionColumns = useMemo<ColumnDef<TransactionRow>[]>(
        () => [
            {
                accessorKey: 'receipt',
                header: 'Receipt',
                meta: { label: 'Receipt' },
            },
            {
                accessorKey: 'scheduled_at',
                header: 'Date',
                meta: { label: 'Date' },
            },
            {
                accessorKey: 'location',
                header: 'Location',
                meta: { label: 'Location' },
            },
            {
                accessorKey: 'customer',
                header: 'Customer',
                meta: { label: 'Customer' },
            },
            {
                accessorKey: 'technician',
                header: 'Technician',
                meta: { label: 'Technician' },
            },
            {
                accessorKey: 'payment_status',
                header: 'Payment',
                meta: { label: 'Payment' },
            },
            {
                accessorKey: 'service_status',
                header: 'Service',
                meta: { label: 'Service' },
            },
            {
                accessorKey: 'total_cents',
                meta: {
                    label: 'Total',
                    headerClassName: 'justify-end',
                },
                cell: ({ row }) => (
                    <div className="text-right">{formatMoney(row.original.total_cents)}</div>
                ),
            },
            {
                accessorKey: 'amount_paid_cents',
                meta: {
                    label: 'Paid',
                    headerClassName: 'justify-end',
                },
                cell: ({ row }) => (
                    <div className="text-right">{formatMoney(row.original.amount_paid_cents)}</div>
                ),
            },
        ],
        [],
    );
    const salesByLocationColumns = useMemo<ColumnDef<SalesByLocationRow>[]>(
        () => [
            {
                accessorKey: 'name',
                header: 'Location',
                meta: { label: 'Location' },
            },
            {
                accessorKey: 'bookings',
                header: 'Bookings',
                meta: { label: 'Bookings' },
            },
            {
                accessorKey: 'sales_cents',
                meta: {
                    label: 'Sales',
                    headerClassName: 'justify-end',
                },
                cell: ({ row }) => (
                    <div className="text-right">{formatMoney(row.original.sales_cents)}</div>
                ),
            },
        ],
        [],
    );
    const employeeLeaderboardColumns = useMemo<ColumnDef<EmployeeLeaderboardRow>[]>(
        () => [
            {
                accessorKey: 'name',
                header: 'Employee',
                meta: { label: 'Employee' },
            },
            {
                accessorKey: 'bookings',
                header: 'Bookings',
                meta: { label: 'Bookings' },
            },
            {
                accessorKey: 'sales_cents',
                meta: {
                    label: 'Sales',
                    headerClassName: 'justify-end',
                },
                cell: ({ row }) => (
                    <div className="text-right">{formatMoney(row.original.sales_cents)}</div>
                ),
            },
        ],
        [],
    );
    const topCustomerColumns = useMemo<ColumnDef<TopCustomerRow>[]>(
        () => [
            {
                accessorKey: 'name',
                header: 'Customer',
                meta: { label: 'Customer' },
                cell: ({ row }) => (
                    <div className="flex flex-col">
                        <span>{row.original.name}</span>
                        <span className="text-xs text-muted-foreground">{row.original.email}</span>
                    </div>
                ),
            },
            {
                accessorKey: 'bookings',
                header: 'Bookings',
                meta: { label: 'Bookings' },
            },
            {
                accessorKey: 'sales_cents',
                meta: {
                    label: 'Sales',
                    headerClassName: 'justify-end',
                },
                cell: ({ row }) => (
                    <div className="text-right">{formatMoney(row.original.sales_cents)}</div>
                ),
            },
        ],
        [],
    );

    const handleRangeChange = (nextRange: string) => {
        const query: Record<string, string> = { range: nextRange };

        if (nextRange === 'custom' && customRange.from && customRange.to) {
            query.start_date = customRange.from;
            query.end_date = customRange.to;
        }

        router.get(
            adminReports.index.url({ query }),
            {},
            {
                preserveState: true,
                preserveScroll: true,
            },
        );
    };

    const handleCustomRangeApply = (range: DateRange) => {
        if (!range.from || !range.to) {
            return;
        }

        router.get(
            adminReports.index.url({
                query: {
                    range: 'custom',
                    start_date: range.from.toISOString().slice(0, 10),
                    end_date: range.to.toISOString().slice(0, 10),
                },
            }),
            {},
            {
                preserveState: true,
                preserveScroll: true,
            },
        );
    };

    const downloadExcel = (table = '') => {
        window.location.href = buildExportUrl('excel', activeRange, customRange, table);
    };

    const downloadRawCsv = (table = '') => {
        window.location.href = buildExportUrl('csv', activeRange, customRange, table);
    };

    const downloadPdfSummary = () => {
        const summaryNode = document.getElementById('reports-summary');
        if (!summaryNode) {
            return;
        }

        const popup = window.open('', '_blank', 'noopener,noreferrer,width=1200,height=900');
        if (!popup) {
            return;
        }

        popup.document.write(`
            <html>
                <head>
                    <title>Reports Summary</title>
                    ${document.head.innerHTML}
                    <style>
                        body { margin: 24px; font-family: Inter, sans-serif; }
                    </style>
                </head>
                <body>
                    ${summaryNode.innerHTML}
                </body>
            </html>
        `);
        popup.document.close();
        popup.focus();
        popup.print();
    };

    return (
        <>
            <Head title="Admin reports" />
            <div className="flex flex-col gap-6">
                <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
                    <div>
                        <h1 className="text-2xl font-semibold tracking-tight">Reports</h1>
                        <p className="text-sm text-muted-foreground">
                            Track sales by location, team performance, and customer activity.
                        </p>
                    </div>
                    <ReportsActionBar
                        activeRange={activeRange}
                        rangeOptions={rangeOptions}
                        onRangeChange={handleRangeChange}
                        customRange={{
                            from: customRange.from ? new Date(customRange.from) : undefined,
                            to: customRange.to ? new Date(customRange.to) : undefined,
                        }}
                        onCustomRangeApply={handleCustomRangeApply}
                        onDownloadPdfSummary={downloadPdfSummary}
                        onDownloadExcel={() => downloadExcel()}
                        onExportRawCsv={() => downloadRawCsv()}
                    />
                </div>

                <Tabs
                    value={activeTab}
                    onValueChange={(value) => setActiveTab(value as ReportTab)}
                >
                    <TabsList>
                        <TabsTrigger value="global">Global View</TabsTrigger>
                        <TabsTrigger value="team">Team View</TabsTrigger>
                        <TabsTrigger value="customer">Customer View</TabsTrigger>
                    </TabsList>
                </Tabs>

                <div id="reports-summary" className="space-y-6">
                    {activeTab === 'global' ? (
                        <>
                            <div className="grid gap-4 md:grid-cols-3">
                                <Card>
                                    <CardHeader>
                                        <CardDescription>{rangeLabel}</CardDescription>
                                        <CardTitle>{formatMoney(report.global.total_sales_cents)}</CardTitle>
                                    </CardHeader>
                                    <CardContent className="text-xs text-muted-foreground">
                                        Total sales in selected period
                                    </CardContent>
                                </Card>
                                <Card>
                                    <CardHeader>
                                        <CardDescription>{rangeLabel}</CardDescription>
                                        <CardTitle>{report.global.total_bookings}</CardTitle>
                                    </CardHeader>
                                    <CardContent className="text-xs text-muted-foreground">
                                        Total bookings in selected period
                                    </CardContent>
                                </Card>
                                <Card>
                                    <CardHeader>
                                        <CardDescription>{rangeLabel}</CardDescription>
                                        <CardTitle>{formatMoney(report.global.average_ticket_cents)}</CardTitle>
                                    </CardHeader>
                                    <CardContent className="text-xs text-muted-foreground">
                                        Average ticket size
                                    </CardContent>
                                </Card>
                            </div>

                            <Card>
                                <CardHeader>
                                    <CardTitle>Daily sales trend</CardTitle>
                                    <CardDescription>
                                        {report.range.start} to {report.range.end}
                                    </CardDescription>
                                </CardHeader>
                                <CardContent>
                                    <ChartErrorBoundary>
                                    <ChartContainer config={salesChartConfig} className="aspect-auto h-[260px] w-full">
                                        <AreaChart
                                            accessibilityLayer
                                            data={report.global.daily_sales_series}
                                            margin={{
                                                left: 12,
                                                right: 12,
                                            }}
                                        >
                                            <CartesianGrid vertical={false} />
                                            <XAxis
                                                dataKey="label"
                                                tickLine={false}
                                                axisLine={false}
                                                tickMargin={8}
                                            />
                                            <ChartTooltip
                                                cursor={false}
                                                content={
                                                    <ChartTooltipContent
                                                        formatter={(value) => formatMoney(Number(value))}
                                                    />
                                                }
                                            />
                                            <defs>
                                                <linearGradient id="fillSalesCents" x1="0" y1="0" x2="0" y2="1">
                                                    <stop
                                                        offset="5%"
                                                        stopColor="var(--color-sales_cents)"
                                                        stopOpacity={0.8}
                                                    />
                                                    <stop
                                                        offset="95%"
                                                        stopColor="var(--color-sales_cents)"
                                                        stopOpacity={0.1}
                                                    />
                                                </linearGradient>
                                            </defs>
                                            <Area
                                                dataKey="sales_cents"
                                                type="natural"
                                                fill="url(#fillSalesCents)"
                                                fillOpacity={0.4}
                                                stroke="var(--color-sales_cents)"
                                                strokeWidth={2}
                                            />
                                        </AreaChart>
                                    </ChartContainer>
                                    </ChartErrorBoundary>
                                </CardContent>
                                <CardFooter className="border-t px-6 py-4">
                                    <div className="flex w-full items-start gap-2 text-sm">
                                        <div className="grid gap-1">
                                            <div className="flex items-center gap-2 leading-none font-medium">
                                                {salesTrendPercent === null ? (
                                                    <span className="text-muted-foreground font-normal">
                                                        No comparison data for trend
                                                    </span>
                                                ) : (
                                                    <>
                                                        {salesTrendPercent >= 0 ? 'Trending up' : 'Trending down'} by{' '}
                                                        {Math.abs(salesTrendPercent)}% in selected range
                                                        <TrendingUp
                                                            className={salesTrendPercent < 0 ? 'size-4 rotate-180' : 'size-4'}
                                                        />
                                                    </>
                                                )}
                                            </div>
                                            <div className="leading-none text-muted-foreground">
                                                {report.range.start} to {report.range.end}
                                            </div>
                                        </div>
                                    </div>
                                </CardFooter>
                            </Card>

                            <Card>
                                <CardHeader className="flex flex-row items-center justify-between">
                                    <div>
                                        <CardTitle>Sales by location</CardTitle>
                                        <CardDescription>Where revenue is coming from</CardDescription>
                                    </div>
                                    <TableExportButton onClick={() => downloadExcel('location_sales')} />
                                </CardHeader>
                                <CardContent>
                                    <DataTable
                                        columns={salesByLocationColumns}
                                        data={report.global.sales_by_location}
                                        searchPlaceholder="Search locations..."
                                    />
                                </CardContent>
                            </Card>
                        </>
                    ) : null}

                    {activeTab === 'team' ? (
                        <Card>
                            <CardHeader className="flex flex-row items-center justify-between">
                                <div>
                                    <CardTitle className="flex items-center gap-2">
                                        <Users className="size-4" />
                                        Employee leaderboard
                                    </CardTitle>
                                    <CardDescription>Sales and booking output per team member</CardDescription>
                                </div>
                                <TableExportButton onClick={() => downloadExcel('team_leaderboard')} />
                            </CardHeader>
                            <CardContent>
                                <DataTable
                                    columns={employeeLeaderboardColumns}
                                    data={report.team.employee_leaderboard}
                                    searchPlaceholder="Search employees..."
                                />
                            </CardContent>
                        </Card>
                    ) : null}

                    {activeTab === 'customer' ? (
                        <>
                            <div className="grid gap-4 md:grid-cols-2">
                                <Card>
                                    <CardHeader className="items-center pb-0">
                                        <CardTitle className="flex items-center gap-2">
                                            <BarChart3 className="size-4" />
                                            Repeat customer rate
                                        </CardTitle>
                                        <CardDescription>{rangeLabel}</CardDescription>
                                    </CardHeader>
                                    <CardContent className="pb-0">
                                        <ChartErrorBoundary>
                                        <ChartContainer
                                            config={repeatRateChartConfig}
                                            className="mx-auto aspect-square max-h-[240px]"
                                        >
                                            <PieChart>
                                                <ChartTooltip
                                                    cursor={false}
                                                    content={
                                                        <ChartTooltipContent
                                                            hideLabel
                                                            formatter={(value, _name, item) => {
                                                                const rawSegment = item.payload?.segment;
                                                                const label = rawSegment === 'repeat' ? 'Repeat' : 'One-time';

                                                                return `${label}: ${Number(value).toFixed(0)}%`;
                                                            }}
                                                        />
                                                    }
                                                />
                                                <Pie
                                                    data={repeatRateChartData}
                                                    dataKey="customers"
                                                    nameKey="segment"
                                                    innerRadius={58}
                                                    strokeWidth={5}
                                                >
                                                    <Label
                                                        content={({ viewBox }) => {
                                                            if (!viewBox || !('cx' in viewBox) || !('cy' in viewBox)) {
                                                                return null;
                                                            }

                                                            return (
                                                                <text
                                                                    x={viewBox.cx}
                                                                    y={viewBox.cy}
                                                                    textAnchor="middle"
                                                                    dominantBaseline="middle"
                                                                >
                                                                    <tspan
                                                                        x={viewBox.cx}
                                                                        y={viewBox.cy}
                                                                        className="fill-foreground text-3xl font-bold"
                                                                    >
                                                                        {report.customer.repeat_rate_percent}%
                                                                    </tspan>
                                                                    <tspan
                                                                        x={viewBox.cx}
                                                                        y={(viewBox.cy || 0) + 22}
                                                                        className="fill-muted-foreground text-xs"
                                                                    >
                                                                        Repeat
                                                                    </tspan>
                                                                </text>
                                                            );
                                                        }}
                                                    />
                                                </Pie>
                                            </PieChart>
                                        </ChartContainer>
                                        </ChartErrorBoundary>
                                    </CardContent>
                                    <CardFooter className="flex-col gap-2 text-sm">
                                        <div className="flex items-center gap-2 leading-none font-medium">
                                            Customer retention snapshot
                                        </div>
                                        <div className="leading-none text-muted-foreground">
                                            Repeat vs one-time customers for selected period
                                        </div>
                                    </CardFooter>
                                </Card>
                                <Card>
                                    <CardHeader className="flex flex-row items-center justify-between">
                                        <div>
                                            <CardTitle>Top customers</CardTitle>
                                            <CardDescription>Most valuable customers in selected range</CardDescription>
                                        </div>
                                        <TableExportButton onClick={() => downloadExcel('top_customers')} />
                                    </CardHeader>
                                    <CardContent>
                                        <DataTable
                                            columns={topCustomerColumns}
                                            data={report.customer.top_customers}
                                            searchPlaceholder="Search customers..."
                                        />
                                    </CardContent>
                                </Card>
                            </div>

                            <Card>
                                <CardHeader>
                                    <CardTitle>Transaction list</CardTitle>
                                    <CardDescription>
                                        Raw receipts for accounting export
                                    </CardDescription>
                                </CardHeader>
                                <CardContent>
                                    <DataTable
                                        columns={transactionColumns}
                                        data={report.customer.transactions}
                                        searchPlaceholder="Search transactions..."
                                    />
                                </CardContent>
                            </Card>
                        </>
                    ) : null}
                </div>
            </div>
        </>
    );
}

AdminReportsIndex.layout = (page: React.ReactNode) => (
    <AppLayout
        breadcrumbs={[
            {
                title: 'Admin reports',
                href: '/admin/reports',
            },
        ]}
    >
        {page}
    </AppLayout>
);
