import { StatCard } from '@/components/card/stat-card';
import { TodayAttendanceAlert } from '@/components/card/today-attendance-alert';
import { CameraCapture } from '@/components/inputs';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, type ChartConfig } from '@/components/ui/chart';
import { useCan } from '@/hooks/use-can';
import { generateRandomColors } from '@/lib/utils';
import { formatRupiah } from '@/lib/rupiah';
import { store, update } from '@/routes/admin/hr/attendances';
import { Head, router, usePage } from '@inertiajs/react';
import {
    Clock,
    Moon,
    Sun,
    Sunrise,
    TrendingDown,
    TrendingUp,
    UserCheck,
} from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
import { Pie, PieChart } from 'recharts';
import { toast } from 'sonner';

type TodayAttendance = {
    id: number;
    attendance_date: string;
    check_in_at: string | null;
    check_out_at: string | null;
    check_in_photo: string | null;
    check_out_photo: string | null;
    check_in_latitude: number;
    check_in_longitude: number;
    check_out_latitude: number | null;
    check_out_longitude: number | null;
    work_duration_minutes: number | null;
} | null;

type DashboardProps = {
    attendance: {
        total_employees: number;
        percentage: number;
        present: number;
        absent: number;
        on_leave: number;
    };
    revenueSummary: {
        total_revenue: number;
        total_discount: number;
        total_cogs: number;
        total_deduction: number;
        gross: number;
        net: number;
        payroll_total: number;
        expense_total: number;
        total_orders: number;
    };
    expenseSummary: {
        total: number;
        expense_total: number;
        advance_total: number;
    };
    orderStats: {
        by_channel: Array<{
            channel: string;
            label: string;
            count: number;
            total: number;
        }>;
        by_payment_type: Array<{
            payment_type: string;
            label: string;
            count: number;
            total: number;
        }>;
        by_marketing: Array<{
            name: string;
            count: number;
            total: number;
        }>;
        by_status: Array<{
            status: string;
            label: string;
            count: number;
        }>;
    };
    todayAttendance: TodayAttendance;
    isOnLeave: boolean;
    canCheckIn: boolean;
};

export default function Dashboard({
    attendance: attendanceStats,
    revenueSummary,
    expenseSummary,
    orderStats,
    todayAttendance,
    isOnLeave,
    canCheckIn,
}: DashboardProps) {
    const { can, hasRole } = useCan();
    const { auth } = usePage().props as { auth: { user?: { username?: string } } };
    const [currentTime, setCurrentTime] = useState(new Date());
    const [showCamera, setShowCamera] = useState(false);
    const [actionType, setActionType] = useState<'check-in' | 'check-out'>('check-in');
    const [locationLoading, setLocationLoading] = useState(false);

    useEffect(() => {
        const timer = setInterval(() => setCurrentTime(new Date()), 1000);

        return () => clearInterval(timer);
    }, []);

    const greeting = useMemo(() => {
        const hour = currentTime.getHours();

        if (hour >= 4 && hour < 11) {
            return { text: 'Selamat Pagi', icon: Sunrise };
        }

        if (hour >= 11 && hour < 15) {
            return { text: 'Selamat Siang', icon: Sun };
        }

        if (hour >= 15 && hour < 18) {
            return { text: 'Selamat Sore', icon: Sun };
        }

        return { text: 'Selamat Malam', icon: Moon };
    }, [currentTime]);

    const timeStr = currentTime.toLocaleTimeString('id-ID', {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false,
    });

    const dateStr = currentTime.toLocaleDateString('id-ID', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric',
    });

    const visibleStatsCount = useMemo(() => {
        let count = 0;

        if (can('dashboard.attendance')) {
            count++;
        }

        if (can('dashboard.revenue')) {
            count++;
        }

        if (can('dashboard.expense')) {
            count++;
        }

        return count;
    }, [can]);

    const visibleChartsCount = useMemo(() => {
        let count = 0;

        if (can('dashboard.orders_channel')) {
            count++;
        }

        if (can('dashboard.orders_payment')) {
            count++;
        }

        if (can('dashboard.orders_marketing')) {
            count++;
        }

        if (can('dashboard.orders_status')) {
            count++;
        }

        return count;
    }, [can]);

    const chartsGridClass = useMemo(() => {
        if (visibleChartsCount === 1) {
            return 'grid gap-4 grid-cols-1 md:max-w-xl';
        }

        if (visibleChartsCount === 2) {
            return 'grid gap-4 grid-cols-1 md:grid-cols-2';
        }

        if (visibleChartsCount === 3) {
            return 'grid gap-4 grid-cols-1 md:grid-cols-3';
        }

        return 'grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-4';
    }, [visibleChartsCount]);

    const GreetingIcon = greeting.icon;

    const handleCheckIn = () => {
        setActionType('check-in');
        setShowCamera(true);
    };

    const handleCheckOut = () => {
        setActionType('check-out');
        setShowCamera(true);
    };

    const handleCameraCapture = (dataUrl: string) => {
        setShowCamera(false);
        setLocationLoading(true);

        if (!navigator.geolocation) {
            setLocationLoading(false);
            toast.error('Geolocation tidak didukung di browser ini.');

            return;
        }

        navigator.geolocation.getCurrentPosition(
            (position) => {
                setLocationLoading(false);
                const formData = new FormData();
                formData.append('photo', dataUrl);
                formData.append('latitude', position.coords.latitude.toString());
                formData.append('longitude', position.coords.longitude.toString());

                if (actionType === 'check-in') {
                    router.post(store(), formData, { preserveScroll: true });
                } else if (actionType === 'check-out' && todayAttendance) {
                    router.put(update(todayAttendance.id), formData, {
                        preserveScroll: true,
                    });
                }
            },
            () => {
                setLocationLoading(false);
                toast.error('Gagal mendapatkan lokasi. Pastikan izin lokasi diberikan.');
            },
            { enableHighAccuracy: true, timeout: 10000 },
        );
    };

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

            <div className="flex h-full flex-1 flex-col gap-6 p-4 md:p-6">
                <Card className="relative overflow-visible">
                    <div className="absolute inset-0 bg-linear-to-br from-primary/5 to-background" />
                    <CardHeader className="relative">
                        <div className="flex items-center gap-3">
                            <div className="flex size-12 items-center justify-center rounded-full bg-primary/10">
                                <GreetingIcon className="size-6 text-primary" />
                            </div>
                            <div>
                                <CardTitle className="text-2xl font-bold">
                                    {greeting.text}, {auth.user?.username}!
                                </CardTitle>
                                <CardDescription className="mt-1">
                                    Selamat datang di dasbor aplikasi.
                                </CardDescription>
                            </div>
                        </div>
                    </CardHeader>
                    <CardContent className="relative">
                        <div className="flex items-center gap-2 text-sm text-muted-foreground">
                            <span>{dateStr}</span>
                            <span>-</span>
                            <span className="flex items-center gap-1">
                                <Clock className="size-3.5" />
                                {timeStr}
                            </span>
                        </div>
                    </CardContent>
                </Card>

                {can('attendances.create') && !hasRole('developer') && !hasRole('owner') && (
                    <>
                        <TodayAttendanceAlert
                            todayAttendance={todayAttendance}
                            isOnLeave={isOnLeave}
                            canCheckIn={canCheckIn}
                            locationLoading={locationLoading}
                            onCheckIn={handleCheckIn}
                            onCheckOut={handleCheckOut}
                        />

                        {showCamera && (
                            <CameraCapture
                                onCapture={handleCameraCapture}
                                onClose={() => setShowCamera(false)}
                            />
                        )}
                    </>
                )}

                {visibleStatsCount > 0 && (
                    <div className="grid gap-4" style={{ gridTemplateColumns: `repeat(${visibleStatsCount}, minmax(0, 1fr))` }}>
                        {can('dashboard.attendance') && (
                            <StatCard
                                title="Kehadiran Hari Ini"
                                icon={UserCheck}
                                mainLabel="Total Karyawan"
                                mainValue={attendanceStats.total_employees}
                                subLabel={`${attendanceStats.percentage}% hadir`}
                                items={[
                                    { label: 'Hadir', value: attendanceStats.present },
                                    { label: 'Tidak Hadir', value: attendanceStats.absent },
                                    { label: 'Cuti', value: attendanceStats.on_leave },
                                ]}
                                cols={3}
                            />
                        )}

                        {can('dashboard.revenue') && (
                            <StatCard
                                title="Pendapatan Hari Ini"
                                icon={TrendingUp}
                                mainLabel="Total"
                                mainValue={`Rp${formatRupiah(revenueSummary.total_revenue)}`}
                                subLabel={`${revenueSummary.total_orders} transaksi selesai`}
                                items={[
                                    {
                                        label: 'Kotor',
                                        value: `Rp${formatRupiah(revenueSummary.gross)}`,
                                    },
                                    {
                                        label: 'Bersih',
                                        value: `Rp${formatRupiah(revenueSummary.net)}`,
                                    },
                                    {
                                        label: 'Gaji',
                                        value: `Rp${formatRupiah(revenueSummary.payroll_total)}`,
                                    },
                                    {
                                        label: 'Pengeluaran',
                                        value: `Rp${formatRupiah(revenueSummary.expense_total)}`,
                                    },
                                    {
                                        label: 'Potongan',
                                        value: `Rp${formatRupiah(revenueSummary.total_deduction)}`,
                                    },
                                    {
                                        label: 'Diskon',
                                        value: `Rp${formatRupiah(revenueSummary.total_discount)}`,
                                    },
                                    {
                                        label: 'HPP',
                                        value: `Rp${formatRupiah(revenueSummary.total_cogs)}`,
                                    },
                                ]}
                                cols={visibleStatsCount === 1 ? 4 : visibleStatsCount === 2 ? 3 : 2}
                            />
                        )}

                        {can('dashboard.expense') && (
                            <StatCard
                                title="Pengeluaran Hari Ini"
                                icon={TrendingDown}
                                mainLabel="Total"
                                mainValue={`Rp${formatRupiah(expenseSummary.total)}`}
                                items={[
                                    {
                                        label: 'Pengeluaran',
                                        value: `Rp${formatRupiah(expenseSummary.expense_total)}`,
                                    },
                                    {
                                        label: 'Kasbon',
                                        value: `Rp${formatRupiah(expenseSummary.advance_total)}`,
                                    },
                                ]}
                                cols={visibleStatsCount <= 2 ? 2 : 2}
                            />
                        )}
                    </div>
                )}

                {visibleChartsCount > 0 && (
                    <div className={chartsGridClass}>
                        {can('dashboard.orders_channel') && (
                            <DashboardPieChart
                                title="Pesanan per Channel Hari Ini"
                                data={orderStats.by_channel.map((item) => ({
                                    name: item.label,
                                    count: item.count,
                                }))}
                                dataKey="count"
                                nameKey="name"
                            />
                        )}

                        {can('dashboard.orders_payment') && (
                            <DashboardPieChart
                                title="Pesanan per Pembayaran Hari Ini"
                                data={orderStats.by_payment_type.map((item) => ({
                                    name: item.label,
                                    count: item.count,
                                }))}
                                dataKey="count"
                                nameKey="name"
                            />
                        )}

                        {can('dashboard.orders_marketing') && (
                            <DashboardPieChart
                                title="Pesanan per Marketing Hari Ini"
                                data={orderStats.by_marketing.map((item) => ({
                                    name: item.name,
                                    count: item.count,
                                }))}
                                dataKey="count"
                                nameKey="name"
                            />
                        )}

                        {can('dashboard.orders_status') && (
                            <DashboardPieChart
                                title="Pesanan per Status Hari Ini"
                                data={orderStats.by_status.map((item) => ({
                                    name: item.label,
                                    count: item.count,
                                }))}
                                dataKey="count"
                                nameKey="name"
                            />
                        )}
                    </div>
                )}
            </div>
        </>
    );
}

type PieChartItem = {
    name: string;
    count: number;
};

type DashboardPieChartProps = {
    title: string;
    data: PieChartItem[];
    dataKey: string;
    nameKey: string;
};

function DashboardPieChart({ title, data, dataKey, nameKey }: DashboardPieChartProps) {
    const hasData = data.length > 0 && data.some((d) => d.count > 0);

    const pieColors = useMemo(() => generateRandomColors(5), []);

    const chartConfig = useMemo(() => {
        const config: ChartConfig = {};
        data.forEach((item, index) => {
            config[item.name] = {
                label: item.name,
                color: pieColors[index % pieColors.length],
            };
        });
        return config;
    }, [data, pieColors]);

    const chartData = useMemo(() => {
        return data.map((item) => ({
            ...item,
            fill: pieColors[data.indexOf(item) % pieColors.length],
        }));
    }, [data, pieColors]);

    return (
        <Card>
            <CardHeader className="items-center pb-0">
                <CardTitle className="text-base">{title}</CardTitle>
            </CardHeader>
            <CardContent className="flex-1 pb-0">
                {hasData ? (
                    <ChartContainer
                        config={chartConfig}
                        className="mx-auto aspect-square max-h-[250px]"
                    >
                        <PieChart>
                            <ChartTooltip
                                content={
                                    <ChartTooltipContent
                                        nameKey={nameKey}
                                        hideLabel
                                    />
                                }
                            />
                            <Pie
                                data={chartData}
                                dataKey={dataKey}
                                nameKey={nameKey}
                            />
                            <ChartLegend
                                content={<ChartLegendContent nameKey={nameKey} />}
                                className="-translate-y-2 flex-wrap gap-2 *:basis-1/4 *:justify-center"
                            />
                        </PieChart>
                    </ChartContainer>
                ) : (
                    <div className="flex h-[200px] items-center justify-center text-muted-foreground">
                        Belum ada data
                    </div>
                )}
            </CardContent>
        </Card>
    );
}
