import React, { useEffect, useMemo, useState } from "react";
import axios from "axios";
import { Button, Input, Switch, Textarea } from "@heroui/react";
import { useTranslation } from "react-i18next";
import { useLanguageStore } from "@/stores/languageStore";

type TranslationPayload = {
  cs?: string;
  en?: string;
};

type ContestOption = {
  id: number;
  name: string | TranslationPayload;
  bands?: { id: number; name: string }[];
  categories?: { id: number; name: string }[];
  power_categories?: { id: number; name: string }[];
  rule_set_id?: number | null;
  duration?: number;
  logs_deadline_days?: number;
};

export type RoundFromApi = {
  id: number;
  contest_id: number;
  name: string | TranslationPayload;
  description?: string | TranslationPayload | null;
  bands?: { id: number; name: string }[];
  categories?: { id: number; name: string }[];
  power_categories?: { id: number; name: string }[];
  rule_set_id?: number | null;

  is_active: boolean;
  is_test: boolean;
  is_sixhr: boolean;

  start_time: string | null;
  end_time: string | null;
  logs_deadline: string | null;
};

type RoundFormMode = "create" | "edit";

type RoundCreateFormProps = {
  mode?: RoundFormMode;          // default "create"
  round?: RoundFromApi | null;   // pro edit
  onCreated?: (round: RoundFromApi) => void;
  onUpdated?: (round: RoundFromApi) => void;
  contestId?: number | null;
};

const buildTranslationPayload = (cs: string, en: string): TranslationPayload => {
  const trimmedCs = cs.trim();
  const trimmedEn = en.trim();

  if (!trimmedCs && !trimmedEn) {
    return {};
  }

  if (trimmedCs && trimmedEn) {
    return {
      cs: trimmedCs,
      en: trimmedEn,
    };
  }

  const value = trimmedCs || trimmedEn;
  return {
    cs: value,
    en: value,
  };
};

const extractTranslations = (
  field: string | TranslationPayload | null | undefined
): TranslationPayload => {
  if (!field) return {};
  if (typeof field === "string") return { cs: field };
  return field;
};

const toDatetimeLocal = (value: string | null): string => {
  if (!value) return "";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return value;
  const pad = (n: number) => `${n}`.padStart(2, "0");
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
};

const normalizeDatetime = (value: string): string | undefined => {
  if (!value.trim()) return undefined;
  return value;
};

const isSixHourBandName = (name?: string | null) => {
  if (!name) return false;
  const lower = name.toLowerCase();
  return lower.includes("145") || lower.includes("435");
};

export default function RoundCreateForm({
  mode = "create",
  round,
  onCreated,
  onUpdated,
  contestId: forcedContestId = null,
}: RoundCreateFormProps) {
  const { t } = useTranslation("common");
  const locale = useLanguageStore((s) => s.locale);

  const isEdit = mode === "edit" && round != null;

  const [contestId, setContestId] = useState<string>(forcedContestId ? String(forcedContestId) : "");
  const [contests, setContests] = useState<ContestOption[]>([]);
  const [loadingContests, setLoadingContests] = useState(false);

  const [nameCs, setNameCs] = useState("");
  const [nameEn, setNameEn] = useState("");
  const [descriptionCs, setDescriptionCs] = useState("");
  const [descriptionEn, setDescriptionEn] = useState("");

  const [startTime, setStartTime] = useState("");
  const [endTime, setEndTime] = useState("");
  const [logsDeadline, setLogsDeadline] = useState("");
  const [contestDurationHours, setContestDurationHours] = useState<number | null>(null);
  const [contestDeadlineDays, setContestDeadlineDays] = useState<number | null>(null);

  const [isActive, setIsActive] = useState(true);
  const [isTest, setIsTest] = useState(false);
  const [isSixHr, setIsSixHr] = useState(false);

  const [availableBands, setAvailableBands] = useState<ContestOption["bands"]>([]);
  const [availableCategories, setAvailableCategories] = useState<ContestOption["categories"]>([]);
  const [availablePowerCategories, setAvailablePowerCategories] = useState<ContestOption["power_categories"]>([]);

  const [selectedBandIds, setSelectedBandIds] = useState<number[]>([]);
  const [selectedCategoryIds, setSelectedCategoryIds] = useState<number[]>([]);
  const [selectedPowerCategoryIds, setSelectedPowerCategoryIds] = useState<number[]>([]);
  const [availableRuleSets, setAvailableRuleSets] = useState<{ id: number; name: string; code?: string | null }[]>([]);
  const [selectedRuleSetId, setSelectedRuleSetId] = useState<number | null>(null);

  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const hasAllowedSixHrBand = useMemo(() => {
    if (!selectedBandIds.length) return false;
    return availableBands.some((b) => selectedBandIds.includes(b.id) && isSixHourBandName(b.name));
  }, [availableBands, selectedBandIds]);

  // načti seznam závodů pro select
  useEffect(() => {
    let active = true;
    (async () => {
      try {
        setLoadingContests(true);
        const [contestsRes, bandsRes, categoriesRes, powerCatsRes, ruleSetsRes] = await Promise.all([
          axios.get<ContestOption[] | { data: ContestOption[] }>("/api/contests", {
            withCredentials: true,
            headers: { Accept: "application/json" },
            params: { lang: locale },
          }),
          axios.get("/api/bands", { headers: { Accept: "application/json" } }),
          axios.get("/api/categories", { headers: { Accept: "application/json" } }),
          axios.get("/api/power-categories", { headers: { Accept: "application/json" } }),
          axios.get("/api/evaluation-rule-sets", { headers: { Accept: "application/json" } }),
        ]);
        if (!active) return;
        const normalize = (res: any) => (Array.isArray(res?.data) ? res.data : res?.data?.data ?? res.data ?? []);
        setContests(normalize(contestsRes));
        setAvailableBands(normalize(bandsRes));
        setAvailableCategories(normalize(categoriesRes));
        setAvailablePowerCategories(normalize(powerCatsRes));
        const ruleSets = normalize(ruleSetsRes);
        setAvailableRuleSets(ruleSets);
        if (!isEdit && !selectedRuleSetId) {
          const defaultRuleSet = ruleSets.find((item: any) => item.code === "default_vhf_compat");
          if (defaultRuleSet) {
            setSelectedRuleSetId(defaultRuleSet.id);
          }
        }
      } catch {
        if (!active) return;
        setError(t("unable_to_load_contests") ?? "Nepodařilo se načíst seznam závodů.");
      } finally {
        if (active) setLoadingContests(false);
      }
    })();
    return () => {
      active = false;
    };
  }, [locale, t]);

  // předvyplnění při editaci
  useEffect(() => {
    if (!isEdit || !round) return;

    const name = extractTranslations(round.name);
    const desc = extractTranslations(round.description ?? null);

    setContestId(String(round.contest_id ?? ""));
    setNameCs(name.cs ?? "");
    setNameEn(name.en ?? "");
    setDescriptionCs(desc.cs ?? "");
    setDescriptionEn(desc.en ?? "");

    setStartTime(toDatetimeLocal(round.start_time));
    setEndTime(toDatetimeLocal(round.end_time));
    setLogsDeadline(toDatetimeLocal(round.logs_deadline));

    setIsActive(!!round.is_active);
    setIsTest(!!round.is_test);
    setIsSixHr(!!round.is_sixhr);

    setSelectedBandIds(Array.isArray((round as any).bands) ? (round as any).bands.map((b: any) => b.id) : []);
    setSelectedCategoryIds(Array.isArray((round as any).categories) ? (round as any).categories.map((c: any) => c.id) : []);
    setSelectedPowerCategoryIds(Array.isArray((round as any).power_categories) ? (round as any).power_categories.map((p: any) => p.id) : []);
    setSelectedRuleSetId((round as any).rule_set_id ?? null);

    setError(null);
    setSuccess(null);
  }, [isEdit, round]);

  // pokud při editaci chybí vazby, doťukej detail kola
  useEffect(() => {
    if (!isEdit || !round) return;
    const needsDetail =
      !(Array.isArray((round as any).bands) && (round as any).bands.length) ||
      !(Array.isArray((round as any).categories) && (round as any).categories.length) ||
      !(Array.isArray((round as any).power_categories) && (round as any).power_categories.length);
    if (!needsDetail) return;

    let active = true;
    (async () => {
      try {
        const res = await axios.get(`/api/rounds/${round.id}`, {
          headers: { Accept: "application/json" },
          params: { lang: locale },
          withCredentials: true,
        });
        if (!active) return;
        const data = res.data;
        setSelectedBandIds(Array.isArray(data.bands) ? data.bands.map((b: any) => b.id) : []);
        setSelectedCategoryIds(Array.isArray(data.categories) ? data.categories.map((c: any) => c.id) : []);
        setSelectedPowerCategoryIds(Array.isArray(data.power_categories) ? data.power_categories.map((p: any) => p.id) : []);

        setIsActive(!!data.is_active);
        setIsTest(!!data.is_test);
        setIsSixHr(!!data.is_sixhr);
        setStartTime(toDatetimeLocal(data.start_time));
        setEndTime(toDatetimeLocal(data.end_time));
        setLogsDeadline(toDatetimeLocal(data.logs_deadline));
      } catch {
        // ignore
      }
    })();

    return () => { active = false; };
  }, [isEdit, round, locale]);

  // pokud máme zvolený contest, načti detail pro defaulty (vazby) a parametry
  useEffect(() => {
    if (!contestId) return;

    let active = true;
    (async () => {
      try {
        const res = await axios.get<ContestOption>(`/api/contests/${contestId}`, {
          headers: { Accept: "application/json" },
          params: { lang: locale },
          withCredentials: true,
        });
        if (!active) return;
        const data = res.data;
        if (!isEdit) {
          if (data?.bands) setSelectedBandIds(data.bands.map((b) => b.id));
          if (data?.categories) setSelectedCategoryIds(data.categories.map((c) => c.id));
          if (data?.power_categories) setSelectedPowerCategoryIds(data.power_categories.map((p) => p.id));
          if (data?.rule_set_id) setSelectedRuleSetId(data.rule_set_id);
        }
        if (typeof data.duration === "number") setContestDurationHours(data.duration);
        if (typeof data.logs_deadline_days === "number") setContestDeadlineDays(data.logs_deadline_days);
      } catch {
        // ignore
      }
    })();

    return () => { active = false; };
  }, [contestId, locale, isEdit]);

  // Auto-nastavení konce kola podle startu a délky závodu
  useEffect(() => {
    if (!startTime || endTime || contestDurationHours == null) return;
    const startDate = new Date(startTime);
    if (Number.isNaN(startDate.getTime())) return;
    const endDate = new Date(startDate);
    endDate.setHours(endDate.getHours() + contestDurationHours);
    setEndTime(toDatetimeLocal(endDate.toISOString()));
  }, [startTime, endTime, contestDurationHours]);

  // Auto-nastavení uzávěrky logů při vyplnění/změně konce
  useEffect(() => {
    if (!endTime || contestDeadlineDays == null) return;
    const endDate = new Date(endTime);
    if (Number.isNaN(endDate.getTime())) return;
    const deadlineDate = new Date(endDate);
    deadlineDate.setDate(deadlineDate.getDate() + contestDeadlineDays);
    setLogsDeadline(toDatetimeLocal(deadlineDate.toISOString()));
  }, [endTime, contestDeadlineDays]);

  useEffect(() => {
    if (isSixHr && !hasAllowedSixHrBand) {
      setIsSixHr(false);
    }
  }, [hasAllowedSixHrBand, isSixHr]);

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setError(null);
    setSuccess(null);

    if (!contestId.trim()) {
      setError(t("Vyber závod.") ?? "Vyber závod.");
      return;
    }

    const namePayload = buildTranslationPayload(nameCs, nameEn);
    if (Object.keys(namePayload).length === 0) {
      setError(t("Vyplň alespoň jeden překlad názvu kola.") ?? "Vyplň alespoň jeden překlad názvu kola.");
      return;
    }

    const descriptionPayload = buildTranslationPayload(descriptionCs, descriptionEn);

  const payload: Record<string, unknown> = {
    contest_id: Number(contestId),
    name: namePayload,
    is_active: isActive,
    is_test: isTest,
    is_sixhr: isSixHr,
    };

  if (Object.keys(descriptionPayload).length > 0) {
    payload.description = descriptionPayload;
  }

    const normalizedStart = normalizeDatetime(startTime);
    const normalizedEnd = normalizeDatetime(endTime);
    const normalizedDeadline = normalizeDatetime(logsDeadline);

    if (normalizedStart) payload.start_time = normalizedStart;
    if (normalizedEnd) payload.end_time = normalizedEnd;
    if (normalizedDeadline) payload.logs_deadline = normalizedDeadline;

  payload.band_ids = selectedBandIds;
  payload.category_ids = selectedCategoryIds;
  payload.power_category_ids = selectedPowerCategoryIds;
  if (selectedRuleSetId) payload.rule_set_id = selectedRuleSetId;

  if (isSixHr && !hasAllowedSixHrBand) {
    payload.is_sixhr = false;
    setIsSixHr(false);
    setError(t("six_hr_band_warning") ?? "6H kategorie je povolena jen pro pásma 145 MHz a 435 MHz.");
  }

    // 6h jen pro pásma 145 / 435 – pokud nesplňuje, vypni is_sixhr
    if (isSixHr) {
      const bands = (round as any)?.bands ?? [];
      const currentBands = (bands.length ? bands.map((b: any) => b.id) : selectedBandIds) ?? [];
      const hasAllowedBand = (round as any)?.bands
        ? bands.some((b: any) => isSixHourBandName(b.name))
        : selectedBandIds.some((id) => {
            const found = (round as any)?.availableBands?.find?.((b: any) => b.id === id);
            return found ? isSixHourBandName(found.name) : true;
          });
      if (!hasAllowedBand) {
        payload.is_sixhr = false;
        setIsSixHr(false);
      }
    }

    try {
      setSubmitting(true);
      await axios.get("/sanctum/csrf-cookie", { withCredentials: true });

      let response;

      if (isEdit && round) {
        response = await axios.put(`/api/rounds/${round.id}`, payload, {
          headers: { Accept: "application/json" },
          withCredentials: true,
          withXSRFToken: true,
        });
        setSuccess(t("Kolo bylo upraveno.") ?? "Kolo bylo upraveno.");
        onUpdated?.(response.data as RoundFromApi);
      } else {
        response = await axios.post("/api/rounds", payload, {
          headers: { Accept: "application/json" },
          withCredentials: true,
          withXSRFToken: true,
        });
        setSuccess(t("Kolo bylo vytvořeno.") ?? "Kolo bylo vytvořeno.");
        onCreated?.(response.data as RoundFromApi);
        // reset formuláře po vytvoření
        setNameCs("");
        setNameEn("");
        setDescriptionCs("");
        setDescriptionEn("");
        setStartTime("");
        setEndTime("");
        setLogsDeadline("");
        setIsActive(true);
        setIsTest(false);
        setIsSixHr(false);
      }
    } catch (e: any) {
      if (axios.isAxiosError(e)) {
        setError(e.response?.data?.message ?? "Chyba při ukládání kola.");
      } else {
        setError("Chyba při ukládání kola.");
      }
    } finally {
      setSubmitting(false);
    }
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div className="space-y-2">
        <label className="text-sm font-medium">
          {t("contest_name") ?? "Závod"}
        </label>
        <select
          value={contestId}
          onChange={(e) => setContestId(e.target.value)}
          disabled={loadingContests || submitting || !!forcedContestId || isEdit}
          className="w-full border rounded px-3 py-2 text-sm bg-white dark:bg-gray-900"
          required
        >
          <option value="">{t("Vyber závod") ?? "Vyber závod"}</option>
          {contests.map((c) => (
            <option key={c.id} value={c.id}>
              {typeof c.name === "string" ? c.name : c.name[locale] ?? c.name["en"] ?? c.name["cs"] ?? c.id}
            </option>
          ))}
        </select>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
        <Input
          label={t("round_name") ?? "Název (cs)"}
          labelPlacement="outside"
          placeholder="Kolo (cs)"
          value={nameCs}
          onChange={(e) => setNameCs(e.target.value)}
          isRequired
        />
        <Input
          label={t("round_name") ?? "Název (en)"}
          labelPlacement="outside"
          placeholder="Round (en)"
          value={nameEn}
          onChange={(e) => setNameEn(e.target.value)}
        />
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
        <Textarea
          label={t("round_description") ?? "Popis (cs)"}
          labelPlacement="outside"
          placeholder="Popis kola (cs)"
          value={descriptionCs}
          onChange={(e) => setDescriptionCs(e.target.value)}
          minRows={2}
        />
        <Textarea
          label={t("round_description") ?? "Popis (en)"}
          labelPlacement="outside"
          placeholder="Round description (en)"
          value={descriptionEn}
          onChange={(e) => setDescriptionEn(e.target.value)}
          minRows={2}
        />
      </div>

      <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
        <Input
          type="datetime-local"
          label={t("Začátek") ?? "Začátek"}
          labelPlacement="outside-left"
          value={startTime}
          onChange={(e) => setStartTime(e.target.value)}
          isRequired
        />
        <Input
          type="datetime-local"
          label={t("Konec") ?? "Konec"}
          labelPlacement="outside-left"
          value={endTime}
          onChange={(e) => setEndTime(e.target.value)}
          isRequired
        />
        <Input
          type="datetime-local"
          label={t("Uzávěrka logů") ?? "Uzávěrka logů"}
          labelPlacement="outside-left"
          value={logsDeadline}
          onChange={(e) => setLogsDeadline(e.target.value)}
        />
      </div>

      <div className="flex flex-wrap gap-4">
        <Switch
          isSelected={isActive}
          onValueChange={setIsActive}
        >
          {t("round_active") ?? "Aktivní"}
        </Switch>
        <Switch
          isSelected={isTest}
          onValueChange={setIsTest}
        >
          {t("round_test") ?? "Testovací"}
        </Switch>
        <Switch
          isSelected={isSixHr}
          onValueChange={setIsSixHr}
          isDisabled={!hasAllowedSixHrBand}
        >
          6h
        </Switch>
      </div>

      <div className="grid gap-6 md:grid-cols-3">
        <div>
          <p className="text-sm font-semibold mb-2">Pásma</p>
          <div className="space-y-2">
            {availableBands?.map((band) => (
              <label key={band.id} className="flex items-center gap-2 text-sm">
                <input
                  type="checkbox"
                  checked={selectedBandIds.includes(band.id)}
                  onChange={() =>
                    setSelectedBandIds((prev) =>
                      prev.includes(band.id) ? prev.filter((id) => id !== band.id) : [...prev, band.id]
                    )
                  }
                  disabled={loadingContests || submitting}
                />
                <span>{band.name}</span>
              </label>
            ))}
          </div>
        </div>

        <div>
          <p className="text-sm font-semibold mb-2">Kategorie</p>
          <div className="space-y-2">
            {availableCategories?.map((cat) => (
              <label key={cat.id} className="flex items-center gap-2 text-sm">
                <input
                  type="checkbox"
                  checked={selectedCategoryIds.includes(cat.id)}
                  onChange={() =>
                    setSelectedCategoryIds((prev) =>
                      prev.includes(cat.id) ? prev.filter((id) => id !== cat.id) : [...prev, cat.id]
                    )
                  }
                  disabled={loadingContests || submitting}
                />
                <span>{cat.name}</span>
              </label>
            ))}
          </div>
        </div>

        <div>
          <p className="text-sm font-semibold mb-2">Výkonové kategorie</p>
          <div className="space-y-2">
            {availablePowerCategories?.map((p) => (
              <label key={p.id} className="flex items-center gap-2 text-sm">
                <input
                  type="checkbox"
                  checked={selectedPowerCategoryIds.includes(p.id)}
                  onChange={() =>
                    setSelectedPowerCategoryIds((prev) =>
                      prev.includes(p.id) ? prev.filter((id) => id !== p.id) : [...prev, p.id]
                    )
                  }
                  disabled={loadingContests || submitting}
                />
                <span>{p.name}</span>
              </label>
            ))}
          </div>
        </div>
        <div>
          <p className="text-sm font-semibold mb-2">Ruleset</p>
          <select
            value={selectedRuleSetId ?? ""}
            onChange={(e) => setSelectedRuleSetId(e.target.value ? Number(e.target.value) : null)}
            disabled={loadingContests || submitting}
            className="w-full border rounded px-3 py-2 text-sm bg-white dark:bg-gray-900"
          >
            <option value="">--</option>
            {availableRuleSets.map((ruleSet) => (
              <option key={ruleSet.id} value={ruleSet.id}>
                {ruleSet.name}
              </option>
            ))}
          </select>
        </div>
      </div>

      {error && <div className="text-sm text-red-600">{error}</div>}
      {success && <div className="text-sm text-green-600">{success}</div>}

      <div className="flex gap-3">
        <Button type="submit" color="primary" isLoading={submitting}>
          {isEdit ? t("Uložit změny") ?? "Uložit změny" : t("Vytvořit kolo") ?? "Vytvořit kolo"}
        </Button>
      </div>
    </form>
  );
}
