/**
 * Day detail panel: shadcn Popover on desktop (>=640px), Sheet (bottom) on mobile.
 * Renders DayDetailContent; anchor for popover is a virtual element at the clicked cell rect.
 * Owns anchor rect state; parent opens via ref.current.openWithRect(dateKey, rect).
 */

"use client";

import * as React from "react";
import {
  Popover,
  PopoverAnchor,
  PopoverContent,
} from "@/components/ui/popover";
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
} from "@/components/ui/sheet";
import { Button } from "@/components/ui/button";
import { useIsDesktop } from "@/hooks/use-media-query";
import { useTranslation } from "@/i18n/use-translation";
import { dutiesByDate, calendarEventsByDate } from "@/lib/calendar-data";
import { localDateString, dateKeyToDDMM } from "@/lib/date-utils";
import { DayDetailContent } from "./DayDetailContent";
import type { CalendarEvent, DutyWithUser } from "@/types";
import { cn } from "@/lib/utils";
import { useAppStore } from "@/store/app-store";

/** Empty state for day detail: date and "no duties or events" message. */
function DayDetailEmpty({ dateKey }: { dateKey: string }) {
  const { t } = useTranslation();
  const todayKey = localDateString(new Date());
  const ddmm = dateKeyToDDMM(dateKey);
  const title =
    dateKey === todayKey ? t("duty.today") + ", " + ddmm : ddmm;
  return (
    <div className="flex flex-col gap-4">
      <h2
        id="day-detail-title"
        className="text-[1.1rem] font-semibold leading-tight m-0"
      >
        {title}
      </h2>
      <p className="text-sm text-muted-foreground m-0">
        {t("day_detail.no_events")}
      </p>
    </div>
  );
}

export interface DayDetailHandle {
  /** Open the panel for the given day with popover anchored at the given rect. */
  openWithRect: (dateKey: string, anchorRect: DOMRect) => void;
}

export interface DayDetailProps {
  /** All duties for the visible range (will be filtered by selectedDay). */
  duties: DutyWithUser[];
  /** All calendar events for the visible range. */
  calendarEvents: CalendarEvent[];
  /** Called when the panel should close. */
  onClose: () => void;
  className?: string;
}

/**
 * Virtual anchor: invisible div at the given rect so Popover positions relative to it.
 */
function VirtualAnchor({
  rect,
  className,
}: {
  rect: DOMRect;
  className?: string;
}) {
  return (
    <div
      className={cn("pointer-events-none fixed z-0", className)}
      style={{
        left: rect.left,
        top: rect.bottom,
        width: rect.width,
        height: 1,
      }}
      aria-hidden
    />
  );
}

export const DayDetail = React.forwardRef<DayDetailHandle, DayDetailProps>(
  function DayDetail({ duties, calendarEvents, onClose, className }, ref) {
    const isDesktop = useIsDesktop();
    const { t } = useTranslation();
    const selectedDay = useAppStore((s) => s.selectedDay);
    const setSelectedDay = useAppStore((s) => s.setSelectedDay);
    const [anchorRect, setAnchorRect] = React.useState<DOMRect | null>(null);
    const [exiting, setExiting] = React.useState(false);

    const open = selectedDay !== null;

    React.useImperativeHandle(
      ref,
      () => ({
        openWithRect(dateKey: string, rect: DOMRect) {
          setSelectedDay(dateKey);
          setAnchorRect(rect);
        },
      }),
      [setSelectedDay]
    );

    const handleClose = React.useCallback(() => {
      setSelectedDay(null);
      setAnchorRect(null);
      setExiting(false);
      onClose();
    }, [setSelectedDay, onClose]);

    /** Start close animation; actual unmount happens in onCloseAnimationEnd (or fallback timeout). */
    const requestClose = React.useCallback(() => {
      setExiting(true);
    }, []);

    // Fallback: if onAnimationEnd never fires (e.g. reduced motion), close after animation duration
    React.useEffect(() => {
      if (!exiting) return;
      const fallback = window.setTimeout(() => {
        handleClose();
      }, 320);
      return () => window.clearTimeout(fallback);
    }, [exiting, handleClose]);

    const dutiesByDateMap = React.useMemo(
      () => dutiesByDate(duties),
      [duties]
    );
    const eventsByDateMap = React.useMemo(
      () => calendarEventsByDate(calendarEvents),
      [calendarEvents]
    );

    const dayDuties = selectedDay ? dutiesByDateMap[selectedDay] ?? [] : [];
    const dayEvents = selectedDay ? eventsByDateMap[selectedDay] ?? [] : [];
    const hasContent = dayDuties.length > 0 || dayEvents.length > 0;

    // Close popover/sheet on window resize so anchor position does not become stale.
    React.useEffect(() => {
      if (!open) return;
      const onResize = () => handleClose();
      window.addEventListener("resize", onResize);
      return () => window.removeEventListener("resize", onResize);
    }, [open, handleClose]);

    const content =
      selectedDay &&
      (hasContent ? (
        <DayDetailContent
          dateKey={selectedDay}
          duties={dayDuties}
          eventSummaries={dayEvents}
        />
      ) : (
        <DayDetailEmpty dateKey={selectedDay} />
      ));

    if (!open || !selectedDay) return null;

  const panelClassName =
    "max-w-[min(360px,calc(100vw-24px))] max-h-[70vh] overflow-auto bg-surface text-[var(--text)] rounded-xl shadow-lg p-4 pt-9";
  const closeButton = (
    <Button
      type="button"
      variant="ghost"
      size="icon"
      className="absolute top-2 right-2 h-8 w-8 text-muted hover:text-[var(--text)] rounded-lg"
      onClick={requestClose}
      aria-label={t("day_detail.close")}
    >
      <svg
        xmlns="http://www.w3.org/2000/svg"
        width="18"
        height="18"
        viewBox="0 0 24 24"
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
        aria-hidden
      >
        <line x1="18" y1="6" x2="6" y2="18" />
        <line x1="6" y1="6" x2="18" y2="18" />
      </svg>
    </Button>
  );

  const renderSheet = (withHandle: boolean) => (
    <Sheet
      open={!exiting && open}
      onOpenChange={(o) => !o && requestClose()}
    >
      <SheetContent
        side="bottom"
        className={cn(
          "rounded-t-2xl pt-3 pb-[calc(24px+env(safe-area-inset-bottom,0px))] max-h-[70vh] bg-[var(--surface)]",
          className
        )}
        showCloseButton={false}
        onCloseAnimationEnd={handleClose}
      >
        <div className="relative px-4">
          {closeButton}
          {withHandle && (
            <div
              className="w-10 h-1 rounded-full bg-[var(--handle-bg)] mx-auto mb-2"
              aria-hidden
            />
          )}
          <SheetHeader className="p-0">
            <SheetTitle id="day-detail-sheet-title" className="sr-only">
              {selectedDay}
            </SheetTitle>
          </SheetHeader>
          {content}
        </div>
      </SheetContent>
    </Sheet>
  );

  if (isDesktop === true && anchorRect != null) {
    return (
      <Popover open={open} onOpenChange={(o) => !o && handleClose()}>
        <PopoverAnchor asChild>
          <VirtualAnchor rect={anchorRect} />
        </PopoverAnchor>
        <PopoverContent
          side="bottom"
          sideOffset={8}
          align="center"
          className={cn(panelClassName, "relative", className)}
          onCloseAutoFocus={(e) => e.preventDefault()}
          onEscapeKeyDown={handleClose}
        >
          {closeButton}
          {content}
        </PopoverContent>
      </Popover>
    );
  }

  return renderSheet(true);
  }
);
