"use client";

import { useEffect, useMemo, useState } from "react";

type Category = "organizacja" | "bezpieczenstwo" | "koszty" | "inne";

const categoryLabel: Record<Category, string> = {
  organizacja: "Organizacja",
  bezpieczenstwo: "Bezpieczeństwo",
  koszty: "Koszty",
  inne: "Inne",
};

type Summary = {
  total: number;
  counts: Record<Category, number>;
};

export default function StanowiskoBox({
  consultationId,
}: {
  consultationId: string;
}) {
  const [text, setText] = useState("");
  const [category, setCategory] = useState<Category>("organizacja");
  const [msg, setMsg] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const [loading, setLoading] = useState(true);
  const [summary, setSummary] = useState<Summary>({
    total: 0,
    counts: { organizacja: 0, bezpieczenstwo: 0, koszty: 0, inne: 0 },
  });

  const remaining = useMemo(() => 300 - text.length, [text]);

  const max = useMemo(() => {
    return Math.max(1, ...Object.values(summary.counts));
  }, [summary]);

  async function refresh() {
    setLoading(true);
    try {
      const res = await fetch(
        `/api/stanowiska?consultationId=${encodeURIComponent(consultationId)}`
      );
      const data = await res.json();

      if (!res.ok || !data?.ok) {
        throw new Error(data?.message || "Błąd pobierania podsumowania");
      }

      setSummary({
        total: data.total ?? 0,
        counts: data.counts ?? {
          organizacja: 0,
          bezpieczenstwo: 0,
          koszty: 0,
          inne: 0,
        },
      });
    } catch (e: any) {
      setError(e?.message || "Błąd połączenia");
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    refresh();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [consultationId]);

  function basicGuards(value: string) {
    const v = value.trim();

    if (v.length < 10) return "Napisz proszę minimum 10 znaków.";
    if (v.length > 300) return "Maksymalnie 300 znaków.";

    if (/(https?:\/\/|www\.)/i.test(v)) return "Linki nie są dozwolone.";

    const letters = v.replace(/[^A-Za-zĄĆĘŁŃÓŚŹŻąćęłńóśźż]/g, "");
    if (letters.length >= 20) {
      const upper = letters.replace(/[^A-ZĄĆĘŁŃÓŚŹŻ]/g, "").length;
      if (upper / letters.length > 0.6) return "Prosimy pisać bez CAPS LOCKA.";
    }

    return null;
  }

  async function submit() {
    const trimmed = text.trim();
    const guard = basicGuards(trimmed);

    if (guard) {
      setError(guard);
      setMsg(null);
      return;
    }

    setError(null);
    setMsg(null);

    try {
      const res = await fetch("/api/stanowiska", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          consultationId,
          text: trimmed,
          category,
        }),
      });

      const data = await res.json();
      if (!res.ok || !data?.ok) {
        throw new Error(data?.message || "Nie udało się przyjąć stanowiska");
      }

      setText("");
      setMsg(
        "Dziękujemy. Stanowisko zostało przyjęte do analizy i nie jest publikowane automatycznie."
      );

      await refresh();
    } catch (e: any) {
      setError(e?.message || "Błąd połączenia");
    }
  }

  return (
    <section className="mt-8">
      <h2 className="text-xl font-semibold">Złóż stanowisko</h2>
      <p className="mt-1 text-gray-700 max-w-2xl">
        Krótko i rzeczowo. Bez danych osobowych. Stanowiska są przyjmowane do
        analizy przez stowarzyszenie.
      </p>

      <div className="mt-4 rounded-2xl border p-5">
        <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
          <label className="text-sm font-medium">
            Kategoria
            <select
              value={category}
              onChange={(e) => setCategory(e.target.value as Category)}
              className="mt-2 w-full md:w-64 rounded-xl border p-2"
            >
              <option value="organizacja">Organizacja</option>
              <option value="bezpieczenstwo">Bezpieczeństwo</option>
              <option value="koszty">Koszty</option>
              <option value="inne">Inne</option>
            </select>
          </label>

          <div className="text-sm text-gray-500">
            {remaining} znaków (max 300)
          </div>
        </div>

        <textarea
          value={text}
          onChange={(e) => setText(e.target.value)}
          placeholder="Wpisz stanowisko (max 300 znaków)…"
          className="mt-3 w-full min-h-28 rounded-xl border p-3 outline-none focus:ring-2 focus:ring-gray-900"
          maxLength={300}
        />

        <div className="mt-4 flex flex-wrap items-center justify-between gap-3">
          <div className="text-sm text-gray-600">
            Wskazówka: opisz <b>miejsce</b>, <b>problem</b>, <b>propozycję</b>.
          </div>

          <button
            type="button"
            onClick={submit}
            disabled={text.trim().length < 10}
            className="rounded-full bg-gray-900 px-5 py-2.5 text-sm font-medium text-white hover:opacity-90 disabled:opacity-40"
          >
            Przyjmij stanowisko
          </button>
        </div>

        {error && <p className="mt-3 text-sm text-red-600">{error}</p>}
        {msg && <p className="mt-3 text-sm text-green-700">{msg}</p>}
      </div>

      {/* PODSUMOWANIE */}
      <section className="mt-8">
        <div className="flex flex-wrap items-end justify-between gap-3">
          <div>
            <h3 className="text-lg font-semibold">Podsumowanie konsultacji</h3>
            <p className="mt-1 text-gray-700">
              Publicznie pokazujemy liczby i kierunki. Treści stanowisk są w
              opracowaniu.
            </p>
          </div>

          <button
            type="button"
            onClick={refresh}
            className="rounded-full border px-4 py-2 text-sm font-medium hover:bg-gray-50"
          >
            Odśwież
          </button>
        </div>

        <div className="mt-4 rounded-2xl border p-5">
          <div className="flex flex-wrap items-end justify-between gap-3">
            <div>
              <p className="text-sm text-gray-600">Przyjęto stanowisk</p>
              <p className="text-3xl font-bold">
                {loading ? "…" : summary.total}
              </p>
            </div>

            <div className="text-sm text-gray-500">
              Źródło: serwer (MVP bez bazy).
            </div>
          </div>

          <div className="mt-5 space-y-3">
            {(Object.keys(summary.counts) as Category[]).map((cat) => {
              const count = summary.counts[cat];
              const width = Math.round((count / max) * 100);

              return (
                <div key={cat}>
                  <div className="flex items-center justify-between text-sm">
                    <span className="font-medium">{categoryLabel[cat]}</span>
                    <span className="text-gray-600">
                      {loading ? "…" : count}
                    </span>
                  </div>
                  <div className="mt-2 h-2 w-full rounded-full bg-gray-100">
                    <div
                      className="h-2 rounded-full bg-gray-900"
                      style={{ width: `${loading ? 0 : width}%` }}
                    />
                  </div>
                </div>
              );
            })}
          </div>

          <p className="mt-5 text-xs text-gray-500">
            Dane nie są jeszcze trwałe (restart serwera je usuwa). Następny etap
            to baza danych i moderacja.
          </p>
        </div>
      </section>
    </section>
  );
}
