import React, { useState, useEffect } from "react";
import { createRoot } from "react-dom/client";
import "./pregunta.css";

// ── Types & constants ─────────────────────────────────────────────────────────

type CreditInfo = {
  token: string;
  username: string;
  expiresAt: number;
  tier: string;
};

const STORAGE_KEY = "argumentes_credito";

const TIERS = [
  { id: "dia",    label: "1 día",    price: "1€",  days: 1  },
  { id: "semana", label: "1 semana", price: "5€",  days: 7  },
  { id: "mes",    label: "1 mes",    price: "15€", days: 30 },
] as const;

type TierId = (typeof TIERS)[number]["id"];

// ── Helpers ───────────────────────────────────────────────────────────────────

function loadCredit(): CreditInfo | null {
  try {
    const raw = localStorage.getItem(STORAGE_KEY);
    if (!raw) return null;
    const c = JSON.parse(raw) as CreditInfo;
    if (!c.token || !c.expiresAt || c.expiresAt < Date.now()) {
      localStorage.removeItem(STORAGE_KEY);
      return null;
    }
    return c;
  } catch {
    return null;
  }
}

function formatDate(ms: number): string {
  return new Date(ms).toLocaleDateString("es-ES", {
    day: "numeric",
    month: "long",
    year: "numeric",
  });
}

function daysLeft(expiresAt: number): number {
  return Math.max(0, Math.ceil((expiresAt - Date.now()) / (1000 * 60 * 60 * 24)));
}

async function submitRedsysForm(data: {
  tpvUrl: string;
  merchantParams: string;
  signature: string;
  signatureVersion: string;
}) {
  const form = document.createElement("form");
  form.method = "POST";
  form.action = data.tpvUrl;
  for (const [name, value] of Object.entries({
    Ds_SignatureVersion: data.signatureVersion,
    Ds_MerchantParameters: data.merchantParams,
    Ds_Signature: data.signature,
  })) {
    const input = document.createElement("input");
    input.type = "hidden";
    input.name = name;
    input.value = value;
    form.appendChild(input);
  }
  document.body.appendChild(form);
  form.submit();
}

// ── Main component ────────────────────────────────────────────────────────────

function App() {
  const params = new URLSearchParams(window.location.search);
  const creditOkOrder = params.get("credito_ok");
  const isKo = params.get("ko") === "1";

  // Credit state
  const [credit, setCredit] = useState<CreditInfo | null>(null);
  const [loaded, setLoaded] = useState(false);

  // Credit verification (polling after Redsys redirect)
  const [verifying, setVerifying] = useState(false);
  const [verifyError, setVerifyError] = useState(false);

  // Purchase flow
  const [selectedTier, setSelectedTier] = useState<TierId | null>(null);
  const [username, setUsername] = useState("");
  const [buying, setBuying] = useState(false);
  const [buyError, setBuyError] = useState<string | null>(null);

  // Question submission
  const [text, setText] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [submitError, setSubmitError] = useState<string | null>(null);
  const [sent, setSent] = useState(false);

  // Load credit from localStorage on mount
  useEffect(() => {
    setCredit(loadCredit());
    setLoaded(true);
  }, []);

  // Poll for credit activation after Redsys redirect
  useEffect(() => {
    if (!creditOkOrder || !loaded || credit) return;

    setVerifying(true);
    let attempts = 0;
    const maxAttempts = 15;

    async function poll() {
      if (attempts >= maxAttempts) {
        setVerifying(false);
        setVerifyError(true);
        return;
      }
      attempts++;
      try {
        const res = await fetch(
          `/api/credito/estado?order=${encodeURIComponent(creditOkOrder!)}`,
        );
        if (res.ok) {
          const data = (await res.json()) as {
            found: boolean;
            status?: string;
            token?: string;
            username?: string;
            expiresAt?: number;
            tier?: string;
          };
          if (data.found && data.status === "active" && data.token && data.expiresAt) {
            const newCredit: CreditInfo = {
              token: data.token,
              username: data.username ?? "",
              expiresAt: data.expiresAt,
              tier: data.tier ?? "",
            };
            localStorage.setItem(STORAGE_KEY, JSON.stringify(newCredit));
            setCredit(newCredit);
            setVerifying(false);
            history.replaceState(null, "", "/pregunta");
            return;
          }
        }
      } catch {
        // retry
      }
      setTimeout(poll, 2000);
    }

    poll();
  }, [creditOkOrder, loaded, credit]);

  async function handleBuyCredit(e: React.FormEvent) {
    e.preventDefault();
    if (!selectedTier) return;
    setBuyError(null);
    setBuying(true);
    try {
      const res = await fetch("/api/credito/iniciar", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ tier: selectedTier, username: username.trim() }),
      });
      if (!res.ok) throw new Error(await res.text());
      await submitRedsysForm(await res.json());
    } catch (err) {
      setBuyError(err instanceof Error ? err.message : "Error al procesar el pago");
      setBuying(false);
    }
  }

  async function handleSubmitQuestion(e: React.FormEvent) {
    e.preventDefault();
    if (!credit) return;
    setSubmitError(null);
    setSubmitting(true);
    try {
      const res = await fetch("/api/pregunta/enviar", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ text: text.trim(), token: credit.token }),
      });
      if (!res.ok) {
        const msg = await res.text();
        if (res.status === 401) {
          localStorage.removeItem(STORAGE_KEY);
          setCredit(null);
          throw new Error("Tu acceso ha expirado. Compra un nuevo plan.");
        }
        throw new Error(msg || `Error ${res.status}`);
      }
      setText("");
      setSent(true);
      setTimeout(() => setSent(false), 4000);
    } catch (err) {
      setSubmitError(err instanceof Error ? err.message : "Error al enviar");
    } finally {
      setSubmitting(false);
    }
  }

  // ── Loading ───────────────────────────────────────────────────────────────

  if (!loaded) {
    return (
      <div className="pregunta">
        <div className="pregunta__panel">
          <a href="/" className="pregunta__logo">
            <img src="/assets/logo.svg" alt="argument.es" />
          </a>
        </div>
      </div>
    );
  }

  // ── Payment failed ────────────────────────────────────────────────────────

  if (isKo) {
    return (
      <div className="pregunta">
        <div className="pregunta__panel">
          <a href="/" className="pregunta__logo">
            <img src="/assets/logo.svg" alt="argument.es" />
          </a>
          <h1>Pago cancelado</h1>
          <p className="pregunta__sub">
            El pago no se completó. Tu acceso no ha sido activado.
          </p>
          <a href="/pregunta" className="pregunta__btn">Intentar de nuevo</a>
          <div className="pregunta__links">
            <a href="/">Volver al juego</a>
          </div>
        </div>
      </div>
    );
  }

  // ── Verifying payment ─────────────────────────────────────────────────────

  if (verifying || (creditOkOrder && !credit)) {
    return (
      <div className="pregunta">
        <div className="pregunta__panel">
          <a href="/" className="pregunta__logo">
            <img src="/assets/logo.svg" alt="argument.es" />
          </a>
          <h1>Verificando tu pago…</h1>
          <p className="pregunta__sub">
            {verifyError
              ? "No se pudo confirmar el pago. Si se completó, espera unos segundos y recarga."
              : "Esto puede tardar unos segundos."}
          </p>
          {verifyError ? (
            <a href="/pregunta" className="pregunta__btn">Volver</a>
          ) : (
            <div className="pregunta__spinner" />
          )}
        </div>
      </div>
    );
  }

  // ── Active credit — question form ─────────────────────────────────────────

  if (credit) {
    const days = daysLeft(credit.expiresAt);
    return (
      <div className="pregunta">
        <div className="pregunta__panel">
          <div className="pregunta__header-row">
            <a href="/" className="pregunta__logo">
              <img src="/assets/logo.svg" alt="argument.es" />
            </a>
            <div className="pregunta__credit-badge">
              {days === 0
                ? "Expira hoy"
                : `${days} día${days !== 1 ? "s" : ""} restante${days !== 1 ? "s" : ""}`}
            </div>
          </div>

          <h1>Hola, {credit.username}</h1>
          <p className="pregunta__sub">
            Acceso activo hasta el {formatDate(credit.expiresAt)}.
            Envía todas las preguntas que quieras.
          </p>

          {sent && (
            <div className="pregunta__success">
              ✓ ¡Pregunta enviada! Se usará en el próximo sorteo.
            </div>
          )}

          <form onSubmit={handleSubmitQuestion} className="pregunta__form">
            <label htmlFor="pregunta-text" className="pregunta__label">
              Tu pregunta (frase de completar)
            </label>
            <textarea
              id="pregunta-text"
              className="pregunta__textarea"
              value={text}
              onChange={(e) => setText(e.target.value)}
              placeholder='Ejemplo: "La peor cosa que puedes encontrar en ___"'
              maxLength={200}
              required
              rows={3}
              autoFocus
            />
            <div className="pregunta__hint">{text.length}/200 · mínimo 10</div>
            {submitError && <div className="pregunta__error">{submitError}</div>}
            <button
              type="submit"
              className="pregunta__submit"
              disabled={submitting || text.trim().length < 10}
            >
              {submitting ? "Enviando…" : "Enviar pregunta"}
            </button>
          </form>

          <div className="pregunta__links">
            <a href="/">Ver el juego</a>
            <span className="pregunta__links-sep">·</span>
            <button
              className="pregunta__link-btn"
              onClick={() => {
                localStorage.removeItem(STORAGE_KEY);
                setCredit(null);
              }}
            >
              Cerrar sesión
            </button>
          </div>
        </div>
      </div>
    );
  }

  // ── No credit — tier selection ────────────────────────────────────────────

  const tierInfo = selectedTier ? TIERS.find((t) => t.id === selectedTier) : null;

  return (
    <div className="pregunta">
      <div className="pregunta__panel">
        <a href="/" className="pregunta__logo">
          <img src="/assets/logo.svg" alt="argument.es" />
        </a>

        <h1>Propón preguntas al juego</h1>
        <p className="pregunta__sub">
          Compra acceso por tiempo y envía todas las preguntas que quieras.
          Las mejores preguntas se usan en lugar de las generadas por IA y
          aparecerás en el marcador de Jugadores.
        </p>

        <div className="tier-cards">
          {TIERS.map((tier) => (
            <button
              key={tier.id}
              type="button"
              className={`tier-card ${selectedTier === tier.id ? "tier-card--selected" : ""}`}
              onClick={() => setSelectedTier(tier.id)}
            >
              <div className="tier-card__price">{tier.price}</div>
              <div className="tier-card__label">{tier.label}</div>
            </button>
          ))}
        </div>

        {selectedTier && (
          <form onSubmit={handleBuyCredit} className="pregunta__form">
            <label htmlFor="username" className="pregunta__label">
              Tu nombre en el marcador
            </label>
            <input
              id="username"
              type="text"
              className="pregunta__input"
              value={username}
              onChange={(e) => setUsername(e.target.value)}
              placeholder="Ej: Malin"
              maxLength={30}
              required
              autoFocus
            />
            {buyError && <div className="pregunta__error">{buyError}</div>}
            <button
              type="submit"
              className="pregunta__submit"
              disabled={buying || !username.trim()}
            >
              {buying
                ? "Redirigiendo…"
                : `Pagar ${tierInfo?.price} — ${tierInfo?.label}`}
            </button>
          </form>
        )}

        <div className="pregunta__links">
          <a href="/">Volver al juego</a>
        </div>
      </div>
    </div>
  );
}

const root = createRoot(document.getElementById("root")!);
root.render(<App />);
