"use client";

import * as React from "react";
import { format, startOfWeek, endOfWeek, eachDayOfInterval, isSameDay, subWeeks, addWeeks, subMonths, addMonths } from "date-fns";
import { Calendar } from "~/components/ui/calendar";
import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
    DialogFooter,
} from "~/components/ui/dialog";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Label } from "~/components/ui/label";
import { NumberInput } from "~/components/ui/number-input";
import { Plus, Trash2, Clock, Calendar as CalendarIcon, ChevronLeft, ChevronRight } from "lucide-react";
import { cn } from "~/lib/utils";


interface InvoiceItem {
    id: string;
    date: Date;
    description: string;
    hours: number;
    rate: number;
    amount: number;
}

interface InvoiceCalendarViewProps {
    items: InvoiceItem[];
    onUpdateItem: (
        index: number,
        field: string,
        value: string | number | Date
    ) => void;
    onAddItem: (date?: Date) => void;
    onRemoveItem: (index: number) => void;
    className?: string;
    defaultHourlyRate: number | null;
}

export function InvoiceCalendarView({
    items,
    onUpdateItem,
    onAddItem,
    onRemoveItem,
    className,
    defaultHourlyRate: _defaultHourlyRate,
}: InvoiceCalendarViewProps) {
    const [date, setDate] = React.useState<Date | undefined>(undefined); // Start unselected
    const [viewDate, setViewDate] = React.useState<Date>(new Date()); // Controls the view (month/week)
    const [view, setView] = React.useState<"month" | "week">("month");
    const [dialogOpen, setDialogOpen] = React.useState(false);
    // Derived state for selected date items - solves cursor jumping
    const selectedDateItems = React.useMemo(() => {
        if (!date) return [];
        return items
            .map((item, index) => ({ item, index }))
            .filter((wrapper) => {
                const itemDate = new Date(wrapper.item.date);
                return isSameDay(itemDate, date);
            });
    }, [items, date]);

    // Helper to get items for any date (for calendar view)
    const getItemsForDate = React.useCallback((targetDate: Date) => {
        return items
            .map((item, index) => ({ item, index }))
            .filter((wrapper) => {
                const itemDate = new Date(wrapper.item.date);
                return isSameDay(itemDate, targetDate);
            });
    }, [items]);

    const handleSelectDate = (newDate: Date | undefined) => {
        if (!newDate) return;
        setDate(newDate);
        // Optionally update viewDate to match selection if desired, but user wants them decoupled during nav
        // setViewDate(newDate); 
        setDialogOpen(true);
    };

    const handleAddNewItem = () => {
        if (date) {
            onAddItem(date);
        }
    };

    // Week View Logic - Uses viewDate
    const currentWeekStart = startOfWeek(viewDate);
    const currentWeekEnd = endOfWeek(viewDate);
    const weekDays = eachDayOfInterval({ start: currentWeekStart, end: currentWeekEnd });

    const handleCloseDialog = (isOpen: boolean) => {
        setDialogOpen(isOpen);
        if (!isOpen) {
            setDate(undefined);
        }
    };

    return (
        <div className={cn("flex flex-col gap-4 h-full w-full", className)}>
            <div className="flex items-center justify-between px-4 pt-4 w-full gap-4">
                {/* Navigation Controls */}
                <div className="flex items-center gap-2">
                    {view === "week" ? (
                        <>
                            <Button variant="outline" size="icon" onClick={() => setViewDate(d => subWeeks(d, 1))} className="h-8 w-8 rounded-lg">
                                <ChevronLeft className="h-4 w-4" />
                            </Button>
                            <span className="text-sm font-medium w-36 text-center">
                                {`${format(currentWeekStart, "MMM d")} - ${format(currentWeekEnd, "MMM d")}`}
                            </span>
                            <Button variant="outline" size="icon" onClick={() => setViewDate(d => addWeeks(d, 1))} className="h-8 w-8 rounded-lg">
                                <ChevronRight className="h-4 w-4" />
                            </Button>
                        </>
                    ) : (
                        <>
                            <Button variant="outline" size="icon" onClick={() => setViewDate(d => subMonths(d, 1))} className="h-8 w-8 rounded-lg">
                                <ChevronLeft className="h-4 w-4" />
                            </Button>
                            <span className="text-sm font-medium w-36 text-center">
                                {format(viewDate, "MMMM yyyy")}
                            </span>
                            <Button variant="outline" size="icon" onClick={() => setViewDate(d => addMonths(d, 1))} className="h-8 w-8 rounded-lg">
                                <ChevronRight className="h-4 w-4" />
                            </Button>
                        </>
                    )}
                </div>

                <div className="flex items-center space-x-2 ml-auto">
                    {/* View Switcher */}
                    <div className="bg-muted p-1 rounded-lg flex text-sm">
                        <button
                            type="button"
                            onClick={() => setView("month")}
                            className={cn("px-3 py-1.5 rounded-md transition-all text-center font-medium", view === "month" ? "bg-background shadow text-foreground" : "text-muted-foreground hover:text-foreground")}
                        >
                            Month
                        </button>
                        <button
                            type="button"
                            onClick={() => setView("week")}
                            className={cn("px-3 py-1.5 rounded-md transition-all text-center font-medium", view === "week" ? "bg-background shadow text-foreground" : "text-muted-foreground hover:text-foreground")}
                        >
                            Week
                        </button>
                    </div>
                </div>
            </div>

            <div className="flex-1 w-full overflow-hidden">
                {view === "month" ? (
                    <Calendar
                        mode="single"
                        selected={date}
                        onSelect={handleSelectDate}
                        month={viewDate}
                        onMonthChange={setViewDate}
                        className="rounded-md border-0 w-full p-0"
                        classNames={{
                            root: "w-full p-0",
                            months: "flex flex-col w-full",
                            month: "flex flex-col w-full space-y-4",

                            // Grid - Revert to Flex but Enforce 1/7th Width
                            // table: "w-full border-collapse", // No table-fixed
                            head_row: "flex w-full",
                            row: "flex w-full mt-2",

                            // Cells & Headers: Explicit width 14.28%
                            // Use calc(100%/7) via tailwind arbitrary or just flex bases.
                            // Better: w-[14.28%] flex-none (approx 1/7)
                            weekdays: "flex w-full border-b",
                            weekday: "w-[14.285%] flex-none text-muted-foreground font-normal text-[0.8rem] text-center pb-4",

                            week: "flex w-full mt-2",
                            cell: "w-[14.285%] flex-none h-32 border-b p-0 relative focus-within:relative focus-within:z-20 text-center text-sm",

                            // Hide internal navigation & caption entirely
                            nav: "hidden",
                            caption: "hidden",

                            day: cn(
                                "w-full h-full p-2 font-normal aria-selected:opacity-100 flex flex-col items-start justify-start gap-1 hover:bg-accent/50 hover:text-accent-foreground align-top transition-colors rounded-xl"
                            ),
                            day_selected: "bg-primary/5 text-primary",
                            day_today: "bg-accent/20",
                            day_outside: "text-muted-foreground opacity-30",
                        }}
                        formatters={{
                            formatMonthCaption: () => "", // Clear default caption text to prevent duplication
                        }}
                        components={{
                            DayButton: (props) => {
                                const { day, modifiers, className, ...buttonProps } = props;
                                const DayDate = day.date;
                                const dayItems = getItemsForDate(DayDate);
                                // const totalHours = dayItems.reduce((acc, curr) => acc + curr.item.hours, 0); // Unused now

                                return (
                                    <button
                                        {...buttonProps}
                                        type="button"
                                        className={cn(
                                            "relative flex h-full w-full flex-col items-start justify-between p-2 transition-all rounded-xl border border-transparent hover:border-border/50 hover:bg-secondary/30 text-left overflow-hidden",
                                            // Selected State: Filled Box, No Outline
                                            modifiers.selected && "bg-primary text-primary-foreground hover:bg-primary/90 shadow-md transform scale-[0.98]",
                                            modifiers.today && !modifiers.selected && "bg-accent/40 rounded-xl",
                                            className
                                        )}
                                    >
                                        <span className="text-sm font-medium z-10">{DayDate.getDate()}</span>
                                        {dayItems.length > 0 && (
                                            <div className="flex flex-col gap-1 w-full mt-1 overflow-hidden h-full justify-end pb-1">
                                                <div className="flex flex-col gap-1 w-full mt-1">
                                                    {dayItems.slice(0, 4).map((item, idx) => (
                                                        <div key={idx} className={cn("h-1 w-full rounded-full", modifiers.selected ? "bg-primary-foreground/50" : "bg-primary/50")} />
                                                    ))}
                                                    {dayItems.length > 4 && <div className={cn("h-1 w-1/3 rounded-full", modifiers.selected ? "bg-primary-foreground/30" : "bg-muted-foreground/30")} />}
                                                </div>
                                            </div>
                                        )}
                                    </button>
                                );
                            }
                        }}
                    />
                ) : (
                    <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-7 gap-4 p-4 h-full w-full">
                        {weekDays.map((day) => {
                            const isSelected = date && isSameDay(day, date);
                            const isToday = isSameDay(day, new Date());
                            const dayItems = getItemsForDate(day);
                            const totalHours = dayItems.reduce((acc, curr) => acc + curr.item.hours, 0);

                            return (
                                <button
                                    key={day.toString()}
                                    type="button"
                                    onClick={() => handleSelectDate(day)}
                                    className={cn(
                                        "flex flex-col h-full min-h-[400px] border rounded-3xl p-4 text-left transition-all hover:bg-accent/30 w-full",
                                        isSelected ? "ring-2 ring-primary ring-offset-2 bg-primary/5" : "bg-background/40",
                                        isToday && !isSelected ? "bg-accent/40" : ""
                                    )}
                                >
                                    <div className="flex flex-col items-center mb-4 pb-4 border-b w-full">
                                        <span className="text-xs font-bold text-muted-foreground uppercase">{format(day, "EEE")}</span>
                                        <span className="text-2xl font-light">{format(day, "d")}</span>
                                    </div>

                                    <div className="flex-1 space-y-2 w-full overflow-hidden">
                                        {dayItems.length > 0 ? (
                                            dayItems.map(({ item }, i) => (
                                                <div key={i} className="bg-background rounded-xl p-2 text-xs shadow-sm border">
                                                    <div className="font-medium truncate">{item.description || "No description"}</div>
                                                    <div className="text-muted-foreground">{item.hours}h</div>
                                                </div>
                                            ))
                                        ) : (
                                            <div className="h-full flex items-center justify-center text-muted-foreground/20">
                                                <Plus className="w-8 h-8" />
                                            </div>
                                        )}
                                    </div>

                                    {dayItems.length > 0 && (
                                        <div className="pt-2 mt-auto text-center w-full">
                                            <span className="text-sm font-semibold">{totalHours}h Total</span>
                                        </div>
                                    )}
                                </button>
                            );
                        })}
                    </div>
                )}
            </div>

            {/* Dialog for Day Details - Now consistently used and rounded */}
            <Dialog
                open={dialogOpen}
                onOpenChange={handleCloseDialog}
            >
                <DialogContent className="max-h-[85vh] overflow-y-auto sm:max-w-[600px] rounded-3xl">
                    <DialogHeader>
                        <DialogTitle className="flex items-center gap-2 text-xl">
                            <div className="bg-primary/10 p-2 rounded-full">
                                <CalendarIcon className="w-5 h-5 text-primary" />
                            </div>
                            {date ? format(date, "EEEE, MMMM do") : "Details"}
                        </DialogTitle>
                    </DialogHeader>

                    <div className="space-y-6 py-4">
                        {date && selectedDateItems.length === 0 ? (
                            <div className="flex flex-col items-center justify-center py-12 text-center space-y-3 bg-secondary/20 rounded-3xl border border-dashed border-border">
                                <Clock className="w-12 h-12 text-muted-foreground/30" />
                                <div className="space-y-1">
                                    <p className="font-medium text-foreground">No hours logged</p>
                                    <p className="text-sm text-muted-foreground">Add time entries for this day.</p>
                                </div>
                                <Button onClick={handleAddNewItem} variant="secondary" className="mt-2 text-primary">
                                    Start Logging
                                </Button>
                            </div>
                        ) : (
                            <div className="space-y-4">
                                {selectedDateItems.map(({ item, index }) => (
                                    <div key={item.id} className="group relative bg-card hover:bg-accent/10 transition-colors p-4 rounded-2xl border shadow-sm space-y-3">
                                        <div className="flex gap-4">
                                            <div className="flex-1 space-y-1.5">
                                                <Label className="text-xs font-semibold text-muted-foreground">Description</Label>
                                                <Input
                                                    value={item.description}
                                                    onChange={(e) => onUpdateItem(index, "description", e.target.value)}
                                                    placeholder="What did you work on?"
                                                    className="bg-background/50 border-transparent focus:border-input focus:bg-background transition-all"
                                                />
                                            </div>
                                        </div>
                                        <div className="flex items-end gap-3">
                                            <div className="w-24 space-y-1.5">
                                                <Label className="text-xs font-semibold text-muted-foreground">Hours</Label>
                                                <NumberInput
                                                    value={item.hours}
                                                    onChange={v => onUpdateItem(index, "hours", v)}
                                                    step={0.25}
                                                    min={0}
                                                    className="bg-background/50"
                                                />
                                            </div>
                                            <div className="w-28 space-y-1.5">
                                                <Label className="text-xs font-semibold text-muted-foreground">Rate ($/hr)</Label>
                                                <NumberInput
                                                    value={item.rate}
                                                    onChange={v => onUpdateItem(index, "rate", v)}
                                                    prefix="$"
                                                    min={0}
                                                    className="bg-background/50"
                                                />
                                            </div>
                                            <div className="flex-1 flex justify-end items-center pb-2 text-sm font-medium text-muted-foreground">
                                                <span>${(item.hours * item.rate).toFixed(2)}</span>
                                            </div>
                                            <Button
                                                variant="ghost"
                                                size="icon"
                                                className="h-10 w-10 text-muted-foreground hover:text-destructive hover:bg-destructive/10 rounded-xl"
                                                onClick={() => onRemoveItem(index)}
                                            >
                                                <Trash2 className="w-4 h-4" />
                                            </Button>
                                        </div>
                                    </div>
                                ))}
                                <Button variant="outline" onClick={handleAddNewItem} className="w-full border-dashed py-6 rounded-xl hover:bg-accent/40 hover:border-primary/50 text-muted-foreground hover:text-primary transition-all">
                                    <Plus className="w-4 h-4 mr-2" />
                                    Add Another Entry
                                </Button>
                            </div>
                        )}
                    </div>
                    <DialogFooter>
                        <Button className="w-full sm:w-auto rounded-xl" onClick={() => handleCloseDialog(false)}>Done</Button>
                    </DialogFooter>
                </DialogContent>
            </Dialog>
        </div>
    );
}
