/**
 * Online Board filter component matching the Angular `online-board-filter`
 * component DOM structure and CSS class names.
 *
 * Renders PrimeNG-style accordion with 2 tabs: Flight Number, Route.
 * Matches Angular p-accordion structure.
 *
 * @module
 */

import { type FC, useState, useCallback, type FormEvent } from "react";
import { useNavigate, useParams } from "@modern-js/runtime/router";
import { Calendar } from "primereact/calendar";
import { Slider, type SliderChangeEvent } from "primereact/slider";
import { useTranslation } from "@/i18n/provider.js";
import { CityAutocomplete } from "@/ui/city-autocomplete/index.js";
import { useDictionaries } from "@/shared/dictionaries/index.js";
import { buildOnlineBoardUrl } from "../url.js";
import "./OnlineBoardFilter.scss";

function minutesToTime(minutes: number): string {
  const h = Math.floor(minutes / 60);
  const m = minutes % 60;
  return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
}

type AccordionTab = "flight" | "route";

function dateToYyyymmdd(value: Date): string {
  const y = value.getFullYear().toString();
  const m = (value.getMonth() + 1).toString().padStart(2, "0");
  const d = value.getDate().toString().padStart(2, "0");
  return `${y}${m}${d}`;
}

/** Validates a flight number string (3-4 digits + optional letter suffix) */
function validateFlightNumber(value: string): string | null {
  if (!value.trim()) {
    return "BOARD.FLIGHT_NUMBER-ERROR-EMPTY";
  }
  const reg = /^\d{3,4}[A-Za-z]?$/;
  if (!reg.test(value.trim()) || value.trim().length > 5) {
    return "BOARD.FLIGHT_NUMBER-ERROR-ONLY-NUMBER";
  }
  return null;
}

export interface OnlineBoardFilterProps {
  /** Pre-populate filter from URL params on search results pages */
  initialDeparture?: string;
  initialArrival?: string;
  initialDate?: string;
  initialTab?: AccordionTab;
  initialFlightNumber?: string;
}

function yyyymmddToDate(yyyymmdd: string): Date {
  const y = parseInt(yyyymmdd.slice(0, 4), 10);
  const m = parseInt(yyyymmdd.slice(4, 6), 10) - 1;
  const d = parseInt(yyyymmdd.slice(6, 8), 10);
  return new Date(y, m, d);
}

export const OnlineBoardFilter: FC<OnlineBoardFilterProps> = ({
  initialDeparture,
  initialArrival,
  initialDate,
  initialTab,
  initialFlightNumber,
}) => {
  const { t } = useTranslation();
  const navigate = useNavigate();
  const routeParams = useParams<{ lang: string }>();
  const lang = routeParams.lang ?? "ru";
  const { dictionaries } = useDictionaries(lang);

  const [activeTab, setActiveTab] = useState<AccordionTab>(initialTab ?? "route");

  // Flight number fields
  const [flightNumber, setFlightNumber] = useState(initialFlightNumber ?? "");
  const [flightDate, setFlightDate] = useState<Date | null>(
    initialTab === "flight" && initialDate ? yyyymmddToDate(initialDate) : new Date(),
  );
  const [flightNumberError, setFlightNumberError] = useState<string | null>(null);

  // Route fields
  const [routeDepartureCode, setRouteDepartureCode] = useState<string>(initialDeparture ?? "");
  const [routeArrivalCode, setRouteArrivalCode] = useState<string>(initialArrival ?? "");
  const [routeDate, setRouteDate] = useState<Date | null>(
    initialDate ? yyyymmddToDate(initialDate) : new Date(),
  );
  const [timeRange, setTimeRange] = useState<[number, number]>([0, 1440]);

  const handleTabClick = useCallback((tab: AccordionTab) => {
    setActiveTab((prev) => (prev === tab ? prev : tab));
  }, []);

  const handleExchange = useCallback(() => {
    const prevDep = routeDepartureCode;
    setRouteDepartureCode(routeArrivalCode);
    setRouteArrivalCode(prevDep);
  }, [routeDepartureCode, routeArrivalCode]);

  const handleFlightSubmit = useCallback(
    (e: FormEvent) => {
      e.preventDefault();

      const error = validateFlightNumber(flightNumber);
      setFlightNumberError(error);
      if (error) return;

      if (!flightDate) return;
      const dateParam = dateToYyyymmdd(flightDate);
      const cleaned = flightNumber.trim().replace(/\s+/g, "");
      const carrier = "SU";
      const num = cleaned;
      if (!num) return;
      const url = buildOnlineBoardUrl({ type: "flight", carrier, flightNumber: num, date: dateParam });
      void navigate(`/${lang}/${url}`);
    },
    [flightNumber, flightDate, navigate, lang],
  );

  const handleRouteSubmit = useCallback(
    (e: FormEvent) => {
      e.preventDefault();

      if (!routeDate) return;
      const dateParam = dateToYyyymmdd(routeDate);
      const depCode = routeDepartureCode.trim().toUpperCase();
      const arrCode = routeArrivalCode.trim().toUpperCase();
      if (!depCode || !arrCode) return;
      const url = buildOnlineBoardUrl({ type: "route", departure: depCode, arrival: arrCode, date: dateParam });
      void navigate(`/${lang}/${url}`);
    },
    [routeDepartureCode, routeArrivalCode, routeDate, navigate, lang],
  );

  return (
    <div className="online-board-filter" data-testid="flight-filter">
      <section className="frame">
        <div className="p-accordion" data-testid="filter-accordion">
          {/* Flight Number Tab */}
          <div className={`p-accordion-tab${activeTab === "flight" ? " p-accordion-tab--active" : ""}`}>
            <div
              className={`p-accordion-header${activeTab === "flight" ? " p-highlight" : ""}`}
              data-testid="search-type-flight"
            >
              <a
                role="button"
                tabIndex={0}
                onClick={() => handleTabClick("flight")}
                onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") handleTabClick("flight"); }}
              >
                <span className="p-header">
                  <span>{t("BOARD.FLIGHT_NUMBER")}</span>
                  <span className={`arrow-icon${activeTab === "flight" ? " arrow-icon--rotated" : ""}`}>
                    <svg viewBox="0 0 12 8" width="12" height="8">
                      <path d="M1 1L6 6L11 1" stroke="currentColor" strokeWidth="1.5" fill="none" />
                    </svg>
                  </span>
                </span>
              </a>
            </div>
            {activeTab === "flight" && (
              <div className="p-accordion-content">
                <form onSubmit={handleFlightSubmit} data-testid="search-form">
                  <div className="filter-content">
                    <div className="p-field">
                      <label className="label--filter">
                        {t("SHARED.FLIGHT_NUMBER")}
                      </label>
                      {flightNumberError && (
                        <div className="validation-tooltip" data-testid="flight-number-error">
                          {t(flightNumberError)}
                        </div>
                      )}
                      <div className={`number-input-composite${flightNumber ? " has-value" : ""}${flightNumberError ? " has-error" : ""}`}>
                        <div className="prefix">SU</div>
                        <input
                          type="text"
                          className="input--filter input--flight-number"
                          placeholder={t("SHARED.FLIGHT_NUMBER_PLACEHOLDER")}
                          value={flightNumber}
                          maxLength={5}
                          onChange={(e) => {
                            setFlightNumber(e.target.value);
                            if (flightNumberError) setFlightNumberError(null);
                          }}
                          data-testid="flight-number-input"
                        />
                        <button
                          className="button-clear"
                          type="button"
                          onClick={() => {
                            setFlightNumber("");
                            setFlightNumberError(null);
                          }}
                          data-testid="flight-number-clear-button"
                        >
                          &times;
                        </button>
                      </div>
                    </div>

                    <div className="calendar">
                      <label className="label--filter">
                        {t("SHARED.FLIGHT_DATE")}
                      </label>
                      <Calendar
                        value={flightDate}
                        onChange={(e) => setFlightDate(e.value as Date | null)}
                        dateFormat="dd.mm.yy"
                        placeholder={t("SHARED.DATE_FORMAT")}
                        showIcon
                        className="input--filter"
                        data-testid="date-input"
                        inputId="search-date-input"
                      />
                    </div>
                  </div>

                  <div className="filter-button">
                    <button
                      type="submit"
                      className="search-button"
                      data-testid="search-submit"
                    >
                      <span>{t("SHARED.SEARCH")}</span>
                    </button>
                  </div>
                </form>
              </div>
            )}
          </div>

          {/* Route Tab */}
          <div className={`p-accordion-tab${activeTab === "route" ? " p-accordion-tab--active" : ""}`}>
            <div
              className={`p-accordion-header${activeTab === "route" ? " p-highlight" : ""}`}
              data-testid="search-type-route"
            >
              <a
                role="button"
                tabIndex={0}
                onClick={() => handleTabClick("route")}
                onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") handleTabClick("route"); }}
              >
                <span className="p-header">
                  <span>{t("BOARD.ROUTE")}</span>
                  <span className={`arrow-icon${activeTab === "route" ? " arrow-icon--rotated" : ""}`}>
                    <svg viewBox="0 0 12 8" width="12" height="8">
                      <path d="M1 1L6 6L11 1" stroke="currentColor" strokeWidth="1.5" fill="none" />
                    </svg>
                  </span>
                </span>
              </a>
            </div>
            {activeTab === "route" && (
              <div className="p-accordion-content">
                <form onSubmit={handleRouteSubmit} data-testid="search-form">
                  <div className="filter-content">
                    <CityAutocomplete
                      label={t("SHARED.DEPARTURE_CITY")}
                      placeholder={t("SHARED.CITY_PLACEHOLDER")}
                      value={routeDepartureCode}
                      onChange={setRouteDepartureCode}
                      dictionaries={dictionaries}
                      testIdPrefix="route-departure"
                    />

                    <div className="change-container">
                      <button
                        className="button-change"
                        type="button"
                        onClick={handleExchange}
                        data-testid="swap-cities-button"
                      >
                        <svg className="svg--change-city">
                          <use xlinkHref="/assets/img/sprite.svg#changeCity" />
                        </svg>
                      </button>
                    </div>

                    <CityAutocomplete
                      label={t("SHARED.ARRIVAL_CITY")}
                      placeholder={t("SHARED.CITY_PLACEHOLDER")}
                      value={routeArrivalCode}
                      onChange={setRouteArrivalCode}
                      dictionaries={dictionaries}
                      testIdPrefix="route-arrival"
                    />

                    <div className="calendar">
                      <label className="label--filter">
                        {t("SHARED.FLIGHT_DATE")}
                      </label>
                      <Calendar
                        value={routeDate}
                        onChange={(e) => setRouteDate(e.value as Date | null)}
                        dateFormat="dd.mm.yy"
                        placeholder={t("SHARED.DATE_FORMAT")}
                        showIcon
                        className="input--filter"
                        data-testid="date-input"
                        inputId="route-date-input"
                      />
                    </div>
                  </div>

                  <div className="wrapper--time-selector compact-view" data-testid="time-selector">
                    <div className="time-selector__label-value">
                      <div className="time-selector__label">{t("SHARED.FLIGHT_TIME")}</div>
                      <div className="time-selector__value">
                        {minutesToTime(timeRange[0])} — {minutesToTime(timeRange[1])}
                      </div>
                    </div>
                    <div className="time-selector">
                      <Slider
                        value={timeRange}
                        onChange={(e: SliderChangeEvent) => setTimeRange(e.value as [number, number])}
                        range
                        min={0}
                        max={1440}
                        step={60}
                      />
                    </div>
                  </div>

                  <div className="filter-button">
                    <button
                      type="submit"
                      className="search-button"
                      data-testid="search-submit"
                    >
                      <span>{t("SHARED.SEARCH")}</span>
                    </button>
                  </div>
                </form>
              </div>
            )}
          </div>
        </div>
      </section>
    </div>
  );
};
