"use client";
import { FormEvent, useEffect, useState } from "react";
import Link from "next/link";
import { PublicFooter, PublicHeader } from "../../components/PublicChrome";
import { userMessage } from "../../lib/messages";
const apiBase = process.env.NEXT_PUBLIC_API_BASE_URL || "/api/v1";
type Pending = {
  pago_id: number;
  folio: string;
  access_token: string;
  proveedor: string;
  account_created?: boolean;
  account_exists?: boolean;
  summary?: Record<string, unknown>;
};
type ConfirmationSummary = {
  documento?: unknown;
  total?: unknown;
  entidad?: Record<string, unknown>;
  notaria?: Record<string, unknown>;
  cliente?: Record<string, unknown>;
  reserva?: unknown;
};
export default function PaymentReturn() {
  const [state, setState] = useState<"loading" | "success" | "error">(
      "loading",
    ),
    [message, setMessage] = useState("Confirmando tu pago…"),
    [pending, setPending] = useState<Pending | null>(null),
    [order, setOrder] = useState(""),
    [retrying, setRetrying] = useState(false),
    [retryAllowed, setRetryAllowed] = useState(false),
    [creating, setCreating] = useState(false),
    [created, setCreated] = useState(false),
    [appointmentStatus, setAppointmentStatus] = useState("");
  useEffect(() => {
    const confirm = async () => {
      const raw =
        sessionStorage.getItem("documenta:pending-payment") ||
        sessionStorage.getItem("documenta:completed-payment");
      if (!raw) {
        setState("error");
        setMessage(
          "No encontramos una transacción pendiente en este navegador.",
        );
        return;
      }
      const p = JSON.parse(raw) as Pending;
      setPending(p);
      try {
        const query = new URLSearchParams(window.location.search),
          result = query.get("resultado");
        let approved = false;
        let authoritativeOrder = "";
        let bookingState = "";
        if (query.get("mock") === "1") {
          const mock = await fetch(`${apiBase}/pagos/mock-confirm`, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ pago_id:p.pago_id,folio:p.folio,access_token:p.access_token }),
          });
          if (!mock.ok) {
            const detail = await mock.json();
            throw new Error(detail.detail || "No fue posible confirmar el pago de prueba.");
          }
          const mockBody = await mock.json();
          approved = mockBody?.ok === true;
          bookingState = String(mockBody?.resumen?.reserva_estado || "");
          authoritativeOrder = String(mockBody?.orden?.numero_ot || mockBody?.resumen?.numero_ot || "");
        } else {
          const reconcile = await fetch(`${apiBase}/pagos/verificar`, {
            method:"POST",headers:{"Content-Type":"application/json"},
            body:JSON.stringify({ pago_id:p.pago_id,folio:p.folio,access_token:p.access_token }),
          });
          const detail = await reconcile.json();
          if (!reconcile.ok) {
            throw new Error(detail.detail || "El medio de pago no pudo validar esta transacción.");
          }
          const samePayment = Number(detail.pago_id) === Number(p.pago_id);
          approved = detail.authoritative === true && detail.approved === true && samePayment;
          bookingState = String(detail.reserva_estado || "");
          authoritativeOrder = String(detail.numero_ot || "");
          setRetryAllowed(detail.retry_allowed === true && samePayment);
        }
        if (!approved) {
          const messages: Record<string,string> = {
            rechazado:"El pago fue rechazado. Puedes intentarlo nuevamente sin perder tus datos.",
            abortado:"Cancelaste el proceso de pago.",timeout:"Se agotó el tiempo disponible para pagar.",
            invalido:"El proveedor no entregó un retorno verificable. El pago no fue marcado como aprobado.",
            verificando:"El pago aún está siendo confirmado. Espera unos segundos y recarga esta página.",
            error_reintentar:"La transacción no fue autorizada.",
            error_verificacion:"No pudimos verificar con seguridad el resultado. No vuelvas a pagar hasta revisarlo.",
          };
          throw new Error(messages[result || ""] || "El servidor no registra este pago como autorizado.");
        }
        setOrder(authoritativeOrder);
        setAppointmentStatus(bookingState);
        sessionStorage.removeItem("documenta:pending-payment");
        sessionStorage.setItem("documenta:completed-payment", raw);
        setState("success");
        setMessage(p.summary?.reserva && bookingState !== "CONFIRMADA"
          ? "El pago fue aprobado. La confirmación de la hora sigue pendiente; conserva tu folio y no vuelvas a pagar."
          : authoritativeOrder
            ? "El pago fue aprobado y la solicitud fue entregada mediante el conector de la entidad."
            : "El pago fue aprobado y la solicitud quedó disponible en la bandeja de la entidad.");
      } catch (e) {
        setState("error");
        setMessage(userMessage(e, "No fue posible confirmar el pago."));
      }
    };
    void confirm();
  }, []);
  async function retryPayment() {
    if (!pending || retrying) return;
    setRetrying(true);
    setMessage("Creando un nuevo intento seguro…");
    try {
      const r = await fetch(`${apiBase}/pagos`, {
        method: "POST",
        headers: { "Content-Type": "application/json", "Idempotency-Key": crypto.randomUUID() },
        body: JSON.stringify({ folio: pending.folio, access_token: pending.access_token,
          proveedor: pending.proveedor }),
      });
      const b = await r.json();
      if (!r.ok) throw new Error(b.detail || "No fue posible reintentar el pago.");
      const next = { ...pending, pago_id: Number(b.pago_id) };
      sessionStorage.setItem("documenta:pending-payment", JSON.stringify(next));
      const form = document.createElement("form");
      form.method = String(b.redirect_method || "POST");
      form.action = String(b.redirect_url);
      if (form.method.toUpperCase() === "POST") {
        const token = document.createElement("input");
        token.type = "hidden"; token.name = "token_ws"; token.value = String(b.token);
        form.appendChild(token);
      }
      document.body.appendChild(form);
      form.submit();
    } catch (e) {
      setMessage(userMessage(e, "No fue posible reintentar el pago."));
      setRetrying(false);
    }
  }
  async function receipt() {
    if (!pending) return;
    const r = await fetch(`${apiBase}/pagos/${pending.pago_id}/comprobante`, {
      headers: { "X-Access-Token": pending.access_token },
    });
    if (!r.ok) return setMessage("No fue posible generar el comprobante.");
    const blob = await r.blob(),
      url = URL.createObjectURL(blob),
      a = document.createElement("a");
    a.href = url;
    a.download = `comprobante-${pending.folio}.pdf`;
    a.click();
    URL.revokeObjectURL(url);
  }
  async function account(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    if (!pending) return;
    const f = new FormData(e.currentTarget);
    if (f.get("password") !== f.get("confirm"))
      return setMessage("Las contraseñas no coinciden.");
    setCreating(true);
    const r = await fetch(`${apiBase}/auth/register-customer`, {
      method: "POST",
      credentials: "include",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        folio: pending.folio,
        access_token: pending.access_token,
        password: f.get("password"),
      }),
    });
    const b = await r.json();
    setCreating(false);
    if (!r.ok) return setMessage(b.detail || "No fue posible crear la cuenta.");
    sessionStorage.setItem("documenta:csrf", b.csrf_token);
    setCreated(true);
  }
  if (state === "loading")
    return (
      <><PublicHeader /><main className="payment-page">
        <section className="payment-card">
          <img
            src="/media/brand/logo-horizontal.svg"
            alt="Documenta"
            width="170"
          />
          <h1>Estamos confirmando</h1>
          <p>{message}</p>
        </section>
      </main><PublicFooter /></>
    );
  if (state === "error")
    return (
      <><PublicHeader /><main className="payment-page payment-result-page">
        <section className="payment-card">
          <img
            src="/media/brand/logo-horizontal.svg"
            alt="Documenta"
            width="170"
          />
          <span className="section-kicker">RESULTADO DEL PAGO</span>
          <h1>No fue posible confirmar</h1>
          <p>{message}</p>
          {pending && retryAllowed && (
            <button className="button button-primary" disabled={retrying} onClick={() => void retryPayment()}>
              {retrying ? "Preparando pago…" : "Reintentar pago"}
            </button>
          )}
          <Link className="button button-secondary" href="/">
            Volver a Documenta
          </Link>
        </section>
      </main><PublicFooter /></>
    );
  const s = (pending?.summary || {}) as ConfirmationSummary,
    n = (s.entidad || s.notaria || {}) as Record<string, unknown>,
    c = (s.cliente || {}) as Record<string, unknown>;
  return (
    <main className="confirmation-page">
      <PublicHeader />
      <section className="confirmation-shell">
        <div className="confirmation-ok">✓</div>
        <span className="section-kicker">PAGO APROBADO</span>
        <h1>Tu trámite quedó ingresado.</h1>
        <p className="confirmation-lead">
          {message} Conserva el folio para consultar su estado.
        </p>
        <div className="summary-grid public-summary">
          {Boolean(s.reserva) && <Summary title="Hora solicitada" rows={[
            ["Fecha y hora", s.reserva],
            ["Estado", appointmentStatus === "CONFIRMADA" ? "Confirmada" : "Pendiente de confirmación"],
          ]} />}
          <Summary
            title="Documento"
            rows={[
              ["Folio", pending?.folio],
              ["Trámite", s.documento],
              ["Referencia externa", order || "No aplica"],
            ]}
          />
          <Summary
            title="Persona informada"
            rows={[
              ["Nombre", c.name],
              ["RUT", c.rut],
              ["Correo", c.email],
            ]}
          />
          <Summary
            title="Entidad"
            rows={[
              ["Nombre", n.nombre_fantasia],
              ["Dirección", `${n.direccion || ""}, ${n.comuna || ""}`],
            ]}
          />
          <Summary
            title="Pago"
            rows={[
              ["Estado", "Aprobado"],
              ["Total", `$${Number(s.total || 0).toLocaleString("es-CL")}`],
            ]}
          />
        </div>
        <div className="confirmation-actions">
          <button className="button button-secondary" onClick={receipt}>
            Descargar comprobante PDF
          </button>
          <Link
            className="button button-secondary"
            href={`/estado?codigo=${encodeURIComponent(pending?.folio || "")}`}
          >
            Ver estado del documento
          </Link>
          {pending?.account_created || pending?.account_exists || created ? (
            <Link className="button button-primary" href="/panel">
              Ir a mi panel
            </Link>
          ) : null}
        </div>
        {!pending?.account_created && !pending?.account_exists && !created && (
          <form
            className="procedure-card confirmation-account"
            onSubmit={account}
          >
            <h2>¿Quieres guardar este trámite en una cuenta?</h2>
            <p>La cuenta es opcional y usará el correo informado.</p>
            <div className="form-pair">
              <label>
                Contraseña
                <input
                  name="password"
                  type="password"
                  minLength={12}
                  required
                />
              </label>
              <label>
                Repetir contraseña
                <input name="confirm" type="password" minLength={12} required />
              </label>
            </div>
            <button className="button button-primary" disabled={creating}>
              {creating ? "Creando…" : "Crear mi cuenta"}
            </button>
          </form>
        )}
        <p className="confirmation-note">
          Enviamos el resumen y el acceso de seguimiento al correo informado y a
          la entidad responsable.
        </p>
      </section>
      <PublicFooter />
    </main>
  );
}
function Summary({
  title,
  rows,
}: {
  title: string;
  rows: Array<[string, unknown]>;
}) {
  return (
    <article className="summary-block">
      <h3>{title}</h3>
      <dl>
        {rows.map(([k, v]) => (
          <div key={k}>
            <dt>{k}</dt>
            <dd>{String(v ?? "—")}</dd>
          </div>
        ))}
      </dl>
    </article>
  );
}
