import { useEffect, useMemo, useState } from "react";
import axios from "axios";
import { Select, SelectItem, type Selection } from "@heroui/react";
import { useTranslation } from "react-i18next";
import { useLanguageStore } from "@/stores/languageStore";
import { useContestStore, type ContestSummary } from "@/stores/contestStore";
import { useContestRefreshStore } from "@/stores/contestRefreshStore";
import { useNavigate } from "react-router-dom";

type ContestItem = ContestSummary & {
  description?: string | null;
  bands?: { id: number; name: string }[];
};

type PaginatedResponse<T> = {
  data: T[];
};

type ContestsSelectBoxProps = {
  /** Zobraz pouze aktivní závody (is_active === true). Default: false */
  onlyActive?: boolean;
  /** Label pro Select, volitelné */
  label?: string;
  /** Placeholder text */
  placeholder?: string;
};

export default function ContestsSelectBox({
  onlyActive = false,
  label,
  placeholder,
}: ContestsSelectBoxProps) {
  const { t } = useTranslation("common");
  const locale = useLanguageStore((s) => s.locale);
  const refreshKey = useContestRefreshStore((s) => s.refreshKey);
  const navigate = useNavigate();

  const [items, setItems] = useState<ContestItem[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set(["none"]));

  const setSelectedContest = useContestStore((s) => s.setSelectedContest);
  const selectedContest = useContestStore((s) => s.selectedContest);

  // předvyplň výběr podle storu
  useEffect(() => {
    if (selectedContest) {
      setSelectedKeys(new Set([String(selectedContest.id)]));
    } else {
      setSelectedKeys(new Set(["none"]));
    }
  }, [selectedContest]);

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

    (async () => {
      try {
        setLoading(true);
        setError(null);

        const res = await axios.get<PaginatedResponse<ContestItem> | ContestItem[]>(
          "/api/contests",
          {
            withCredentials: true,
            headers: { Accept: "application/json" },
            params: { lang: locale },
          }
        );

        if (!active) return;

        const data = Array.isArray(res.data)
          ? res.data
          : (res.data as PaginatedResponse<ContestItem>).data;

        setItems(data);
      } catch {
        if (!active) return;
        setError(t("unable_to_load_contests") ?? "Nepodařilo se načíst seznam závodů.");
      } finally {
        if (active) setLoading(false);
      }
    })();

    return () => {
      active = false;
    };
  }, [locale, t, refreshKey]);

  const visibleItems = useMemo(
    () => (onlyActive ? items.filter((c) => c.is_active) : items),
    [items, onlyActive]
  );

  const handleSelectionChange = (keys: Selection) => {
    setSelectedKeys(keys);
    if (keys === "all") return;

    const id = Array.from(keys)[0];
    if (!id || id === "none") {
      if (selectedContest) {
        setSelectedContest(null);
        navigate("/contests");
      }
      return;
    }

    if (selectedContest && String(selectedContest.id) === String(id)) {
      return;
    }

    const selected = visibleItems.find((c) => String(c.id) === String(id));
    if (selected) {
      setSelectedContest(selected);
      navigate(`/contests/${selected.id}`);
    }
  };

  if (loading) return <div>{t("contests_loading") ?? "Načítám závody…"}</div>;
  if (error) return <div className="text-sm text-red-600">{error}</div>;
  if (visibleItems.length === 0) {
    return <div>{t("contests_empty") ?? "Žádné závody nejsou k dispozici."}</div>;
  }

  return (
    <Select
      aria-label="Contests select"
      label={label ?? t("contest_name") ?? "Závod"}
      placeholder={placeholder ?? t("select_contest") ?? "Vyber závod"}
      selectedKeys={selectedKeys}
      onSelectionChange={handleSelectionChange}
      color="primary"
      isMultiline={true}
    >
      <SelectItem key="none" textValue="None">
        {t("select_none") ?? "Žádný závod"}
      </SelectItem>
      {visibleItems.map((item) => (
        <SelectItem
          key={item.id}
          textValue={item.name}
          description={
            <>
              <div>{item.description || "—"}</div>
              <div className="text-[11px] text-foreground-500">
                {(item.bands ?? []).map((b) => b.name).join(", ") || "—"}
              </div>
            </>
          }
        >
          {item.name}
        </SelectItem>
      ))}
    </Select>
  );
}
