import { Head, Link, router } from '@inertiajs/react';
import AppLayout from '@/layouts/app-layout';
import { ChartErrorBoundary } from '@/components/chart-error-boundary';
import { format } from 'date-fns';
import {
    ArrowDownRight,
    ArrowUpRight,
    CalendarCheck,
    CircleDollarSign,
    ClipboardList,
    Minus,
    Percent,
    ReceiptText,
    Sparkles,
    Users,
    Wallet,
} from 'lucide-react';
import type { LucideIcon } from 'lucide-react';
import type { DateRange } from 'react-day-picker';
import type { DashboardPerformance } from '@/components/dashboard/dashboard-performance-chart';
import { DashboardPerformanceChart } from '@/components/dashboard/dashboard-performance-chart';
import { EmptyState } from '@/components/layout/empty-state';
import { PageHeader } from '@/components/layout/page-header';
import { SectionCard } from '@/components/layout/section-card';
import { ReportsActionBar } from '@/components/reporting/reports-action-bar';
import { StatusBadge } from '@/components/status-badge';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Card,
    CardContent,
    CardDescription,
    CardHeader,
    CardTitle,
} from '@/components/ui/card';
import {
    Item,
    ItemContent,
    ItemDescription,
    ItemGroup,
    ItemMedia,
    ItemSeparator,
    ItemTitle,
} from '@/components/ui/item';
import { dashboard } from '@/routes';
import adminBookings from '@/routes/admin/bookings';
import adminReports from '@/routes/admin/reports';
import { useBookingDateTimeFormatters } from '@/hooks/use-booking-timezone';

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

type DashboardStats = {
    revenue: number;
    revenue_change: number | null;
    bookings: number;
    bookings_change: number | null;
    completion_rate: number;
    outstanding_balance: number;
    new_customers: number;
    repeat_customers: number;
    open_jobs: number;
    average_ticket: number;
};

type RecentActivityItem = {
    id: number;
    uuid: string;
    customer_name: string;
    package_name: string;
    scheduled_at: string | null;
    updated_at: string | null;
    payment_status: string;
    service_status: string;
    total: number;
    amount_paid: number;
};

type Props = {
    activeRange: string;
    rangeOptions: RangeOption[];
    customRange: {
        from: string | null;
        to: string | null;
    };
    stats: DashboardStats;
    performance: DashboardPerformance;
    recentActivity: RecentActivityItem[];
};

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

function formatPercent(value: number): string {
    return `${value}%`;
}

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

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

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

function TrendBadge({
    change,
    label,
}: {
    change: number | null;
    label: string;
}) {
    if (change === null) {
        return (
            <Badge variant="outline" className="gap-1 font-normal normal-case">
                <Minus className="size-3" />
                {label}
            </Badge>
        );
    }

    const isPositive = change >= 0;

    return (
        <Badge
            variant={isPositive ? 'green' : 'red'}
            className="gap-1 font-normal normal-case"
        >
            {isPositive ? (
                <ArrowUpRight className="size-3" />
            ) : (
                <ArrowDownRight className="size-3" />
            )}
            {Math.abs(change)}% {label}
        </Badge>
    );
}

type StatMetricCardProps = {
    label: string;
    value: string;
    hint: string;
    icon: LucideIcon;
    trend?: {
        change: number | null;
        label: string;
    };
};

function StatMetricCard({
    label,
    value,
    hint,
    icon: Icon,
    trend,
}: StatMetricCardProps) {
    return (
        <Card size="sm" className="relative">
            <CardHeader className="space-y-3">
                <div className="flex items-start justify-between gap-3">
                    <CardDescription className="text-xs font-medium tracking-wide uppercase">
                        {label}
                    </CardDescription>
                    <div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-primary/10 text-primary">
                        <Icon className="size-4" />
                    </div>
                </div>
                <CardTitle className="text-3xl font-semibold tracking-tight tabular-nums">
                    {value}
                </CardTitle>
            </CardHeader>
            <CardContent className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                <span className="text-xs text-muted-foreground">{hint}</span>
                {trend ? (
                    <TrendBadge change={trend.change} label={trend.label} />
                ) : null}
            </CardContent>
        </Card>
    );
}

export default function Dashboard({
    activeRange,
    rangeOptions,
    customRange,
    stats,
    performance,
    recentActivity,
}: Props) {
    const { formatDateTime } = useBookingDateTimeFormatters();
    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(
            dashboard.url({ query }),
            {},
            {
                preserveState: true,
                preserveScroll: true,
            },
        );
    };

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

        router.get(
            dashboard.url({
                query: {
                    range: 'custom',
                    start_date: format(range.from, 'yyyy-MM-dd'),
                    end_date: format(range.to, 'yyyy-MM-dd'),
                },
            }),
            {},
            {
                preserveState: true,
                preserveScroll: true,
            },
        );
    };

    const downloadPdfSummary = () => {
        const summaryNode = document.getElementById('dashboard-summary');

        if (!summaryNode) {
            return;
        }

        const popup = window.open(
            '',
            '_blank',
            'noopener,noreferrer,width=1200,height=900',
        );

        if (!popup) {
            return;
        }

        popup.document.write(`
            <html>
                <head>
                    <title>Dashboard 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();
    };

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

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

    return (
        <>
            <Head title="Dashboard" />

            <div className="flex flex-col gap-6">
                <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
                    <PageHeader
                        title="Dashboard"
                        description="Snapshot of bookings, revenue, and activity for your wash business."
                    />
                    <ReportsActionBar
                        activeRange={activeRange}
                        rangeOptions={rangeOptions}
                        onRangeChange={handleRangeChange}
                        customRange={{
                            from: customRange.from
                                ? new Date(customRange.from + 'T00:00:00')
                                : undefined,
                            to: customRange.to
                                ? new Date(customRange.to + 'T00:00:00')
                                : undefined,
                        }}
                        onCustomRangeApply={handleCustomRangeApply}
                        onDownloadPdfSummary={downloadPdfSummary}
                        onDownloadExcel={downloadExcel}
                        onExportRawCsv={downloadRawCsv}
                    />
                </div>

                <div id="dashboard-summary" className="space-y-6">
                    <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
                        <StatMetricCard
                            label="Revenue"
                            value={formatMoney(stats.revenue)}
                            hint="Paid bookings in range"
                            icon={CircleDollarSign}
                            trend={{
                                change: stats.revenue_change,
                                label: 'vs prior range',
                            }}
                        />
                        <StatMetricCard
                            label="Bookings"
                            value={String(stats.bookings)}
                            hint="Scheduled washes in range"
                            icon={CalendarCheck}
                            trend={{
                                change: stats.bookings_change,
                                label: 'vs prior range',
                            }}
                        />
                        <StatMetricCard
                            label="Completion rate"
                            value={formatPercent(stats.completion_rate)}
                            hint="Completed vs scheduled"
                            icon={Percent}
                        />
                        <StatMetricCard
                            label="Outstanding balance"
                            value={formatMoney(stats.outstanding_balance)}
                            hint="Uncollected booking totals"
                            icon={Wallet}
                        />
                        <StatMetricCard
                            label="Open jobs"
                            value={String(stats.open_jobs)}
                            hint="Scheduled through in progress"
                            icon={ClipboardList}
                        />
                        <StatMetricCard
                            label="New customers"
                            value={String(stats.new_customers)}
                            hint="Customer accounts created"
                            icon={Users}
                        />
                        <StatMetricCard
                            label="Repeat customers"
                            value={String(stats.repeat_customers)}
                            hint="Customers with 2+ bookings"
                            icon={Sparkles}
                        />
                        <StatMetricCard
                            label="Average ticket"
                            value={formatMoney(stats.average_ticket)}
                            hint="Revenue per paid booking"
                            icon={ReceiptText}
                        />
                    </div>

                    <ChartErrorBoundary>
                        <DashboardPerformanceChart performance={performance} />
                    </ChartErrorBoundary>
                </div>

                <SectionCard
                    title="Recent activity"
                    description="Latest booking updates across your operation"
                    actions={
                        recentActivity.length > 0 ? (
                            <Button variant="ghost" size="sm" asChild>
                                <Link href={adminBookings.index.url()}>
                                    See all
                                </Link>
                            </Button>
                        ) : null
                    }
                    contentClassName="p-0"
                >
                    {recentActivity.length === 0 ? (
                        <div className="px-6 pb-6">
                            <EmptyState
                                title="No activity yet"
                                description="Bookings and status changes will show up here as customers schedule washes."
                            />
                        </div>
                    ) : (
                        <ItemGroup className="px-2 pb-2">
                            {recentActivity.map((activity, index) => (
                                <div key={activity.id}>
                                    <Item size="sm" className="rounded-lg">
                                        <ItemMedia variant="icon">
                                            <CalendarCheck className="size-4" />
                                        </ItemMedia>
                                        <ItemContent>
                                            <ItemTitle>
                                                {activity.customer_name}
                                                <StatusBadge
                                                    status={
                                                        activity.service_status
                                                    }
                                                    className="ml-1"
                                                />
                                            </ItemTitle>
                                            <ItemDescription>
                                                {activity.package_name} ·{' '}
                                                {activity.scheduled_at
                                                    ? formatDateTime(activity.scheduled_at)
                                                    : '—'}
                                            </ItemDescription>
                                        </ItemContent>
                                        <div className="flex flex-col items-end gap-1 text-right">
                                            <span className="text-sm font-medium tabular-nums">
                                                {formatMoney(activity.total)}
                                            </span>
                                            <StatusBadge
                                                status={activity.payment_status}
                                            />
                                        </div>
                                    </Item>
                                    {index < recentActivity.length - 1 ? (
                                        <ItemSeparator className="mx-4" />
                                    ) : null}
                                </div>
                            ))}
                        </ItemGroup>
                    )}
                </SectionCard>
            </div>
        </>
    );
}

Dashboard.layout = (page: React.ReactNode) => (
    <AppLayout
        breadcrumbs={[
            {
                title: 'Dashboard',
                href: dashboard.url(),
            },
        ]}
    >
        {page}
    </AppLayout>
);
