"use client";

import { useState, useMemo, useCallback, useEffect } from "react";
import { useTranslations } from "next-intl";
import { useRouter } from "@/i18n/navigation";
import { ChevronLeft, ChevronRight } from "lucide-react";
import {
  startOfMonth,
  endOfMonth,
  startOfWeek,
  endOfWeek,
  eachDayOfInterval,
  format,
  isToday,
  isSameDay,
  addMonths,
  subMonths,
  isSameMonth,
} from "date-fns";
import { cn } from "@/lib/utils";
import { useSettingsStore } from "@/stores/settings-store";
import { useCalendarStore } from "@/stores/calendar-store";
import { useAuthStore } from "@/stores/auth-store";
import { getEventDayBounds } from "@/lib/calendar-utils";

interface MiniCalendarDashletProps {
  events?: { date: string; color?: string }[];
  onDayClick?: (date: Date) => void;
  selectedDate?: Date;
}

const ALL_DAY_KEYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"] as const;

export function MiniCalendarDashlet({
  events: propEvents,
  onDayClick,
  selectedDate: propSelectedDate,
}: MiniCalendarDashletProps) {
  const t = useTranslations("calendar");
  const router = useRouter();
  const firstDayOfWeek = useSettingsStore((s) => s.firstDayOfWeek);
  const storeSelectedDate = useCalendarStore((s) => s.selectedDate);
  const storeEvents = useCalendarStore((s) => s.events);
  const selectedDate = propSelectedDate ?? storeSelectedDate;
  const client = useAuthStore((s) => s.client);

  const [displayMonth, setDisplayMonth] = useState(() => new Date());

  const weekStartsOn = useMemo(() => {
    if (firstDayOfWeek === 0) return 0 as const;
    if (firstDayOfWeek === 6) return 6 as const;
    return 1 as const;
  }, [firstDayOfWeek]);

  useEffect(() => {
    if (!client) return;
    const start = format(startOfMonth(displayMonth), "yyyy-MM-dd'T'00:00:00");
    const end = format(endOfMonth(displayMonth), "yyyy-MM-dd'T'23:59:59");
    const { dateRange } = useCalendarStore.getState();
    if (dateRange?.start === start && dateRange?.end === end) return;
    useCalendarStore.getState().fetchEvents(client, start, end);
  }, [displayMonth, client]);

  const days = useMemo(() => {
    const monthStart = startOfMonth(displayMonth);
    const monthEnd = endOfMonth(displayMonth);
    const calStart = startOfWeek(monthStart, { weekStartsOn });
    const calEnd = endOfWeek(monthEnd, { weekStartsOn });
    return eachDayOfInterval({ start: calStart, end: calEnd });
  }, [displayMonth, weekStartsOn]);

  const eventDates = useMemo(() => {
    const set = new Set<string>();
    for (const e of storeEvents) {
      try {
        const { startDay, endDay } = getEventDayBounds(e);
        const cursor = new Date(startDay);
        while (cursor <= endDay) {
          set.add(format(cursor, "yyyy-MM-dd"));
          cursor.setDate(cursor.getDate() + 1);
        }
      } catch {
        /* skip */
      }
    }
    if (propEvents) {
      for (const e of propEvents) {
        set.add(e.date);
      }
    }
    return set;
  }, [storeEvents, propEvents]);

  const dayHeaders = useMemo(
    () => [...ALL_DAY_KEYS.slice(weekStartsOn), ...ALL_DAY_KEYS.slice(0, weekStartsOn)],
    [weekStartsOn],
  );

  const handlePrevMonth = useCallback(() => {
    setDisplayMonth((prev) => subMonths(prev, 1));
  }, []);

  const handleNextMonth = useCallback(() => {
    setDisplayMonth((prev) => addMonths(prev, 1));
  }, []);

  const handleGoToToday = useCallback(() => {
    setDisplayMonth(new Date());
  }, []);

  const handleDayClick = useCallback(
    (day: Date) => {
      useCalendarStore.getState().setSelectedDate(day);
      if (onDayClick) {
        onDayClick(day);
      } else {
        router.push("/calendar");
      }
    },
    [onDayClick, router],
  );

  return (
    <div className="select-none px-2 py-1.5">
      <div className="flex items-center justify-between mb-1">
        <button
          onClick={handlePrevMonth}
          className="p-0.5 rounded hover:bg-muted transition-colors"
          aria-label={t("nav_prev")}
        >
          <ChevronLeft className="w-3.5 h-3.5 text-muted-foreground" />
        </button>
        <button
          onClick={handleGoToToday}
          className="text-xs font-medium hover:bg-muted px-1.5 py-0.5 rounded transition-colors"
          title={t("views.today")}
        >
          {format(displayMonth, "MMM yyyy")}
        </button>
        <button
          onClick={handleNextMonth}
          className="p-0.5 rounded hover:bg-muted transition-colors"
          aria-label={t("nav_next")}
        >
          <ChevronRight className="w-3.5 h-3.5 text-muted-foreground" />
        </button>
      </div>

      <div className="grid grid-cols-7 mb-0.5">
        {dayHeaders.map((dh) => (
          <div
            key={dh}
            className="text-center text-[9px] font-medium text-muted-foreground py-0.5"
          >
            {t(`days.${dh}`)}
          </div>
        ))}
      </div>

      <div className="grid grid-cols-7 gap-0">
        {days.map((day) => {
          const inMonth = isSameMonth(day, displayMonth);
          const selected = isSameDay(day, selectedDate);
          const today = isToday(day);
          const dateStr = format(day, "yyyy-MM-dd");
          const hasEvent = eventDates.has(dateStr);
          const dotColor =
            propEvents?.find((e) => e.date === dateStr && e.color)?.color ??
            undefined;

          return (
            <button
              key={day.toISOString()}
              onClick={() => handleDayClick(day)}
              className={cn(
                "relative flex items-center justify-center w-6 h-6 text-[11px] rounded-full transition-colors mx-auto",
                !inMonth && "text-muted-foreground/30",
                inMonth && !selected && "hover:bg-muted",
                today && !selected && "font-bold text-primary",
                selected && "bg-primary text-primary-foreground",
              )}
            >
              {day.getDate()}
              {hasEvent && !selected && (
                <span
                  className="absolute bottom-0 left-1/2 -translate-x-1/2 w-1 h-1 rounded-full bg-primary"
                  style={dotColor ? { backgroundColor: dotColor } : undefined}
                />
              )}
            </button>
          );
        })}
      </div>
    </div>
  );
}
