import { Head, router } from '@inertiajs/react';
import { addMonths, format, subMonths } from 'date-fns';
import { id } from 'date-fns/locale';
import {
    CalendarCheck,
    CalendarDays,
    CheckCircle2,
    ChevronLeft,
    ChevronRight,
    Clock,
    LogIn,
    LogOut,
    UserX,
    Wallet,
} from 'lucide-react';
import { useMemo, useState } from 'react';
import { toast } from 'sonner';
import { CameraCapture } from '@/components/camera-capture';
import { LocationMap } from '@/components/location-map';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import {
    index as attendanceIndex,
    store,
    update,
} from '@/routes/admin/hr/attendances';

type Attendance = {
    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;
};

type MonthStats = {
    working_days: number;
    present: number;
    absent: number;
    leave: number;
};

type Props = {
    attendances: Attendance[];
    todayAttendance: Attendance | null;
    currentYear: number;
    currentMonth: number;
    monthStats: MonthStats;
    hrSettings: {
        scheduled_check_in_time: string;
        scheduled_check_out_time: string;
    };
};

const WEEKDAYS = ['Min', 'Sen', 'Sel', 'Rab', 'Kam', 'Jum', 'Sab'];

function getDaysInMonth(year: number, month: number): number {
    return new Date(year, month, 0).getDate();
}

function getFirstDayOfMonth(year: number, month: number): number {
    return new Date(year, month - 1, 1).getDay();
}

function isSameDay(d1: Date, d2: Date): boolean {
    return (
        d1.getDate() === d2.getDate() &&
        d1.getMonth() === d2.getMonth() &&
        d1.getFullYear() === d2.getFullYear()
    );
}

function checkIsToday(date: Date): boolean {
    const t = new Date();

    return (
        date.getDate() === t.getDate() &&
        date.getMonth() === t.getMonth() &&
        date.getFullYear() === t.getFullYear()
    );
}

function isWeekend(date: Date): boolean {
    const day = date.getDay();

    return day === 0 || day === 6;
}

function isLate(
    checkInAt: string | null,
    officeHour: number,
    officeMinute: number,
): boolean {
    if (!checkInAt) {
return false;
}

    const d = new Date(checkInAt);
    const h = d.getHours();
    const m = d.getMinutes();

    return h > officeHour || (h === officeHour && m > officeMinute);
}

function getLateMinutes(
    checkInAt: string | null,
    officeHour: number,
    officeMinute: number,
): number {
    if (!checkInAt || !isLate(checkInAt, officeHour, officeMinute)) {
return 0;
}

    const d = new Date(checkInAt);
    const officeStart = new Date(d);
    officeStart.setHours(officeHour, officeMinute, 0, 0);

    return Math.ceil((d.getTime() - officeStart.getTime()) / 60000);
}

function formatMinutes(minutes: number | null): string {
    if (!minutes) {
return '-';
}

    const hours = Math.floor(minutes / 60);
    const mins = Math.floor(minutes % 60);

    if (mins === 0) {
return `${hours} jam`;
}

    return `${hours} jam ${mins} menit`;
}

export default function AttendanceIndex({
    attendances,
    todayAttendance,
    currentYear,
    currentMonth,
    monthStats,
    hrSettings,
}: Props) {
    const [officeHour, officeMinute] = hrSettings.scheduled_check_in_time
        .split(':')
        .map(Number);
    const [viewDate, setViewDate] = useState(
        new Date(currentYear, currentMonth - 1),
    );
    const [selectedDate, setSelectedDate] = useState<Date>(new Date());
    const [showCamera, setShowCamera] = useState(false);
    const [actionType, setActionType] = useState<'check-in' | 'check-out'>(
        'check-in',
    );
    const [locationLoading, setLocationLoading] = useState(false);
    const [detailAttendance, setDetailAttendance] = useState<Attendance | null>(
        null,
    );

    const viewYear = viewDate.getFullYear();
    const viewMonth = viewDate.getMonth() + 1;

    const attendanceDates = useMemo(() => {
        const dates = new Map<string, Attendance>();
        attendances.forEach((att) => {
            dates.set(att.attendance_date, att);
        });

        return dates;
    }, [attendances]);

    const selectedAttendance = useMemo(() => {
        const dateStr = format(selectedDate, 'yyyy-MM-dd');

        return attendanceDates.get(dateStr) ?? null;
    }, [selectedDate, attendanceDates]);

    const calendarDays = useMemo(() => {
        const daysInMonth = getDaysInMonth(viewYear, viewMonth);
        const firstDay = getFirstDayOfMonth(viewYear, viewMonth);
        const prevMonthDays = getDaysInMonth(
            viewYear,
            viewMonth === 1 ? 12 : viewMonth - 1,
        );

        const days: { day: number; isCurrentMonth: boolean; date: Date }[] = [];

        for (let i = firstDay - 1; i >= 0; i--) {
            const d = prevMonthDays - i;
            const m = viewMonth === 1 ? 12 : viewMonth - 1;
            const y = viewMonth === 1 ? viewYear - 1 : viewYear;
            days.push({
                day: d,
                isCurrentMonth: false,
                date: new Date(y, m - 1, d),
            });
        }

        for (let i = 1; i <= daysInMonth; i++) {
            days.push({
                day: i,
                isCurrentMonth: true,
                date: new Date(viewYear, viewMonth - 1, i),
            });
        }

        const remaining = 42 - days.length;

        for (let i = 1; i <= remaining; i++) {
            const m = viewMonth === 12 ? 1 : viewMonth + 1;
            const y = viewMonth === 12 ? viewYear + 1 : viewYear;
            days.push({
                day: i,
                isCurrentMonth: false,
                date: new Date(y, m - 1, i),
            });
        }

        return days;
    }, [viewYear, viewMonth]);

    const handlePrevMonth = () => setViewDate((d) => subMonths(d, 1));
    const handleNextMonth = () => setViewDate((d) => addMonths(d, 1));

    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 },
        );
    };

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

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

    function formatTime(dateStr: string | null): string {
        if (!dateStr) {
return '-';
}

        return format(new Date(dateStr), 'HH:mm');
    }

    const hasCheckedIn = !!todayAttendance;
    const hasCheckedOut = !!todayAttendance?.check_out_at;

    const today = new Date();

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

            <div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
                <div>
                    <h2 className="text-2xl font-semibold tracking-tight">
                        Presensi
                    </h2>
                </div>

                {/* Alert Status Presensi */}
                <Alert>
                    <CalendarCheck className="h-4 w-4" />
                    <AlertTitle>Presensi Hari Ini</AlertTitle>
                    <AlertDescription>
                        <div className="flex flex-col gap-4">
                            <div className="flex flex-col gap-1">
                                {hasCheckedIn ? (
                                    <div className="flex items-center gap-4 text-sm">
                                        <div className="flex items-center gap-1.5">
                                            <CheckCircle2 className="h-3.5 w-3.5 text-green-600" />
                                            <span className="text-muted-foreground">
                                                Masuk:
                                            </span>
                                            <span className="font-medium">
                                                {formatTime(
                                                    todayAttendance?.check_in_at,
                                                )}
                                            </span>
                                        </div>
                                        <div className="flex items-center gap-1.5">
                                            {hasCheckedOut ? (
                                                <>
                                                    <CheckCircle2 className="h-3.5 w-3.5 text-green-600" />
                                                    <span className="text-muted-foreground">
                                                        Pulang:
                                                    </span>
                                                    <span className="font-medium">
                                                        {formatTime(
                                                            todayAttendance?.check_out_at,
                                                        )}
                                                    </span>
                                                </>
                                            ) : (
                                                <>
                                                    <Clock className="h-3.5 w-3.5 text-orange-500" />
                                                    <span className="text-muted-foreground">
                                                        Pulang:
                                                    </span>
                                                    <span className="font-medium text-orange-600">
                                                        Belum
                                                    </span>
                                                </>
                                            )}
                                        </div>
                                    </div>
                                ) : (
                                    <p className="text-sm text-muted-foreground">
                                        Anda belum melakukan presensi hari ini
                                    </p>
                                )}
                            </div>

                            <div className="flex items-center gap-2">
                                {locationLoading && (
                                    <span className="text-xs text-muted-foreground">
                                        Mendapatkan lokasi...
                                    </span>
                                )}
                                <Button
                                    size="sm"
                                    onClick={handleCheckIn}
                                    disabled={hasCheckedIn || locationLoading}
                                >
                                    <LogIn className="mr-1.5 h-3.5 w-3.5" />
                                    Presensi Masuk
                                </Button>
                                <Button
                                    size="sm"
                                    variant="outline"
                                    onClick={handleCheckOut}
                                    disabled={
                                        !hasCheckedIn ||
                                        hasCheckedOut ||
                                        locationLoading
                                    }
                                >
                                    <LogOut className="mr-1.5 h-3.5 w-3.5" />
                                    Presensi Pulang
                                </Button>
                            </div>
                        </div>
                    </AlertDescription>
                </Alert>

                {/* Summary Stats */}
                <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
                    <Card>
                        <CardContent className="flex items-center gap-3 py-3">
                            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-blue-100">
                                <CalendarDays className="h-5 w-5 text-blue-600" />
                            </div>
                            <div>
                                <p className="text-xs text-muted-foreground">
                                    Hari Kerja
                                </p>
                                <p className="text-lg font-bold">
                                    {monthStats.working_days}
                                </p>
                            </div>
                        </CardContent>
                    </Card>
                    <Card>
                        <CardContent className="flex items-center gap-3 py-3">
                            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-green-100">
                                <CheckCircle2 className="h-5 w-5 text-green-600" />
                            </div>
                            <div>
                                <p className="text-xs text-muted-foreground">
                                    Hadir
                                </p>
                                <p className="text-lg font-bold">
                                    {monthStats.present}
                                </p>
                            </div>
                        </CardContent>
                    </Card>
                    <Card>
                        <CardContent className="flex items-center gap-3 py-3">
                            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-red-100">
                                <UserX className="h-5 w-5 text-red-600" />
                            </div>
                            <div>
                                <p className="text-xs text-muted-foreground">
                                    Tidak Hadir
                                </p>
                                <p className="text-lg font-bold">
                                    {monthStats.absent}
                                </p>
                            </div>
                        </CardContent>
                    </Card>
                    <Card>
                        <CardContent className="flex items-center gap-3 py-3">
                            <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-amber-100">
                                <Wallet className="h-5 w-5 text-amber-600" />
                            </div>
                            <div>
                                <p className="text-xs text-muted-foreground">
                                    Cuti
                                </p>
                                <p className="text-lg font-bold">
                                    {monthStats.leave}
                                </p>
                            </div>
                        </CardContent>
                    </Card>
                </div>

                <Card
                    className="overflow-hidden"
                    style={{ '--card-spacing': '0px' } as React.CSSProperties}
                >
                    {/* Calendar Header */}
                    <div className="flex items-center justify-between border-b px-6 py-4">
                        <div className="flex items-center gap-3">
                            <div className="flex flex-col items-center overflow-hidden rounded-lg ring-1 ring-border">
                                <div className="bg-muted px-3 py-0.5">
                                    <span className="text-xs font-semibold text-muted-foreground uppercase">
                                        {format(today, 'MMM', {
                                            locale: id,
                                        })}
                                    </span>
                                </div>
                                <div className="px-3 py-1">
                                    <span className="text-lg font-bold text-primary">
                                        {format(today, 'dd')}
                                    </span>
                                </div>
                            </div>
                            <div>
                                <h3 className="text-lg font-semibold text-foreground">
                                    {format(viewDate, 'MMMM yyyy', {
                                        locale: id,
                                    })}
                                </h3>
                            </div>
                        </div>
                        <div className="flex items-center gap-1">
                            <Button
                                variant="ghost"
                                size="icon"
                                className="h-8 w-8"
                                onClick={handlePrevMonth}
                            >
                                <ChevronLeft className="h-4 w-4" />
                            </Button>
                            <Button
                                variant="ghost"
                                size="sm"
                                className="h-8 px-3 text-xs font-medium"
                                onClick={() => {
                                    setViewDate(new Date());
                                    setSelectedDate(new Date());
                                }}
                            >
                                Hari ini
                            </Button>
                            <Button
                                variant="ghost"
                                size="icon"
                                className="h-8 w-8"
                                onClick={handleNextMonth}
                            >
                                <ChevronRight className="h-4 w-4" />
                            </Button>
                        </div>
                    </div>

                    {/* Weekday Headers */}
                    <div className="grid grid-cols-7 border-b">
                        {WEEKDAYS.map((day) => (
                            <div
                                key={day}
                                className="flex items-center justify-center py-3 text-xs font-medium text-muted-foreground"
                            >
                                {day}
                            </div>
                        ))}
                    </div>

                    {/* Calendar Grid */}
                    <div className="grid grid-cols-7">
                        {calendarDays.map((cell, idx) => {
                            const dateStr = format(cell.date, 'yyyy-MM-dd');
                            const attendance = attendanceDates.get(dateStr);
                            const isSelected = isSameDay(
                                cell.date,
                                selectedDate,
                            );
                            const isTodayDate = isSameDay(
                                cell.date,
                                new Date(),
                            );

                            const today = new Date();
                            today.setHours(0, 0, 0, 0);
                            const cellDate = new Date(cell.date);
                            cellDate.setHours(0, 0, 0, 0);

                            const isPastDate = cellDate < today;
                            const showAbsent =
                                cell.isCurrentMonth &&
                                isPastDate &&
                                !isWeekend(cell.date) &&
                                !attendance;

                            const late = attendance
                                ? isLate(
                                      attendance.check_in_at,
                                      officeHour,
                                      officeMinute,
                                  )
                                : false;
                            const lateMins = attendance
                                ? getLateMinutes(
                                      attendance.check_in_at,
                                      officeHour,
                                      officeMinute,
                                  )
                                : 0;

                            return (
                                <button
                                    key={idx}
                                    onClick={() => {
                                        setSelectedDate(cell.date);

                                        if (attendance) {
setDetailAttendance(attendance);
}
                                    }}
                                    className={`group relative flex min-h-[100px] flex-col p-2 text-left transition-colors hover:bg-muted/50 ${
                                        !cell.isCurrentMonth
                                            ? 'bg-muted/30 text-muted-foreground/50'
                                            : ''
                                    }`}
                                    style={{
                                        borderRight: '1px solid var(--border)',
                                        borderBottom: '1px solid var(--border)',
                                    }}
                                >
                                    <div className="flex items-start justify-between">
                                        <span
                                            className={`flex h-7 w-7 items-center justify-center rounded-full text-xs font-semibold transition-colors ${
                                                isSelected
                                                    ? 'bg-primary text-primary-foreground'
                                                    : isTodayDate
                                                      ? 'bg-muted text-foreground'
                                                      : 'text-foreground'
                                            }`}
                                        >
                                            {cell.day}
                                        </span>
                                    </div>
                                    <div className="mt-1 flex flex-col gap-0.5">
                                        {attendance && (
                                            <>
                                                <span
                                                    className={`inline-flex items-center justify-center rounded-full px-1.5 py-0.5 text-[10px] font-semibold ${late ? 'bg-yellow-100 text-yellow-700' : 'bg-green-100 text-green-700'}`}
                                                >
                                                    {late
                                                        ? 'Terlambat'
                                                        : 'Hadir'}
                                                </span>
                                                <span className="text-[10px] text-muted-foreground">
                                                    Masuk :{' '}
                                                    {formatTime(
                                                        attendance.check_in_at,
                                                    )}
                                                </span>
                                                <span className="text-[10px] text-muted-foreground">
                                                    Pulang :{' '}
                                                    {formatTime(
                                                        attendance.check_out_at,
                                                    )}
                                                </span>
                                                {late && (
                                                    <span className="text-[10px] text-yellow-600">
                                                        Telat :{' '}
                                                        {formatMinutes(
                                                            lateMins,
                                                        )}{' '}
                                                        menit
                                                    </span>
                                                )}
                                                <span className="text-[10px] text-muted-foreground">
                                                    Jam Kerja :{' '}
                                                    {formatMinutes(
                                                        attendance.work_duration_minutes,
                                                    )}
                                                </span>
                                            </>
                                        )}
                                        {showAbsent && (
                                            <span className="inline-flex items-center justify-center rounded-full bg-red-100 px-1.5 py-0.5 text-[10px] font-semibold text-red-700">
                                                Tidak Hadir
                                            </span>
                                        )}
                                    </div>
                                </button>
                            );
                        })}
                    </div>
                </Card>
            </div>

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

            <Dialog
                open={!!detailAttendance}
                onOpenChange={(open) => !open && setDetailAttendance(null)}
            >
                <DialogContent className="sm:max-w-2xl">
                    <DialogHeader>
                        <DialogTitle>
                            Detail Presensi -{' '}
                            {detailAttendance &&
                                format(
                                    new Date(detailAttendance.attendance_date),
                                    'dd MMMM yyyy',
                                    { locale: id },
                                )}
                        </DialogTitle>
                    </DialogHeader>
                    {detailAttendance && (
                        <div className="flex flex-col gap-4">
                            <div className="grid grid-cols-2 gap-4">
                                <div className="flex flex-col gap-2">
                                    <span className="text-sm font-medium text-muted-foreground">
                                        Foto Masuk
                                    </span>
                                    {detailAttendance.check_in_photo ? (
                                        <img
                                            src={
                                                detailAttendance.check_in_photo
                                            }
                                            alt="Foto Masuk"
                                            className="w-full rounded-lg border object-cover"
                                        />
                                    ) : (
                                        <div className="flex h-40 items-center justify-center rounded-lg border bg-muted text-sm text-muted-foreground">
                                            Tidak ada foto
                                        </div>
                                    )}
                                    <div className="flex items-center gap-2 text-sm">
                                        <LogIn className="h-4 w-4 text-green-600" />
                                        <span className="font-medium">
                                            {formatTime(
                                                detailAttendance.check_in_at,
                                            )}
                                        </span>
                                    </div>
                                </div>
                                <div className="flex flex-col gap-2">
                                    <span className="text-sm font-medium text-muted-foreground">
                                        Foto Pulang
                                    </span>
                                    {detailAttendance.check_out_photo ? (
                                        <img
                                            src={
                                                detailAttendance.check_out_photo
                                            }
                                            alt="Foto Pulang"
                                            className="w-full rounded-lg border object-cover"
                                        />
                                    ) : (
                                        <div className="flex h-40 items-center justify-center rounded-lg border bg-muted text-sm text-muted-foreground">
                                            Tidak ada foto
                                        </div>
                                    )}
                                    <div className="flex items-center gap-2 text-sm">
                                        {detailAttendance.check_out_at ? (
                                            <>
                                                <LogOut className="h-4 w-4 text-blue-600" />
                                                <span className="font-medium">
                                                    {formatTime(
                                                        detailAttendance.check_out_at,
                                                    )}
                                                </span>
                                            </>
                                        ) : (
                                            <>
                                                <Clock className="h-4 w-4 text-orange-500" />
                                                <span className="font-medium text-orange-600">
                                                    Belum pulang
                                                </span>
                                            </>
                                        )}
                                    </div>
                                </div>
                            </div>
                            <div className="flex flex-col gap-2">
                                <span className="text-sm font-medium text-muted-foreground">
                                    Lokasi Presensi
                                </span>
                                <LocationMap
                                    latitude={
                                        detailAttendance.check_in_latitude
                                    }
                                    longitude={
                                        detailAttendance.check_in_longitude
                                    }
                                    height="200px"
                                />
                            </div>
                        </div>
                    )}
                </DialogContent>
            </Dialog>
        </>
    );
}
