/**
 * Schedule start page -- search form for route-based schedule search.
 *
 * No API calls on load. Pure form that navigates to the appropriate
 * search route on submit.
 *
 * @module
 */

import { type FC, useState, useCallback, type FormEvent } from "react";
import { useNavigate, useParams, useSearchParams } from "@modern-js/runtime/router";
import { Calendar } from "primereact/calendar";
import { Slider, type SliderChangeEvent } from "primereact/slider";
import { AutoComplete, type AutoCompleteCompleteEvent } from "primereact/autocomplete";
import { useTranslation } from "@/i18n/provider.js";
import { useCitySearch, type CitySuggestion } from "@/shared/hooks/useCitySearch.js";
import { PageLayout } from "@/ui/layout/PageLayout.js";
import { PageTabs } from "@/ui/layout/PageTabs.js";
import { SearchHistory } from "@/ui/layout/SearchHistory.js";
import { PopularRequestsPanel } from "@/features/popular-requests/components/PopularRequestsPanel.js";
import type { PopularRequest } from "@/features/popular-requests/types.js";
import { buildPopularRequestQueryParams } from "@/features/online-board/components/OnlineBoardStartPage.js";
import { buildScheduleUrl } from "../url.js";
import "./ScheduleStartPage.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")}`;
}

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}`;
}

function addDays(base: Date, days: number): Date {
  const result = new Date(base);
  result.setDate(result.getDate() + days);
  return result;
}

/**
 * Build URL search params for a schedule-type popular request.
 *
 * Only Route and RouteWithBack modes produce params; other modes
 * return empty params (they belong to the online board).
 */
export function buildSchedulePopularRequestQueryParams(
  request: PopularRequest,
): URLSearchParams {
  const params = new URLSearchParams();
  if (request.mode === "Route" || request.mode === "RouteWithBack") {
    params.set("departure", request.departure);
    params.set("arrival", request.arrival);
    if (request.mode === "RouteWithBack") {
      params.set("return", "true");
    }
  }
  return params;
}

export const ScheduleStartPage: FC = () => {
  const navigate = useNavigate();
  const { t } = useTranslation();
  const routeParams = useParams<{ lang: string }>();
  const lang = routeParams.lang ?? "ru";
  const [searchParams] = useSearchParams();

  const today = new Date();

  const [departureAirport, setDepartureAirport] = useState<CitySuggestion | string>(searchParams.get("departure") ?? "");
  const [arrivalAirport, setArrivalAirport] = useState<CitySuggestion | string>(searchParams.get("arrival") ?? "");
  const [dateFrom, setDateFrom] = useState<Date | null>(today);
  const [dateTo, setDateTo] = useState<Date | null>(addDays(today, 7));
  const [timeRange, setTimeRange] = useState<[number, number]>([0, 1440]);
  const [directOnly, setDirectOnly] = useState(false);
  const [isRoundTrip, setIsRoundTrip] = useState(searchParams.get("return") === "true");
  const [returnDateFrom, setReturnDateFrom] = useState<Date | null>(addDays(today, 7));
  const [returnDateTo, setReturnDateTo] = useState<Date | null>(addDays(today, 14));
  const [returnTimeRange, setReturnTimeRange] = useState<[number, number]>([0, 1440]);

  // City autocomplete search
  const { suggestions: departureSuggestions, search: searchDeparture } = useCitySearch();
  const { suggestions: arrivalSuggestions, search: searchArrival } = useCitySearch();

  const handleDepartureSearch = useCallback((event: AutoCompleteCompleteEvent) => {
    void searchDeparture(event.query);
  }, [searchDeparture]);

  const handleArrivalSearch = useCallback((event: AutoCompleteCompleteEvent) => {
    void searchArrival(event.query);
  }, [searchArrival]);

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

      const dep = (typeof departureAirport === "string"
        ? departureAirport.trim().toUpperCase()
        : departureAirport.code);
      const arr = (typeof arrivalAirport === "string"
        ? arrivalAirport.trim().toUpperCase()
        : arrivalAirport.code);
      if (!dep || !arr) return;

      if (!dateFrom || !dateTo) return;
      const dateFromParam = dateToYyyymmdd(dateFrom);
      const dateToParam = dateToYyyymmdd(dateTo);

      let url: string;

      const outbound: { departure: string; arrival: string; dateFrom: string; dateTo: string; timeFrom?: string; timeTo?: string } = {
        departure: dep, arrival: arr, dateFrom: dateFromParam, dateTo: dateToParam,
      };
      if (timeRange[0] > 0) outbound.timeFrom = minutesToTime(timeRange[0]).replace(":", "");
      if (timeRange[1] < 1440) outbound.timeTo = minutesToTime(timeRange[1]).replace(":", "");

      if (isRoundTrip) {
        if (!returnDateFrom || !returnDateTo) return;
        const retDateFromParam = dateToYyyymmdd(returnDateFrom);
        const retDateToParam = dateToYyyymmdd(returnDateTo);

        const inbound: { departure: string; arrival: string; dateFrom: string; dateTo: string; timeFrom?: string; timeTo?: string } = {
          departure: arr, arrival: dep, dateFrom: retDateFromParam, dateTo: retDateToParam,
        };
        if (returnTimeRange[0] > 0) inbound.timeFrom = minutesToTime(returnTimeRange[0]).replace(":", "");
        if (returnTimeRange[1] < 1440) inbound.timeTo = minutesToTime(returnTimeRange[1]).replace(":", "");

        url = buildScheduleUrl({
          type: "roundtrip",
          outbound,
          inbound,
        });
      } else {
        url = buildScheduleUrl({
          type: "route",
          outbound,
        });
      }

      void navigate(`/${lang}/${url}`);
    },
    [departureAirport, arrivalAirport, dateFrom, dateTo, timeRange, directOnly, isRoundTrip, returnDateFrom, returnDateTo, returnTimeRange, navigate, lang],
  );

  const handlePopularRequestClick = useCallback(
    (request: PopularRequest) => {
      if (request.type === "Onlineboard") {
        const params = buildPopularRequestQueryParams(request);
        navigate({
          pathname: `/${lang}/onlineboard`,
          search: params.toString(),
        });
        return;
      }

      // Schedule-type: build params and navigate to schedule with pre-fill
      const params = buildSchedulePopularRequestQueryParams(request);
      navigate({
        pathname: `/${lang}/schedule`,
        search: params.toString(),
      });
    },
    [navigate, lang],
  );

  const scheduleFilter = (
    <form
      className="schedule-start__form"
      data-testid="schedule-search-form"
      onSubmit={handleSubmit}
    >
      <div className="schedule-start__field">
        <label htmlFor="schedule-departure">{t("SHARED.DEPARTURE_CITY")}</label>
        <AutoComplete
          value={departureAirport}
          suggestions={departureSuggestions}
          completeMethod={handleDepartureSearch}
          field="name"
          dropdown
          onChange={(e) => setDepartureAirport(e.value as CitySuggestion | string)}
          placeholder={t("SHARED.CITY_PLACEHOLDER")}
          className="input--filter"
          inputClassName="input--filter"
          inputId="schedule-departure"
          data-testid="departure-input"
        />
      </div>

      <div className="change-container">
        <button
          className="button-change"
          type="button"
          onClick={() => {
            const tmp = departureAirport;
            setDepartureAirport(arrivalAirport);
            setArrivalAirport(tmp);
          }}
          data-testid="swap-cities-button"
        >
          <svg className="svg--change-city">
            <use xlinkHref="/assets/img/sprite.svg#changeCity" />
          </svg>
        </button>
      </div>

      <div className="schedule-start__field">
        <label htmlFor="schedule-arrival">{t("SHARED.ARRIVAL_CITY")}</label>
        <AutoComplete
          value={arrivalAirport}
          suggestions={arrivalSuggestions}
          completeMethod={handleArrivalSearch}
          field="name"
          dropdown
          onChange={(e) => setArrivalAirport(e.value as CitySuggestion | string)}
          placeholder={t("SHARED.CITY_PLACEHOLDER")}
          className="input--filter"
          inputClassName="input--filter"
          inputId="schedule-arrival"
          data-testid="arrival-input"
        />
      </div>

      <div className="schedule-start__field">
        <label htmlFor="schedule-date-from">{t("SHARED.SCHEDULES_DATE")}</label>
        <Calendar
          value={dateFrom && dateTo ? [dateFrom, dateTo] : null}
          onChange={(e) => {
            const val = e.value as Date[] | null;
            if (val && val.length >= 1) setDateFrom(val[0] ?? null);
            if (val && val.length >= 2) setDateTo(val[1] ?? null);
          }}
          selectionMode="range"
          dateFormat="dd.mm.yy"
          placeholder={`${t("SHARED.DATE_FORMAT")} - ${t("SHARED.DATE_FORMAT")}`}
          showIcon
          className="input--filter"
          inputId="schedule-date-from"
          data-testid="date-range-input"
        />
      </div>

      <div className="wrapper--time-selector full-view" data-testid="time-selector">
        <div className="time-selector__label">{t("SHARED.DEPARTURE_TIME")}</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 className="time-selector__value">
          {minutesToTime(timeRange[0])} — {minutesToTime(timeRange[1])}
        </div>
      </div>

      <div className="schedule-start__field">
        <label>
          <input
            type="checkbox"
            checked={directOnly}
            onChange={(e) => setDirectOnly(e.target.checked)}
            data-testid="direct-only-toggle"
          />
          {t("SHARED.DIRECT_FLIGHT_ONLY")}
        </label>
      </div>

      <div className="schedule-start__field">
        <label>
          <input
            type="checkbox"
            checked={isRoundTrip}
            onChange={(e) => setIsRoundTrip(e.target.checked)}
            data-testid="round-trip-toggle"
          />
          {t("SHARED.RETURN_FLIGHT_VIEW")}
        </label>
      </div>

      {isRoundTrip && (
        <>
          <div className="schedule-start__field">
            <label htmlFor="schedule-return-date-from">{t("SHARED.RETURN_FLIGHT_DATE")}</label>
            <Calendar
              value={returnDateFrom}
              onChange={(e) => setReturnDateFrom(e.value as Date)}
              dateFormat="dd.mm.yy"
              showIcon
              className="input--filter"
              inputId="schedule-return-date-from"
              data-testid="return-date-from-input"
            />
          </div>

          <div className="schedule-start__field">
            <label htmlFor="schedule-return-date-to">{t("SHARED.RETURN_FLIGHT_TIME")}</label>
            <Calendar
              value={returnDateTo}
              onChange={(e) => setReturnDateTo(e.value as Date)}
              dateFormat="dd.mm.yy"
              showIcon
              className="input--filter"
              inputId="schedule-return-date-to"
              data-testid="return-date-to-input"
            />
          </div>

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

      <button
        type="submit"
        className="schedule-start__submit"
        data-testid="schedule-search-submit"
      >
        {t("SHARED.SCHEDULES_VIEW")}
      </button>
    </form>
  );

  return (
    <div className="schedule-start-page" data-testid="schedule-start">
      <PageLayout
        headerLeft={
          <PageTabs viewType="schedule" />
        }
        title={
          <h1 className="text--white page-title">
            {t("SCHEDULE.TITLE")}
          </h1>
        }
        breadcrumbs={[]}
        contentLeft={
          <>
            {scheduleFilter}
            <SearchHistory />
          </>
        }
      >
        <section className="frame">
          <h2>{t("SCHEDULE.SCHEDULE-START")}</h2>

          <div className="titles-container">
            <div className="title title1">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE1")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE1-DESCRIPTION")}
              </div>
            </div>

            <div className="title title2">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE2")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE2-DESCRIPTION")}
              </div>
            </div>

            <div className="title title3">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE3")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE3-DESCRIPTION")}
              </div>
            </div>

            <div className="title title4">
              <a>{t("SCHEDULE.SCHEDULE-START-TITLE4")}</a>
              <div>
                {t("SCHEDULE.SCHEDULE-START-TITLE4-DESCRIPTION")}
              </div>
            </div>
          </div>

          <PopularRequestsPanel onRequestClick={handlePopularRequestClick} />
        </section>

        <section className="frame bottom-description-frame">
          <div className="bottom-description-container">
            <h3 className="bottom-description-title">
              {t("SCHEDULE.SCHEDULE-BOTTOM-DESCRIPTION")}
            </h3>
            <div
              className="bottom-description-text"
              dangerouslySetInnerHTML={{
                __html: t("SCHEDULE.SCHEDULE-BOTTOM-DESCRIPTION-TEXT"),
              }}
            />
          </div>
        </section>
      </PageLayout>
    </div>
  );
};
