import { type FC, useState } from "react";
import { useTranslation } from "@/i18n/provider.js";
import type { IFlightLeg } from "../../types.js";
import { Station } from "./Station.js";
import { StationChange } from "./StationChange.js";

export interface TimelineProps {
  legs: IFlightLeg[];
  canChange: boolean;
}

function depTime(leg: IFlightLeg, canChange: boolean): string {
  const t = leg.departure.times;
  if (canChange) return t.actualBlockOff?.localTime ?? t.scheduledDeparture.localTime;
  return t.scheduledDeparture.localTime;
}

function arrTime(leg: IFlightLeg, canChange: boolean): string {
  const t = leg.arrival.times;
  if (canChange) return t.actualBlockOn?.localTime ?? t.scheduledArrival.localTime;
  return t.scheduledArrival.localTime;
}

/**
 * Extract the day-change value (+X/-X) for a departure time.
 * Prefers actual if canChange and actual exists, otherwise falls back to scheduled.
 * §4.1.15.5 Маршрут rows 3 & 9: "+X"/"-X" badge required when value !== 0.
 */
function depDayChange(leg: IFlightLeg, canChange: boolean): number {
  const t = leg.departure.times;
  if (canChange && t.actualBlockOff) return t.actualBlockOff.dayChange?.value ?? 0;
  return t.scheduledDeparture.dayChange?.value ?? 0;
}

/**
 * Extract the day-change value (+X/-X) for an arrival time.
 * Prefers actual if canChange and actual exists, otherwise falls back to scheduled.
 * §4.1.15.5 Маршрут rows 3 & 9: "+X"/"-X" badge required when value !== 0.
 */
function arrDayChange(leg: IFlightLeg, canChange: boolean): number {
  const t = leg.arrival.times;
  if (canChange && t.actualBlockOn) return t.actualBlockOn.dayChange?.value ?? 0;
  return t.scheduledArrival.dayChange?.value ?? 0;
}

function isSpecifying(leg: IFlightLeg, canChange: boolean): boolean {
  return canChange && leg.estimatedDuration?.isNegative === true;
}

/** Single time cell with optional day-change badge (+X / -X). */
interface TimeCellProps {
  time: string;
  /** Day offset relative to departure date: 0 = no badge, +1 = "+1", -1 = "-1" etc. */
  dayChange: number;
}

const TimeCell: FC<TimeCellProps> = ({ time, dayChange }) => (
  <span className="timeline__time-cell">
    {time}
    {dayChange !== 0 && (
      <span
        className="timeline__day-change"
        data-testid="timeline-day-change"
        aria-label={`${dayChange > 0 ? "+" : ""}${dayChange}`}
      >
        {dayChange > 0 ? `+${dayChange}` : `${dayChange}`}
      </span>
    )}
  </span>
);

interface SectionProps {
  legNumber: number;
  duration: string;
  specifying: boolean;
}

const Section: FC<SectionProps> = ({ legNumber, duration, specifying }) => (
  <div className="timeline-section">
    <div className="timeline-section__separator" />
    <span className="timeline-section__number">{legNumber}</span>
    <span
      className={`timeline-section__duration${
        specifying ? " timeline-section__duration--specifying" : ""
      }`}
    >
      {duration}
    </span>
    <div className="timeline-section__separator" />
  </div>
);

export const Timeline: FC<TimelineProps> = ({ legs, canChange }) => {
  const { t } = useTranslation();
  const [index, setIndex] = useState(0);
  const lastPairStart = Math.max(0, legs.length - 2);
  const currentLeg = legs[index];
  const nextLeg = legs[index + 1];

  if (!currentLeg || !nextLeg) return null;

  return (
    <div className="timeline">
      {index > 0 && (
        <button
          type="button"
          className="timeline__arrow"
          data-testid="timeline-prev"
          onClick={() => setIndex((i) => Math.max(0, i - 1))}
          aria-label={t("SHARED.A11Y-PREV-LEGS")}
        >
          {"\u2039"}
        </button>
      )}

      <div className="timeline__content">
        <div className="timeline__row timeline__row--times">
          <TimeCell time={depTime(currentLeg, canChange)} dayChange={depDayChange(currentLeg, canChange)} />
          <Section
            legNumber={index + 1}
            duration={currentLeg.flyingTime}
            specifying={isSpecifying(currentLeg, canChange)}
          />
          <TimeCell time={arrTime(currentLeg, canChange)} dayChange={arrDayChange(currentLeg, canChange)} />
          <Section
            legNumber={index + 2}
            duration={nextLeg.flyingTime}
            specifying={isSpecifying(nextLeg, canChange)}
          />
          <TimeCell time={depTime(nextLeg, canChange)} dayChange={depDayChange(nextLeg, canChange)} />
          <TimeCell time={arrTime(nextLeg, canChange)} dayChange={arrDayChange(nextLeg, canChange)} />
        </div>

        <div className="timeline__row timeline__row--stations">
          <Station station={currentLeg.departure} align="left" size="medium" />
          <StationChange from={currentLeg.arrival} to={nextLeg.departure} />
          <Station station={nextLeg.arrival} align="right" size="medium" />
        </div>
      </div>

      {index < lastPairStart && (
        <button
          type="button"
          className="timeline__arrow"
          data-testid="timeline-next"
          onClick={() => setIndex((i) => Math.min(lastPairStart, i + 1))}
          aria-label={t("SHARED.A11Y-NEXT-LEGS")}
        >
          {"\u203a"}
        </button>
      )}
    </div>
  );
};
