import { type FC, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "@/i18n/provider.js";
import { DayTabButton } from "./DayTabButton.js";
import { DaySelect } from "./DaySelect.js";
import {
  formatYyyymmdd,
  generateDateRange,
  findPageIndex,
  parseYyyymmdd,
} from "./dateRange.js";
import "./DayTabs.scss";

const PAGE_SIZE = 7;

export interface DayTabsProps {
  selectedDate: string;
  availableDates: string[];
  daysBefore: number;
  daysAfter: number;
  locale: string;
  onNavigate: (date: string) => void;
  /**
   * Caption rendered above the mobile dropdown (desktop ignores it).
   * Pass 'SHARED.FLIGHT_DATE' on the details page to mirror Angular's
   * "Дата рейса" label.
   */
  mobileCaptionKey?: string;
}

export const DayTabs: FC<DayTabsProps> = ({
  selectedDate,
  availableDates,
  daysBefore,
  daysAfter,
  locale,
  onNavigate,
  mobileCaptionKey,
}) => {
  const { t } = useTranslation();
  const allDates = useMemo(
    () => generateDateRange(new Date(), daysBefore, daysAfter),
    [daysBefore, daysAfter],
  );

  const totalPages = Math.max(1, Math.ceil(allDates.length / PAGE_SIZE));

  const initialPage = useMemo(
    () => findPageIndex(allDates, selectedDate, PAGE_SIZE),
    [allDates, selectedDate],
  );

  const [currentPage, setCurrentPage] = useState(initialPage);

  // TZ §4.1.13.1: auto-scroll — keep the visible page in sync when the
  // URL-driven selectedDate changes externally (e.g. deep-link navigation).
  const activeBtnRef = useRef<HTMLButtonElement | null>(null);

  useEffect(() => {
    const newPage = findPageIndex(allDates, selectedDate, PAGE_SIZE);
    setCurrentPage(newPage);
  }, [allDates, selectedDate]);

  useEffect(() => {
    activeBtnRef.current?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
  }, [selectedDate]);

  // Empty availableDates means the calendar API hasn't resolved yet (or
  // the route has no day data). Treat every date as tappable in that
  // case — matches Angular where the tabs stay enabled until we *know*
  // the upstream reports no flights for a given day.
  const availableSet = useMemo(() => new Set(availableDates), [availableDates]);
  const disableByAvailability = availableDates.length > 0;

  const visibleDates = allDates.slice(
    currentPage * PAGE_SIZE,
    (currentPage + 1) * PAGE_SIZE,
  );

  // TZ §4.1.13.1: when the last active day is not the 7th visible slot,
  // pad the remaining slots with the *following* (out-of-range) dates,
  // rendered greyed-out so the user can see where the +N boundary lies —
  // matches Angular which keeps generating dates beyond +daysAfter and
  // disables them. Right-arrow is still disabled on the last page.
  const isLastPage = currentPage >= totalPages - 1;
  const paddingCount = isLastPage ? PAGE_SIZE - visibleDates.length : 0;
  const paddingDates = useMemo(() => {
    if (paddingCount === 0) return [];
    const last = visibleDates[visibleDates.length - 1];
    if (!last) return [];
    const lastDate = parseYyyymmdd(last);
    return Array.from({ length: paddingCount }, (_, i) => {
      const d = new Date(
        lastDate.getFullYear(),
        lastDate.getMonth(),
        lastDate.getDate() + i + 1,
      );
      return formatYyyymmdd(d);
    });
  }, [paddingCount, visibleDates]);

  const canGoPrev = currentPage > 0;
  const canGoNext = !isLastPage;

  return (
    <div className="day-tabs-wrap" data-testid="day-tabs">
      <div className="day-tabs">
        <button
          type="button"
          className="day-tabs__arrow"
          data-testid="day-tabs-prev"
          disabled={!canGoPrev}
          onClick={() => setCurrentPage((p) => Math.max(0, p - 1))}
          aria-label={t("SHARED.A11Y-PREV-PAGE")}
        >
          {"‹"}
        </button>
        <div className="day-tabs__list">
          {visibleDates.map((date) => (
            <DayTabButton
              key={date}
              date={date}
              isActive={date === selectedDate}
              isDisabled={disableByAvailability && !availableSet.has(date)}
              locale={locale}
              onClick={onNavigate}
              ref={date === selectedDate ? activeBtnRef : undefined}
            />
          ))}
          {paddingDates.map((date) => (
            <DayTabButton
              key={`pad-${date}`}
              date={date}
              isActive={false}
              isDisabled
              locale={locale}
              onClick={onNavigate}
            />
          ))}
        </div>
        <button
          type="button"
          className="day-tabs__arrow"
          data-testid="day-tabs-next"
          disabled={!canGoNext}
          onClick={() => setCurrentPage((p) => Math.min(totalPages - 1, p + 1))}
          aria-label={t("SHARED.A11Y-NEXT-PAGE")}
        >
          {"›"}
        </button>
      </div>
      <DaySelect
        selectedDate={selectedDate}
        availableDates={availableDates}
        locale={locale}
        onNavigate={onNavigate}
        {...(mobileCaptionKey ? { captionKey: mobileCaptionKey } : {})}
      />
    </div>
  );
};
