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

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

type ContestFromApi = {
  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;

  url?: string | null;
  evaluator?: string | null;
  email?: string | null;
  email2?: string | null;

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

  start_time: string | null;
  duration: number;
  logs_deadline_days: number;
};

type ContestFormMode = "create" | "edit";

type ContestCreateFormProps = {
  mode?: ContestFormMode;           // default "create"
  contest?: ContestFromApi | null;  // pro edit
  onCreated?: (contest: ContestFromApi) => void;
  onUpdated?: (contest: ContestFromApi) => void;
};

type Option = { id: number; name: string; code?: string | null };

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

  // nic nevyplněno → prázdný objekt
  if (!trimmedCs && !trimmedEn) {
    return {};
  }

  // oba jazyky vyplněné → použij obě hodnoty
  if (trimmedCs && trimmedEn) {
    return {
      cs: trimmedCs,
      en: trimmedEn,
    };
  }

  // vyplněný jen jeden jazyk → použij ho pro oba
  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 normalizeStartTime = (time: string): string | undefined => {
  if (!time.trim()) return undefined;
  return time.length === 5 ? `${time}:00` : time;
};

export default function ContestCreateForm({
  mode = "create",
  contest,
  onCreated,
  onUpdated,
}: ContestCreateFormProps) {
  const { t } = useTranslation("common");

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

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

  const [url, setUrl] = useState("");
  const [evaluator, setEvaluator] = useState("");
  const [email, setEmail] = useState("");
  const [email2, setEmail2] = useState("");

  const [startTime, setStartTime] = useState("");
  const [durationHours, setDurationHours] = useState("24");
  const [deadlineDays, setDeadlineDays] = useState("3");

  const [isMcr, setIsMcr] = useState(false);
  const [isSixHr, setIsSixHr] = useState(false);
  const [isActive, setIsActive] = useState(true);

  const [availableBands, setAvailableBands] = useState<Option[]>([]);
  const [availableCategories, setAvailableCategories] = useState<Option[]>([]);
  const [availablePowerCategories, setAvailablePowerCategories] = useState<Option[]>([]);
  const [availableRuleSets, setAvailableRuleSets] = useState<Option[]>([]);
  const [selectedRuleSetId, setSelectedRuleSetId] = useState<number | null>(null);

  const [selectedBandIds, setSelectedBandIds] = useState<number[]>([]);
  const [selectedCategoryIds, setSelectedCategoryIds] = useState<number[]>([]);
  const [selectedPowerCategoryIds, setSelectedPowerCategoryIds] = useState<number[]>([]);

  const [loadingOptions, setLoadingOptions] = useState(false);

  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [submitting, setSubmitting] = useState(false);

  // načti volby pro checkboxy
  useEffect(() => {
    let active = true;

    (async () => {
      try {
        setLoadingOptions(true);
        const [bandsRes, categoriesRes, powerCatsRes, ruleSetsRes] = await Promise.all([
          axios.get<Option[] | { data: Option[] }>("/api/bands", { headers: { Accept: "application/json" } }),
          axios.get<Option[] | { data: Option[] }>("/api/categories", { headers: { Accept: "application/json" } }),
          axios.get<Option[] | { data: Option[] }>("/api/power-categories", { headers: { Accept: "application/json" } }),
          axios.get<Option[] | { data: Option[] }>("/api/evaluation-rule-sets", { headers: { Accept: "application/json" } }),
        ]);

        if (!active) return;

        const normalize = (res: any): Option[] =>
          Array.isArray(res.data ?? res) ? (res.data ?? res) : [];

        setAvailableBands(normalize(bandsRes.data ?? bandsRes));
        setAvailableCategories(normalize(categoriesRes.data ?? categoriesRes));
        setAvailablePowerCategories(normalize(powerCatsRes.data ?? powerCatsRes));
        const normalizedRuleSets = normalize(ruleSetsRes.data ?? ruleSetsRes);
        setAvailableRuleSets(normalizedRuleSets);
        if (!isEdit && !selectedRuleSetId) {
          const defaultRuleSet = normalizedRuleSets.find((item) => item.code === "default_vhf_compat");
          if (defaultRuleSet) {
            setSelectedRuleSetId(defaultRuleSet.id);
          }
        }
      } catch {
        if (!active) return;
        setError("Nepodařilo se načíst seznam pásem/kategorií.");
      } finally {
        if (active) setLoadingOptions(false);
      }
    })();

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

  React.useEffect(() => {
    if (!isEdit || !contest) return;

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

    setNameCs(name.cs ?? "");
    setNameEn(name.en ?? "");
    setDescriptionCs(desc.cs ?? "");
    setDescriptionEn(desc.en ?? "");

    setUrl(contest.url ?? "");
    setEvaluator(contest.evaluator ?? "");
    setEmail(contest.email ?? "");
    setEmail2(contest.email2 ?? "");

    setStartTime(contest.start_time ?? "");
    setDurationHours(String(contest.duration ?? 24));
    setDeadlineDays(String(contest.logs_deadline_days ?? 3));

    setIsMcr(!!contest.is_mcr);
    setIsSixHr(!!contest.is_sixhr);
    setIsActive(!!contest.is_active);

    setSelectedBandIds(contest.bands?.map((b) => b.id) ?? []);
    setSelectedCategoryIds(contest.categories?.map((c) => c.id) ?? []);
    setSelectedPowerCategoryIds(contest.power_categories?.map((p) => p.id) ?? []);
    setSelectedRuleSetId(contest.rule_set_id ?? null);

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

  const triggerRefresh = useContestRefreshStore((s) => s.triggerRefresh);

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

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

    const descriptionPayload = buildTranslationPayload(descriptionCs, descriptionEn);

    const payload: Record<string, unknown> = {
      name: namePayload,
      is_mcr: isMcr,
      is_sixhr: isSixHr,
      is_active: isActive,
    };

    if (Object.keys(descriptionPayload).length > 0) {
      payload.description = descriptionPayload;
    }
    if (url.trim()) payload.url = url.trim();
    if (evaluator.trim()) payload.evaluator = evaluator.trim();
    if (email.trim()) payload.email = email.trim();
    if (email2.trim()) payload.email2 = email2.trim();

    const normalizedStartTime = normalizeStartTime(startTime);
    if (normalizedStartTime) payload.start_time = normalizedStartTime;

    const durationNumber = durationHours.trim() ? Number(durationHours) : undefined;
    const deadlineNumber = deadlineDays.trim() ? Number(deadlineDays) : undefined;

    if (durationNumber !== undefined && Number.isNaN(durationNumber)) {
      setError(t("Délka závodu musí být číslo."));
      return;
    }

    if (deadlineNumber !== undefined && Number.isNaN(deadlineNumber)) {
      setError(t("Uzávěrka logů musí být číslo."));
      return;
    }

    if (durationNumber !== undefined) payload.duration = durationNumber;
    if (deadlineNumber !== undefined) payload.logs_deadline_days = deadlineNumber;

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

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

      let response;

      if (isEdit && contest) {
        response = await axios.put(`/api/contests/${contest.id}`, payload, {
          headers: {
            Accept: "application/json",
          },
          withCredentials: true,
          withXSRFToken: true,
        });

        setSuccess("Závod byl upraven.");
        triggerRefresh();
        onUpdated?.(response.data);
      } else {
        response = await axios.post("/api/contests", payload, {
          headers: {
            Accept: "application/json",
          },
          withCredentials: true,
          withXSRFToken: true,
        });

        setSuccess("Závod byl vytvořen.");
        triggerRefresh();
        onCreated?.(response.data);
      }
    } catch (err) {
      if (axios.isAxiosError(err)) {
        const apiErrors =
          err.response?.data?.errors ??
          err.response?.data?.message ??
          "Nepodařilo se uložit závod.";
        setError(
          typeof apiErrors === "string"
            ? apiErrors
            : "Nepodařilo se uložit závod."
        );
      } else {
        setError("Nepodařilo se uložit závod.");
      }
    } finally {
      setSubmitting(false);
    }
  };

  const toggleId = (id: number, list: number[], setter: (v: number[]) => void) => {
    setter(list.includes(id) ? list.filter((x) => x !== id) : [...list, id]);
  };

  return (
    <form onSubmit={handleSubmit} className="space-y-4">
      <div className="grid gap-4 md:grid-cols-2">
        <Input
          label="Název (cs)"
          placeholder="VKV závod"
          value={nameCs}
          onValueChange={setNameCs}
          isRequired
        />
        <Input
          label="Name (en)"
          placeholder="VHF contest"
          value={nameEn}
          onValueChange={setNameEn}
        />
      </div>

      <div className="grid gap-4 md:grid-cols-2">
        <Textarea
          label="Popis (cs)"
          placeholder="Stručný popis závodu…"
          minRows={2}
          value={descriptionCs}
          onValueChange={setDescriptionCs}
        />
        <Textarea
          label="Description (en)"
          placeholder="Short contest description…"
          minRows={2}
          value={descriptionEn}
          onValueChange={setDescriptionEn}
        />
      </div>

      <div className="grid gap-4 md:grid-cols-4">
        <Input
          label="URL závodu"
          type="url"
          placeholder="https://example.com"
          value={url}
          onValueChange={setUrl}
        />
        <Input
          label="Vyhodnocovatel"
          placeholder="ČRK"
          value={evaluator}
          onValueChange={setEvaluator}
        />
        <Input
          label="Email"
          type="email"
          placeholder="kontakt@domena.cz"
          value={email}
          onValueChange={setEmail}
        />
        <Input
          label="Email 2"
          type="email"
          placeholder="druhy_kontakt@domena.cz"
          value={email2}
          onValueChange={setEmail2}
        />
      </div>

      <div className="grid gap-4 md:grid-cols-3">
        <Input
          label="Start závodu (HH:MM)"
          type="time"
          value={startTime}
          onValueChange={setStartTime}
        />
        <Input
          label="Délka závodu (hodiny)"
          type="number"
          min={1}
          value={durationHours}
          onValueChange={setDurationHours}
        />
        <Input
          label="Uzávěrka logů (dny)"
          type="number"
          min={0}
          value={deadlineDays}
          onValueChange={setDeadlineDays}
        />
      </div>

      <div className="flex flex-wrap gap-6">
        <Switch isSelected={isActive} onValueChange={setIsActive}>
          Závod je aktivní
        </Switch>
        <Switch isSelected={isMcr} onValueChange={setIsMcr}>
          MČR
        </Switch>
        <Switch isSelected={isSixHr} onValueChange={setIsSixHr}>
          6H závod
        </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={() => toggleId(band.id, selectedBandIds, setSelectedBandIds)}
                  disabled={loadingOptions || 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={() => toggleId(cat.id, selectedCategoryIds, setSelectedCategoryIds)}
                  disabled={loadingOptions || 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={() => toggleId(p.id, selectedPowerCategoryIds, setSelectedPowerCategoryIds)}
                  disabled={loadingOptions || 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={loadingOptions || 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 && <p className="text-sm text-red-600">{error}</p>}
      {success && <p className="text-sm text-green-600">{success}</p>}

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