// CardAdmin — admin panel tab for managing collectible cards.
// CRUD: create, edit, delete cards. Each card has drop rules tied to arcs/chapters.
// Live preview using HoloCard.

const { useState: _useState, useEffect: _useEffect } = React;

function CardAdmin({ store, setStore }) {
  const cards = store.cards || [];
  const [activeId, setActiveId] = _useState(cards[0]?.id || null);

  const setCards = (next) => setStore({ ...store, cards: next });

  const active = cards.find(c => c.id === activeId) || null;

  const addCard = () => {
    const c = {
      id: window.NovelStore.newId(),
      name: "Nueva carta",
      image: "",
      rarity: "comun",
      category: "personaje",
      flavor: "",
      description: "",
      dropRules: [],
    };
    setCards([...cards, c]);
    setActiveId(c.id);
  };

  const updateCard = (id, patch) => {
    setCards(cards.map(c => c.id === id ? { ...c, ...patch } : c));
  };

  const deleteCard = (id) => {
    if (!confirm("¿Eliminar esta tarjeta? No se puede deshacer.")) return;
    setCards(cards.filter(c => c.id !== id));
    if (activeId === id) setActiveId(null);
  };

  const duplicateCard = (id) => {
    const src = cards.find(c => c.id === id);
    if (!src) return;
    const copy = { ...src, id: window.NovelStore.newId(), name: src.name + " (copia)", dropRules: [...(src.dropRules || [])] };
    setCards([...cards, copy]);
    setActiveId(copy.id);
  };

  return (
    <div className="cardadm-grid">
      <aside className="cardadm-sidebar">
        <div className="admin-section-title">TARJETAS</div>
        <div className="cardadm-list">
          {cards.length === 0 && (
            <div className="cardadm-empty">No hay tarjetas todavía.</div>
          )}
          {cards.map((c) => {
            const r = window.CardSystem.getRarity(c.rarity);
            return (
              <button
                key={c.id}
                className={"cardadm-list-item" + (activeId === c.id ? " active" : "")}
                onClick={() => setActiveId(c.id)}
              >
                <div className="cardadm-thumb" style={{ borderColor: r.color }}>
                  {c.image ? (
                    <img src={c.image} alt="" />
                  ) : (
                    <div className="cardadm-thumb-empty">?</div>
                  )}
                </div>
                <div className="cardadm-list-meta">
                  <div className="cardadm-list-name">{c.name || "(sin nombre)"}</div>
                  <div className="cardadm-list-rarity" style={{ color: r.color }}>{r.label}</div>
                </div>
              </button>
            );
          })}
        </div>
        <button className="admin-add-btn" onClick={addCard}>+ NUEVA TARJETA</button>
      </aside>

      <main className="cardadm-main">
        {active ? (
          <CardEditor
            key={active.id}
            card={active}
            arcs={store.arcs || []}
            onChange={(patch) => updateCard(active.id, patch)}
            onDelete={() => deleteCard(active.id)}
            onDuplicate={() => duplicateCard(active.id)}
          />
        ) : (
          <div className="admin-empty">
            <div className="admin-empty-icon">◆</div>
            <div className="admin-empty-title">SELECCIONA UNA TARJETA</div>
            <div className="admin-empty-sub">
              Las tarjetas son las recompensas que el lector colecciona<br/>
              al leer capítulos y completar arcos.
            </div>
          </div>
        )}
      </main>
    </div>
  );
}

function CardEditor({ card, arcs, onChange, onDelete, onDuplicate }) {
  const setField = (k, v) => onChange({ [k]: v });

  const addRule = () => {
    const firstArc = arcs[0];
    const rule = {
      id: window.NovelStore.newId(),
      trigger: "chapter",
      arcId: firstArc?.id || "",
      chapterId: firstArc?.chapters?.[0]?.id || "",
      chance: 100,
    };
    onChange({ dropRules: [...(card.dropRules || []), rule] });
  };

  const updateRule = (rid, patch) => {
    onChange({
      dropRules: (card.dropRules || []).map(r => r.id === rid ? { ...r, ...patch } : r)
    });
  };

  const deleteRule = (rid) => {
    onChange({ dropRules: (card.dropRules || []).filter(r => r.id !== rid) });
  };

  const handleImage = async (file) => {
    if (!file) return;
    try {
      const url = await window.NovelStore.uploadImage(file);
      setField("image", url);
    } catch (e) {
      alert(e.message);
    }
  };

  return (
    <div className="cardadm-editor">
      <div className="cardadm-edit-header">
        <input
          className="cardadm-edit-name"
          value={card.name || ""}
          onChange={(e) => setField("name", e.target.value)}
          placeholder="Nombre de la tarjeta"
        />
        <div className="cardadm-edit-actions">
          <button className="cardadm-mini-btn" onClick={() => { window.CardSystem.addCardToCollection(card.id); }}>OBTENER</button>
          <button className="cardadm-mini-btn" onClick={onDuplicate}>DUPLICAR</button>
          <button className="cardadm-mini-btn cardadm-danger" onClick={onDelete}>ELIMINAR</button>
        </div>
      </div>

      <div className="cardadm-edit-cols">
        <div className="cardadm-edit-fields">
          <div className="cardadm-field">
            <label className="cardadm-label">IMAGEN</label>
            <CardImageUpload value={card.image || ""} onChange={(v) => setField("image", v)} onFile={handleImage} />
          </div>

          <div className="cardadm-field">
            <label className="cardadm-label">RAREZA</label>
            <div className="cardadm-rarity-picker">
              {window.CardSystem.RARITY_LIST.map(r => (
                <button
                  key={r.id}
                  className={"cardadm-rarity-btn" + (card.rarity === r.id ? " active" : "")}
                  style={{ '--rc': r.color }}
                  onClick={() => setField("rarity", r.id)}
                >
                  <span className="cardadm-rdot" style={{ background: r.color }} />
                  {r.label}
                </button>
              ))}
            </div>
          </div>

          <div className="cardadm-field-row">
            <div className="cardadm-field">
              <label className="cardadm-label">CATEGORÍA</label>
              <select
                className="cardadm-select"
                value={card.category || "personaje"}
                onChange={(e) => setField("category", e.target.value)}
              >
                <option value="personaje">Personaje</option>
                <option value="item">Item</option>
                <option value="lugar">Lugar</option>
                <option value="evento">Evento</option>
                <option value="otro">Otro</option>
              </select>
            </div>
          </div>

          <div className="cardadm-field">
            <label className="cardadm-label">FRASE / FLAVOR</label>
            <input
              className="cardadm-input"
              value={card.flavor || ""}
              onChange={(e) => setField("flavor", e.target.value)}
              placeholder="Una frase corta que aparece en la carta"
              maxLength={80}
            />
          </div>

          <div className="cardadm-field">
            <label className="cardadm-label">DESCRIPCIÓN</label>
            <textarea
              className="cardadm-textarea"
              value={card.description || ""}
              onChange={(e) => setField("description", e.target.value)}
              placeholder="Texto extendido (opcional)"
              rows={3}
            />
          </div>

          <div className="cardadm-field">
            <div className="cardadm-rules-header">
              <label className="cardadm-label">DROPS · ¿CUÁNDO APARECE?</label>
              <button className="cardadm-mini-btn" onClick={addRule}>+ AGREGAR DROP</button>
            </div>
            {(card.dropRules || []).length === 0 && (
              <div className="cardadm-rules-empty">
                Sin reglas. Esta carta no aparecerá hasta que agregues al menos un drop.
              </div>
            )}
            {(card.dropRules || []).map((rule) => (
              <DropRuleRow
                key={rule.id}
                rule={rule}
                arcs={arcs}
                onChange={(patch) => updateRule(rule.id, patch)}
                onDelete={() => deleteRule(rule.id)}
              />
            ))}
          </div>
        </div>

        <div className="cardadm-edit-preview">
          <div className="cardadm-preview-label">PREVIEW</div>
          <CardPreviewWithAdjust card={card} onChange={onChange} />
        </div>
      </div>
    </div>
  );
}

function DropRuleRow({ rule, arcs, onChange, onDelete }) {
  const arc = arcs.find(a => String(a.id) === String(rule.arcId));
  const chapters = arc?.chapters || [];

  return (
    <div className="cardadm-rule">
      <select
        className="cardadm-select cardadm-rule-trigger"
        value={rule.trigger}
        onChange={(e) => onChange({ trigger: e.target.value })}
      >
        <option value="chapter">Al leer capítulo</option>
        <option value="arc">Al completar arco</option>
      </select>

      <select
        className="cardadm-select cardadm-rule-arc"
        value={rule.arcId}
        onChange={(e) => {
          const newArc = arcs.find(a => String(a.id) === String(e.target.value));
          onChange({ arcId: e.target.value, chapterId: newArc?.chapters?.[0]?.id || "" });
        }}
      >
        {arcs.length === 0 && <option value="">— sin arcos —</option>}
        {arcs.map(a => (
          <option key={a.id} value={a.id}>{a.num} · {a.title}</option>
        ))}
      </select>

      {rule.trigger === "chapter" && (
        <select
          className="cardadm-select cardadm-rule-ch"
          value={rule.chapterId}
          onChange={(e) => onChange({ chapterId: e.target.value })}
        >
          {chapters.length === 0 && <option value="">— sin capítulos —</option>}
          {chapters.map(c => (
            <option key={c.id} value={c.id}>{c.num} · {c.title}</option>
          ))}
        </select>
      )}

      <div className="cardadm-rule-chance">
        <input
          type="number"
          className="cardadm-input cardadm-chance-input"
          min={1}
          max={100}
          value={rule.chance}
          onChange={(e) => onChange({ chance: Math.max(1, Math.min(100, Number(e.target.value) || 0)) })}
        />
        <span className="cardadm-chance-pct">%</span>
      </div>

      <button className="cardadm-mini-btn cardadm-danger cardadm-rule-x" onClick={onDelete}>×</button>
    </div>
  );
}

function CardPreviewWithAdjust({ card, onChange }) {
  const [adjusting, setAdjusting] = _useState(false);
  const dragRef = React.useRef(null);
  const previewRef = React.useRef(null);

  const ox = card.imageOffsetX ?? 50;
  const oy = card.imageOffsetY ?? 50;
  const scale = card.imageScale ?? 1;

  const startAdjust = () => {
    if (adjusting) { setAdjusting(false); return; }
    setAdjusting(true);
    // If image is wider/taller than card aspect, the cover-fit locks one axis.
    // Bump scale so both axes have slack to pan.
    if (card.image && (card.imageScale ?? 1) === 1) {
      const probe = new Image();
      probe.onload = () => {
        const cardAspect = 0.718; // W/H
        const imgAspect = probe.naturalWidth / probe.naturalHeight;
        // ratio between aspects: how much the locked axis needs to expand
        const lockedAxisStretch = imgAspect > cardAspect
          ? imgAspect / cardAspect    // wider image → height locked, need scale
          : cardAspect / imgAspect;   // taller image → width locked, need scale
        // Cap scale boost so it stays usable
        const boost = Math.min(2, Math.max(1.1, lockedAxisStretch));
        if (Math.abs(boost - 1) > 0.05) {
          onChange({ imageScale: boost });
        }
      };
      probe.src = card.image;
    }
  };

  const onPointerDown = (e) => {
    if (!adjusting || !card.image) return;
    e.preventDefault();
    const target = e.currentTarget;
    target.setPointerCapture?.(e.pointerId);
    const rect = target.getBoundingClientRect();
    dragRef.current = {
      startX: e.clientX,
      startY: e.clientY,
      startOX: ox,
      startOY: oy,
      w: rect.width,
      h: rect.height,
    };
  };

  const onPointerMove = (e) => {
    if (!dragRef.current) return;
    const d = dragRef.current;
    // Drag image: moving right should reveal left side → object-position % decreases
    const dxPct = ((e.clientX - d.startX) / d.w) * 100;
    const dyPct = ((e.clientY - d.startY) / d.h) * 100;
    const nx = Math.max(0, Math.min(100, d.startOX - dxPct));
    const ny = Math.max(0, Math.min(100, d.startOY - dyPct));
    onChange({ imageOffsetX: nx, imageOffsetY: ny });
  };

  const onPointerUp = (e) => {
    dragRef.current = null;
    e.currentTarget.releasePointerCapture?.(e.pointerId);
  };

  const onWheel = (e) => {
    if (!adjusting || !card.image) return;
    e.preventDefault();
    const delta = -e.deltaY * 0.002;
    const next = Math.max(1, Math.min(4, scale + delta));
    onChange({ imageScale: next });
  };

  const reset = () => {
    onChange({ imageOffsetX: 50, imageOffsetY: 50, imageScale: 1 });
  };

  return (
    <>
      <div
        className={"cardadm-preview-card" + (adjusting ? " is-adjusting" : "")}
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={onPointerUp}
        onPointerCancel={onPointerUp}
        onWheel={onWheel}
        style={{ touchAction: adjusting ? "none" : "auto", cursor: adjusting && card.image ? (dragRef.current ? "grabbing" : "grab") : "default" }}
      >
        <window.HoloCard card={card} size="md" enableTilt={!adjusting} />
        {adjusting && card.image && (
          <div className="cardadm-adjust-hint">ARRASTRA · SCROLL = ZOOM</div>
        )}
      </div>

      {card.image && (
        <div className="cardadm-adjust-panel">
          <button
            className={"cardadm-mini-btn" + (adjusting ? " active" : "")}
            onClick={startAdjust}
          >
            {adjusting ? "✓ LISTO" : "✛ AJUSTAR IMAGEN"}
          </button>
          {adjusting && (
            <>
              <div className="cardadm-adjust-row">
                <label className="cardadm-adjust-label">ZOOM</label>
                <input
                  type="range"
                  min={1}
                  max={4}
                  step={0.01}
                  value={scale}
                  onChange={(e) => onChange({ imageScale: Number(e.target.value) })}
                  className="cardadm-adjust-slider"
                />
                <span className="cardadm-adjust-val">{scale.toFixed(2)}×</span>
              </div>
              <div className="cardadm-adjust-row">
                <label className="cardadm-adjust-label">X</label>
                <input
                  type="range"
                  min={0}
                  max={100}
                  step={0.5}
                  value={ox}
                  onChange={(e) => onChange({ imageOffsetX: Number(e.target.value) })}
                  className="cardadm-adjust-slider"
                />
                <span className="cardadm-adjust-val">{Math.round(ox)}%</span>
              </div>
              <div className="cardadm-adjust-row">
                <label className="cardadm-adjust-label">Y</label>
                <input
                  type="range"
                  min={0}
                  max={100}
                  step={0.5}
                  value={oy}
                  onChange={(e) => onChange({ imageOffsetY: Number(e.target.value) })}
                  className="cardadm-adjust-slider"
                />
                <span className="cardadm-adjust-val">{Math.round(oy)}%</span>
              </div>
              <button className="cardadm-mini-btn cardadm-adjust-reset" onClick={reset}>RESET</button>
            </>
          )}
        </div>
      )}
    </>
  );
}

function CardImageUpload({ value, onChange, onFile }) {
  const ref = React.useRef(null);
  const [over, setOver] = _useState(false);

  const handleDrop = (e) => {
    e.preventDefault();
    setOver(false);
    const f = e.dataTransfer.files?.[0];
    if (f) onFile(f);
  };

  return (
    <div
      className={"cardadm-img-upload" + (over ? " is-over" : "")}
      onDragOver={(e) => { e.preventDefault(); setOver(true); }}
      onDragLeave={() => setOver(false)}
      onDrop={handleDrop}
      onClick={() => ref.current?.click()}
    >
      {value ? (
        <>
          <img src={value} alt="" className="cardadm-img-preview" />
          <button
            className="cardadm-img-clear"
            onClick={(e) => { e.stopPropagation(); onChange(""); }}
          >×</button>
        </>
      ) : (
        <div className="cardadm-img-placeholder">
          <div className="cardadm-img-plus">+</div>
          <div className="cardadm-img-hint">CLICK O ARRASTRA UNA IMAGEN</div>
          <div className="cardadm-img-spec">
            <span>Proporción · <b>3:4</b> vertical</span>
            <span>Recomendado · <b>1080×1500 px</b></span>
          </div>
        </div>
      )}
      <input
        ref={ref}
        type="file"
        accept="image/*"
        style={{ display: "none" }}
        onChange={(e) => {
          const f = e.target.files?.[0];
          if (f) onFile(f);
        }}
      />
    </div>
  );
}

window.CardAdmin = CardAdmin;
