"use client";

import { useState, type ChangeEvent } from "react";
import { getPB } from "@/lib/pocketbase";
import { fileToDataURL } from "@/lib/disenador/image";
import {
  RENDER_TIPOS, VISTA_LABELS, extractDudas, type RenderTipo, type VistaCroquis,
} from "@/lib/disenador/render-prompts";
import { saveRender, patchRenderDriveId } from "@/lib/pb/renders";
import GuardarRenderModal from "@/components/disenador/GuardarRenderModal";

// Pestaña "Croquis → Render": foto del croquis en papel + descripción → la IA
// devuelve una FICHA editable → renders en distintos estilos (Gemini / OpenAI).

interface Croquis { data: string; vista: VistaCroquis }
interface RenderResult { id: number; url: string; tipo: RenderTipo; modelo: "gemini" | "openai" }
// Estado de guardado por render de la galería: pb = guardado, drive = espejado.
type SavedState = "pb" | "drive" | "drive_err";

const VISTAS: VistaCroquis[] = ["isometrica", "frontal", "lateral", "superior"];
const MAX_CROQUIS = 3;
let renderSeq = 0;

export default function CroquisRenderTab() {
  const [croquis, setCroquis] = useState<Croquis[]>([]);
  const [descripcion, setDescripcion] = useState("");
  const [ficha, setFicha] = useState("");
  const [entendiendo, setEntendiendo] = useState(false);
  const [fichaErr, setFichaErr] = useState("");
  const [respuestas, setRespuestas] = useState("");
  const [aplicando, setAplicando] = useState(false);
  const [tipo, setTipo] = useState<RenderTipo>("fotorrealista");
  const [modelo, setModelo] = useState<"gemini" | "openai">("gemini");
  const [calidad, setCalidad] = useState<"low" | "medium" | "high">("low");
  const [rendering, setRendering] = useState(false);
  const [renderErr, setRenderErr] = useState("");
  const [galeria, setGaleria] = useState<RenderResult[]>([]);
  const [guardando, setGuardando] = useState<RenderResult | null>(null); // render abierto en el modal
  const [saved, setSaved] = useState<Record<number, SavedState>>({});

  async function onPickCroquis(e: ChangeEvent<HTMLInputElement>) {
    const files = Array.from(e.target.files || []).slice(0, MAX_CROQUIS - croquis.length);
    const nuevos: Croquis[] = [];
    for (const f of files) nuevos.push({ data: await fileToDataURL(f), vista: "isometrica" });
    if (nuevos.length) setCroquis((prev) => [...prev, ...nuevos].slice(0, MAX_CROQUIS));
    e.target.value = "";
  }

  function setVista(i: number, vista: VistaCroquis) {
    setCroquis((prev) => prev.map((c, j) => (j === i ? { ...c, vista } : c)));
  }

  async function entenderMueble() {
    setEntendiendo(true);
    setFichaErr("");
    try {
      const token = getPB().authStore.token;
      const r = await fetch("/api/disenador/ficha", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify({ descripcion, croquis }),
      });
      const data = await r.json();
      if (!r.ok) throw new Error(data?.error || `Error ${r.status}`);
      setFicha(data.ficha as string);
    } catch (e) {
      setFichaErr((e as Error).message);
    } finally {
      setEntendiendo(false);
    }
  }

  /** Responde las DUDAS de la ficha: la IA la actualiza sin reinterpretar el croquis. */
  async function aplicarRespuestas() {
    setAplicando(true);
    setFichaErr("");
    try {
      const token = getPB().authStore.token;
      const r = await fetch("/api/disenador/ficha", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify({ descripcion, croquis, fichaActual: ficha, respuestas }),
      });
      const data = await r.json();
      if (!r.ok) throw new Error(data?.error || `Error ${r.status}`);
      setFicha(data.ficha as string);
      setRespuestas("");
    } catch (e) {
      setFichaErr((e as Error).message);
    } finally {
      setAplicando(false);
    }
  }

  async function generarRender() {
    setRendering(true);
    setRenderErr("");
    try {
      const token = getPB().authStore.token;
      const r = await fetch("/api/disenador/render-libre", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify({ ficha, tipo, modelo, quality: calidad, croquis }),
      });
      const data = await r.json();
      if (!r.ok) throw new Error(data?.error || `Error ${r.status}`);
      setGaleria((prev) => [{ id: ++renderSeq, url: data.imagen as string, tipo, modelo }, ...prev]);
    } catch (e) {
      setRenderErr((e as Error).message);
    } finally {
      setRendering(false);
    }
  }

  const tipoLabel = (t: RenderTipo) => RENDER_TIPOS.find((x) => x.id === t)?.label || t;
  const dudas = ficha ? extractDudas(ficha) : null;

  /** Espejo a Drive: fire-and-forget, el render ya está a salvo en PB. */
  async function mirrorToDrive(g: RenderResult, nombre: string, recordId: string) {
    try {
      const token = getPB().authStore.token;
      const r = await fetch("/api/disenador/drive", {
        method: "POST",
        headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
        body: JSON.stringify({ nombre, imagen: g.url }),
      });
      const data = await r.json();
      if (r.ok && typeof data.driveId === "string") {
        await patchRenderDriveId(recordId, data.driveId);
        setSaved((prev) => ({ ...prev, [g.id]: "drive" }));
      } else {
        setSaved((prev) => ({ ...prev, [g.id]: "drive_err" }));
      }
    } catch {
      setSaved((prev) => ({ ...prev, [g.id]: "drive_err" }));
    }
  }

  /** Guarda el render en PB (con vínculo opcional) y dispara el espejo a Drive. */
  async function guardarRender(g: RenderResult, nombre: string, presupuestoId: string | undefined, propuestaIndex0: number | null) {
    const rec = await saveRender({
      nombre, dataURL: g.url, tipo: g.tipo, modelo: g.modelo, ficha,
      presupuesto: presupuestoId, propuestaIndex0,
    });
    setSaved((prev) => ({ ...prev, [g.id]: "pb" }));
    void mirrorToDrive(g, nombre, rec.id);
  }

  return (
    <div className="space-y-5">
      {/* 1 · Croquis + descripción */}
      <div className="rounded-xl border border-line bg-surface p-4 space-y-3">
        <div>
          <h3 className="text-sm font-medium text-ink">1 · Croquis y descripción</h3>
          <p className="text-xs text-faint">Sacale una foto al croquis en papel. Indicá qué vista es cada imagen para que la IA la interprete bien.</p>
        </div>

        <div className="flex flex-wrap gap-3">
          {croquis.map((c, i) => (
            <div key={i} className="w-36 space-y-1">
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img src={c.data} alt={`croquis ${i + 1}`} className="w-36 h-28 object-cover rounded-lg border border-line" />
              <select
                value={c.vista}
                onChange={(e) => setVista(i, e.target.value as VistaCroquis)}
                className="w-full rounded-lg border border-line bg-canvas p-1.5 text-xs text-ink"
                title="Vista del croquis"
              >
                {VISTAS.map((v) => <option key={v} value={v}>{VISTA_LABELS[v]}</option>)}
              </select>
              <button
                type="button"
                onClick={() => setCroquis((prev) => prev.filter((_, j) => j !== i))}
                className="w-full text-xs text-red-600"
              >
                quitar
              </button>
            </div>
          ))}
          {croquis.length < MAX_CROQUIS && (
            <label className="w-36 h-28 flex flex-col items-center justify-center gap-1 rounded-lg border border-dashed border-line bg-canvas text-xs text-faint cursor-pointer hover:border-brand-dark hover:text-ink">
              <input type="file" accept="image/*" multiple className="hidden" onChange={onPickCroquis} />
              <span className="text-xl">📎</span>
              {croquis.length ? "Agregar otra vista" : "Cargar croquis"}
            </label>
          )}
        </div>

        <textarea
          value={descripcion}
          onChange={(e) => setDescripcion(e.target.value)}
          className="w-full h-20 rounded-lg border border-line bg-canvas p-3 text-sm text-ink"
          placeholder="Detalles que el croquis no muestra: medidas, materiales, cantidad de cajones, tipo de apertura…"
        />

        <div className="flex items-center gap-3 flex-wrap">
          <button
            onClick={entenderMueble}
            disabled={entendiendo || (!descripcion.trim() && !croquis.length)}
            className="inline-flex items-center gap-2 rounded-lg bg-brand-dark px-4 py-2 text-sm font-semibold text-white disabled:opacity-60"
          >
            {entendiendo && <span className="inline-block w-4 h-4 rounded-full border-2 border-white/40 border-t-white animate-spin" />}
            {entendiendo ? "Analizando…" : ficha ? "Volver a analizar" : "Entender el mueble"}
          </button>
          {fichaErr && <span className="text-sm text-red-600">{fichaErr}</span>}
        </div>
      </div>

      {/* 2 · Ficha editable */}
      {ficha && (
        <div className="rounded-xl border border-line bg-surface p-4 space-y-2">
          <div>
            <h3 className="text-sm font-medium text-ink">2 · Ficha del mueble</h3>
            <p className="text-xs text-faint">Esto es lo que la IA entendió. Corregila a mano: todos los renders salen de acá.</p>
          </div>
          <textarea
            value={ficha}
            onChange={(e) => setFicha(e.target.value)}
            spellCheck={false}
            className="w-full h-56 rounded-lg border border-line bg-canvas p-3 text-sm text-ink"
          />

          {/* Responder las DUDAS de la ficha sin reescribirla a mano */}
          <div className={`rounded-lg border p-3 space-y-2 ${dudas ? "border-amber-300 bg-amber-50" : "border-dashed border-line bg-canvas"}`}>
            {dudas ? (
              <div className="space-y-1">
                <p className="text-xs font-bold text-amber-800 uppercase tracking-wide">La IA tiene dudas</p>
                <p className="text-sm text-amber-900 whitespace-pre-wrap">{dudas}</p>
                <p className="text-xs text-amber-800/80">Respondelas acá abajo y la ficha se actualiza sin reinterpretar el croquis.</p>
              </div>
            ) : (
              <p className="text-xs text-faint">
                ¿Querés corregir o agregar algo? Escribilo acá y la IA actualiza la ficha sin reinterpretar el croquis.
              </p>
            )}
            <textarea
              value={respuestas}
              onChange={(e) => setRespuestas(e.target.value)}
              className="w-full h-16 rounded-lg border border-line bg-surface p-2 text-sm text-ink"
              placeholder="Ej: sí, el zócalo es de 8 cm; las puertas abren con uñero; los estantes son fijos…"
            />
            <div className="flex items-center gap-3">
              <button
                onClick={aplicarRespuestas}
                disabled={aplicando || !respuestas.trim()}
                className="inline-flex items-center gap-2 rounded-lg bg-brand-soft px-3 py-1.5 text-sm font-semibold text-brand-dark disabled:opacity-50"
              >
                {aplicando && <span className="inline-block w-3.5 h-3.5 rounded-full border-2 border-brand-dark/30 border-t-brand-dark animate-spin" />}
                {aplicando ? "Actualizando ficha…" : "Aplicar respuestas a la ficha"}
              </button>
            </div>
          </div>
        </div>
      )}

      {/* 3 · Render */}
      {ficha && (
        <div className="rounded-xl border border-line bg-surface p-4 space-y-3">
          <h3 className="text-sm font-medium text-ink">3 · Render</h3>

          <div className="flex flex-wrap gap-2">
            {RENDER_TIPOS.map((t) => (
              <button
                key={t.id}
                type="button"
                onClick={() => setTipo(t.id)}
                className={`rounded-lg px-3 py-1.5 text-sm font-medium border transition-colors ${
                  tipo === t.id
                    ? "bg-brand-soft text-brand-dark border-brand-dark"
                    : "bg-canvas text-faint border-line hover:text-ink"
                }`}
              >
                {t.label}
              </button>
            ))}
          </div>

          <div className="flex items-center gap-3 flex-wrap">
            <label className="inline-flex items-center gap-2 text-sm text-ink">
              <span className="text-xs text-faint">Modelo</span>
              <select
                value={modelo}
                onChange={(e) => setModelo(e.target.value as "gemini" | "openai")}
                className="rounded-lg border border-line bg-canvas p-2 text-sm text-ink"
              >
                <option value="gemini">Gemini (nano banana)</option>
                <option value="openai">gpt-image-1 (OpenAI)</option>
              </select>
            </label>
            {modelo === "openai" && (
              <label className="inline-flex items-center gap-2 text-sm text-ink">
                <span className="text-xs text-faint">Calidad</span>
                <select
                  value={calidad}
                  onChange={(e) => setCalidad(e.target.value as "low" | "medium" | "high")}
                  className="rounded-lg border border-line bg-canvas p-2 text-sm text-ink"
                >
                  <option value="low">Borrador (más barato)</option>
                  <option value="medium">Estándar</option>
                  <option value="high">Alta (para cliente)</option>
                </select>
              </label>
            )}
            <button
              onClick={generarRender}
              disabled={rendering || !croquis.length}
              className="inline-flex items-center gap-2 rounded-lg bg-brand-dark px-4 py-2 text-sm font-semibold text-white disabled:opacity-60"
            >
              {rendering && <span className="inline-block w-4 h-4 rounded-full border-2 border-white/40 border-t-white animate-spin" />}
              {rendering ? "Generando…" : "Generar render"}
            </button>
            {renderErr && <span className="text-sm text-red-600">{renderErr}</span>}
            <span className="text-xs text-faint">Tarda unos segundos · consume crédito de IA.</span>
          </div>

          {/* Galería: los renders se acumulan para comparar estilos y modelos */}
          {galeria.length > 0 && (
            <div className="grid gap-4 sm:grid-cols-2 pt-2">
              {galeria.map((g) => (
                <div key={g.id} className="rounded-lg border border-line overflow-hidden bg-canvas">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img src={g.url} alt={tipoLabel(g.tipo)} className="w-full" />
                  <div className="flex items-center justify-between gap-2 px-3 py-2 text-xs">
                    <span className="text-ink font-medium truncate">
                      {tipoLabel(g.tipo)}
                      <span className="text-faint font-normal"> · {g.modelo === "gemini" ? "Gemini" : "gpt-image-1"}</span>
                    </span>
                    <span className="flex items-center gap-2 shrink-0">
                      {saved[g.id] ? (
                        <span className={saved[g.id] === "drive_err" ? "text-amber-700" : "text-good"} title={saved[g.id] === "drive_err" ? "Guardado en la app; el espejo a Drive falló (¿carpeta compartida?)" : undefined}>
                          {saved[g.id] === "drive" ? "Guardado ✓ + Drive" : saved[g.id] === "drive_err" ? "Guardado ✓ (Drive pendiente)" : "Guardado ✓"}
                        </span>
                      ) : (
                        <button onClick={() => setGuardando(g)} className="font-semibold text-brand-dark underline">
                          Guardar
                        </button>
                      )}
                      <a href={g.url} download={`render-${g.tipo}-${g.id}.png`} className="text-brand-dark underline">
                        Descargar
                      </a>
                    </span>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      )}

      {/* Modal: guardar render (nombre + vínculo opcional a presupuesto/propuesta) */}
      {guardando && (
        <GuardarRenderModal
          title="Guardar render"
          confirmLabel="Guardar render"
          initialNombre={`${tipoLabel(guardando.tipo)} — ${new Date().toLocaleDateString("es-AR")}`}
          onClose={() => setGuardando(null)}
          onConfirm={async (v) => {
            await guardarRender(guardando, v.nombre, v.presupuesto?.id, v.propuestaIndex0);
          }}
        />
      )}
    </div>
  );
}
