import { useEffect, useMemo, useState } from "react";
import axios from "axios";
import { Card, CardBody, Listbox, ListboxItem, type Selection } from "@heroui/react";
import { useTranslation } from "react-i18next";
import { useLanguageStore } from "@/stores/languageStore";
import { useContestStore, type RoundSummary } from "@/stores/contestStore";
import { useContestRefreshStore } from "@/stores/contestRefreshStore";
import { useNavigate } from "react-router-dom";

type RoundItem = RoundSummary & {
  contest_id: number;
  description?: string | Record<string, string> | null;
};

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

type RoundsOverviewProps = {
  contestId: number | null;
  onlyActive?: boolean;
  showTests?: boolean;
  className?: string;
  roundsFromStore?: RoundSummary[] | null;
};

const resolveTranslation = (field: any, locale: string): string => {
  if (!field) return "";
  if (typeof field === "string") return field;
  if (typeof field === "object") {
    if (field[locale]) return field[locale];
    if (field["en"]) return field["en"];
    const first = Object.values(field)[0];
    return typeof first === "string" ? first : "";
  }
  return String(field);
};

export default function RoundsOverview({
  contestId,
  onlyActive = false,
  showTests = false,
  className,
  roundsFromStore = null,
}: RoundsOverviewProps) {
  const { t } = useTranslation("common");
  const locale = useLanguageStore((s) => s.locale);
  const refreshKey = useContestRefreshStore((s) => s.refreshKey);
  const navigate = useNavigate();

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

  const setSelectedRound = useContestStore((s) => s.setSelectedRound);
  const selectedRound = useContestStore((s) => s.selectedRound);

  // sync selection with store
  useEffect(() => {
    if (selectedRound) {
      setSelectedKeys(new Set([String(selectedRound.id)]));
    } else {
      setSelectedKeys(new Set([]));
    }
  }, [selectedRound]);

  useEffect(() => {
    // pokud máme roundsFromStore s daty, použij je a nefetchuj
    if (roundsFromStore && roundsFromStore.length > 0) {
      setItems(roundsFromStore);
      setLoading(false);
      setError(null);
      return;
    }

    if (!contestId) {
      setItems([]);
      setLoading(false);
      setError(null);
      return;
    }

    let active = true;

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

        const res = await axios.get<PaginatedResponse<RoundItem> | RoundItem[]>(
          "/api/rounds",
          {
            withCredentials: true,
            headers: { Accept: "application/json" },
            params: {
              lang: locale,
              contest_id: contestId,
              only_active: onlyActive ? 1 : 0,
              include_tests: showTests ? 1 : 0,
            },
          }
        );

        if (!active) return;

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

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

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

  const visibleItems = useMemo(() => items, [items]);

  const isSelected = (id: string | number) => {
    if (selectedKeys === "all") return false;
    return Array.from(selectedKeys).some((k) => String(k) === String(id));
  };

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

    const id = Array.from(keys)[0];
    if (!id) {
      if (selectedRound) {
        setSelectedRound(null);
        if (contestId != null) navigate(`/contests/${contestId}`);
      }
      return;
    }

    if (selectedRound && String(selectedRound.id) === String(id)) return;

    const selected = visibleItems.find((r) => String(r.id) === String(id));
    if (selected) {
      setSelectedRound(selected);
      navigate(`/contests/${selected.contest_id}/rounds/${selected.id}`);
    }
  };

  return (
    <Card className={className}>
      <CardBody className="p-0">
        {loading ? (
          <div className="p-4">{t("rounds_loading") ?? "Načítám kola…"}</div>
        ) : error ? (
          <div className="p-4 text-sm text-red-600">{error}</div>
        ) : visibleItems.length === 0 ? (
          <div className="p-4">{t("rounds_empty") ?? "Žádná kola nejsou k dispozici."}</div>
        ) : (
          <Listbox
            aria-label="Rounds overview"
            selectionMode="single"
            selectedKeys={selectedKeys}
            onSelectionChange={handleSelectionChange}
            variant="flat"
          >
            {visibleItems.map((item) => (
              <ListboxItem key={item.id} textValue={resolveTranslation(item.name, locale)}>
                <div className="flex flex-col">
                  <span
                    className={`text-sm ${
                      isSelected(item.id) ? "font-semibold text-primary" : "font-medium"
                    }`}
                  >
                    {resolveTranslation(item.name, locale)}
                  </span>
                  <span
                    className={`text-xs line-clamp-2 ${
                      isSelected(item.id) ? "text-primary-500" : "text-foreground-500"
                    }`}
                  >
                    {resolveTranslation(item.description ?? null, locale) || "—"}
                  </span>
                </div>
              </ListboxItem>
            ))}
          </Listbox>
        )}
      </CardBody>
    </Card>
  );
}
