import { useEffect, useMemo, useState } from "react";
import { Link } from "react-router-dom";
import type { Race, RacesQuery } from "../api";
import { ApiError, getRaces } from "../api";
import {
  formatDistance,
  formatRaceDate,
  getRaceStatusClassName,
  getRaceStatusLabel,
  splitRacesByDate,
} from "../lib";

const MONTH_OPTIONS: { value: string; label: string }[] = [
  { value: "", label: "Все месяцы" },
  { value: "1", label: "Январь" },
  { value: "2", label: "Февраль" },
  { value: "3", label: "Март" },
  { value: "4", label: "Апрель" },
  { value: "5", label: "Май" },
  { value: "6", label: "Июнь" },
  { value: "7", label: "Июль" },
  { value: "8", label: "Август" },
  { value: "9", label: "Сентябрь" },
  { value: "10", label: "Октябрь" },
  { value: "11", label: "Ноябрь" },
  { value: "12", label: "Декабрь" },
];

function yearSelectOptions(): number[] {
  const current = new Date().getFullYear();
  const start = current - 2;
  const end = current + 4;
  const years: number[] = [];
  for (let y = start; y <= end; y += 1) {
    years.push(y);
  }
  return years;
}

function getErrorMessage(error: unknown): string {
  if (error instanceof ApiError) {
    return error.message;
  }
  return "Не удалось загрузить календарь стартов.";
}

function RaceList(props: { title: string; races: Race[] }): JSX.Element {
  const { title, races } = props;

  return (
    <section className="race-list" aria-label={title}>
      <h2 className="race-list__title">{title}</h2>
      {races.length > 0 ? (
        <ul className="race-list__items">
          {races.map((race) => (
            <li key={race.id} className="race-card">
              <div className="race-card__main">
                <p className="race-card__title">
                  <Link className="race-card__link" to={`/races/${race.id}`}>
                    {race.title}
                  </Link>
                </p>
                <p className="race-card__meta">
                  {formatRaceDate(race.date)} · {formatDistance(race.distanceKm)}
                </p>
              </div>
              <span className={getRaceStatusClassName(race.status)}>{getRaceStatusLabel(race.status)}</span>
            </li>
          ))}
        </ul>
      ) : (
        <p className="race-list__empty">Пока нет данных в этом разделе.</p>
      )}
    </section>
  );
}

export function RacesPage(): JSX.Element {
  const [races, setRaces] = useState<Race[]>([]);
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [yearFilter, setYearFilter] = useState<string>("");
  const [monthFilter, setMonthFilter] = useState<string>("");

  const listQuery = useMemo((): RacesQuery | undefined => {
    const q: RacesQuery = {};
    if (yearFilter !== "") {
      const y = parseInt(yearFilter, 10);
      if (!Number.isNaN(y)) {
        q.year = y;
      }
    }
    if (monthFilter !== "") {
      const m = parseInt(monthFilter, 10);
      if (!Number.isNaN(m)) {
        q.month = m;
      }
    }
    return Object.keys(q).length > 0 ? q : undefined;
  }, [yearFilter, monthFilter]);

  useEffect(() => {
    let isMounted = true;

    async function loadRaces(): Promise<void> {
      setIsLoading(true);
      try {
        const items = await getRaces(listQuery);
        if (!isMounted) {
          return;
        }
        setRaces(items);
        setErrorMessage(null);
      } catch (error) {
        if (!isMounted) {
          return;
        }
        setErrorMessage(getErrorMessage(error));
      } finally {
        if (isMounted) {
          setIsLoading(false);
        }
      }
    }

    void loadRaces();
    return () => {
      isMounted = false;
    };
  }, [listQuery]);

  const { upcoming, past } = useMemo(() => splitRacesByDate(races), [races]);

  if (errorMessage && races.length === 0 && !isLoading) {
    return (
      <section className="page page--races" role="alert">
        <h1 className="page__title">Календарь стартов</h1>
        <p className="page__subtitle page__subtitle--error">{errorMessage}</p>
      </section>
    );
  }

  return (
    <section className="page page--races">
      <h1 className="page__title">Календарь стартов</h1>
      <p className="page__subtitle">Будущие и прошедшие старты в одном месте.</p>

      {errorMessage && !isLoading ? (
        <p className="page__subtitle page__subtitle--error" role="alert" style={{ marginTop: "var(--space-4)" }}>
          {errorMessage}
        </p>
      ) : null}

      <div className="races-filter" role="search" aria-label="Фильтр по дате">
        <label className="races-filter__field">
          <span className="races-filter__label">Год</span>
          <select
            className="races-filter__select"
            value={yearFilter}
            onChange={(event) => {
              setYearFilter(event.target.value);
            }}
          >
            <option value="">Все года</option>
            {yearSelectOptions().map((y) => (
              <option key={y} value={String(y)}>
                {y}
              </option>
            ))}
          </select>
        </label>
        <label className="races-filter__field">
          <span className="races-filter__label">Месяц</span>
          <select
            className="races-filter__select"
            value={monthFilter}
            onChange={(event) => {
              setMonthFilter(event.target.value);
            }}
          >
            {MONTH_OPTIONS.map((opt) => (
              <option key={opt.value || "all"} value={opt.value}>
                {opt.label}
              </option>
            ))}
          </select>
        </label>
      </div>

      {isLoading ? (
        <p className="page__subtitle" aria-busy="true">
          Загружаем данные...
        </p>
      ) : null}

      <div className="race-lists">
        <RaceList title="Будущие" races={upcoming} />
        <RaceList title="Прошедшие" races={past} />
      </div>
    </section>
  );
}
