/**
 * Single calendar day cell: date number and day indicators. Click opens day detail.
 * Ported from webapp/js/calendar.js day cell rendering.
 */

"use client";

import React, { useMemo } from "react";
import { useTranslation } from "@/i18n/use-translation";
import { dateKeyToDDMM } from "@/lib/date-utils";
import { cn } from "@/lib/utils";
import type { DutyWithUser } from "@/types";
import { DayIndicators } from "./DayIndicators";

export interface CalendarDayProps {
  /** YYYY-MM-DD key for this day. */
  dateKey: string;
  /** Day of month (1–31) for display. */
  dayOfMonth: number;
  isToday: boolean;
  isOtherMonth: boolean;
  /** Duties overlapping this day (for indicators and tooltip). */
  duties: DutyWithUser[];
  /** External calendar event summaries for this day. */
  eventSummaries: string[];
  onDayClick: (dateKey: string, anchorRect: DOMRect) => void;
}

function CalendarDayInner({
  dateKey,
  dayOfMonth,
  isToday,
  isOtherMonth,
  duties,
  eventSummaries,
  onDayClick,
}: CalendarDayProps) {
  const { t } = useTranslation();
  const { dutyList, unavailableList, vacationList } = useMemo(
    () => ({
      dutyList: duties.filter((d) => d.event_type === "duty"),
      unavailableList: duties.filter((d) => d.event_type === "unavailable"),
      vacationList: duties.filter((d) => d.event_type === "vacation"),
    }),
    [duties]
  );
  const hasEvent = eventSummaries.length > 0;
  const showIndicator = !isOtherMonth;
  const hasAny = duties.length > 0 || hasEvent;

  const ariaParts: string[] = [dateKeyToDDMM(dateKey)];
  if (hasAny && showIndicator) {
    const counts: string[] = [];
    if (dutyList.length) counts.push(`${dutyList.length} ${t("event_type.duty")}`);
    if (unavailableList.length)
      counts.push(`${unavailableList.length} ${t("event_type.unavailable")}`);
    if (vacationList.length)
      counts.push(`${vacationList.length} ${t("event_type.vacation")}`);
    if (hasEvent) counts.push(t("hint.events"));
    ariaParts.push(counts.join(", "));
  } else {
    ariaParts.push(t("aria.day_info"));
  }
  const ariaLabel = ariaParts.join("; ");

  const content = (
    <button
      type="button"
      aria-label={ariaLabel}
      aria-disabled={isOtherMonth}
      data-date={dateKey}
      className={cn(
        "relative flex w-full aspect-square min-h-8 min-w-0 flex-col items-center justify-start rounded-lg p-1 text-[0.85rem] transition-[background-color,transform] overflow-hidden",
        "focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
        isOtherMonth &&
          "pointer-events-none opacity-40 bg-[var(--surface-muted-tint)] cursor-default",
        !isOtherMonth && [
          "bg-surface hover:bg-[var(--surface-hover-10)]",
          "active:scale-[0.98] cursor-pointer",
          isToday && "bg-today text-[var(--bg)] hover:bg-[var(--today-hover)]",
        ],
        showIndicator && hasAny && "font-bold",
        showIndicator &&
          hasEvent &&
          "bg-[linear-gradient(135deg,var(--surface)_0%,var(--today-gradient-end)_100%)] border border-[var(--today-border)]",
        isToday &&
          hasEvent &&
          "bg-today text-[var(--bg)] border border-[var(--today-border-selected)]"
      )}
      onClick={(e) => {
        if (isOtherMonth) return;
        onDayClick(dateKey, e.currentTarget.getBoundingClientRect());
      }}
    >
      <span className="num">{dayOfMonth}</span>
      {showIndicator && (duties.length > 0 || hasEvent) && (
        <DayIndicators
          dutyCount={dutyList.length}
          unavailableCount={unavailableList.length}
          vacationCount={vacationList.length}
          hasEvents={hasEvent}
          isToday={isToday}
        />
      )}
    </button>
  );

  return content;
}

function arePropsEqual(prev: CalendarDayProps, next: CalendarDayProps): boolean {
  return (
    prev.dateKey === next.dateKey &&
    prev.dayOfMonth === next.dayOfMonth &&
    prev.isToday === next.isToday &&
    prev.isOtherMonth === next.isOtherMonth &&
    prev.duties === next.duties &&
    prev.eventSummaries === next.eventSummaries &&
    prev.onDayClick === next.onDayClick
  );
}

export const CalendarDay = React.memo(CalendarDayInner, arePropsEqual);
