/* Working photo controls: drag-to-reposition hook + zoom/adjust editor */
const { useRef: useRefP } = React;

/* Clamp pan offset so you can't drag the image off its frame */
function clampOffset(v, zoom) {
  const lim = Math.max(0, (zoom - 1) * 50);
  return Math.max(-lim, Math.min(lim, v));
}

/* Pointer drag handlers for repositioning the photo directly on the poster */
function usePhotoDrag(design, update) {
  const drag = useRefP(null);
  if (!update) return {}; // non-interactive (e.g. thumbnails)
  const onPointerDown = e => {
    if (!design.photo) return;
    try { e.currentTarget.setPointerCapture(e.pointerId); } catch (_) {}
    const rect = e.currentTarget.getBoundingClientRect();
    const pt = design.photoT || { zoom: 1, ox: 0, oy: 0 };
    drag.current = { x: e.clientX, y: e.clientY, rect, ox: pt.ox, oy: pt.oy, zoom: pt.zoom };
  };
  const onPointerMove = e => {
    if (!drag.current) return;
    const { x, y, rect, ox, oy, zoom } = drag.current;
    const nx = clampOffset(ox + (e.clientX - x) / rect.width * 100, zoom);
    const ny = clampOffset(oy + (e.clientY - y) / rect.height * 100, zoom);
    update({ photoT: { zoom, ox: nx, oy: ny } });
  };
  const onPointerUp = e => {
    drag.current = null;
    try { e.currentTarget.releasePointerCapture(e.pointerId); } catch (_) {}
  };
  return { onPointerDown, onPointerMove, onPointerUp, onPointerCancel: onPointerUp };
}

/* hook: open a file dialog and read an image as dataURL (+ natural dimensions) */
function usePhoto(update) {
  return () => {
    const inp = document.createElement("input");
    inp.type = "file"; inp.accept = "image/*";
    inp.onchange = e => {
      const file = e.target.files && e.target.files[0];
      if (!file) return;
      const r = new FileReader();
      r.onload = () => {
        const src = r.result;
        const img = new Image();
        img.onload = () => update({ photo: src, photoT: { zoom: 1, ox: 0, oy: 0 }, photoMeta: { w: img.naturalWidth, h: img.naturalHeight } });
        img.onerror = () => update({ photo: src, photoT: { zoom: 1, ox: 0, oy: 0 }, photoMeta: null });
        img.src = src;
      };
      r.readAsDataURL(file);
    };
    inp.click();
  };
}

/* Photo resolution / DPI warning for the chosen size */
function PhotoQualityNote({ design, compact }) {
  const q = window.PS_DATA.photoQuality(design);
  if (!q || q.good) {
    if (q && q.good && !compact) {
      return (
        <div style={{ display: "flex", gap: 9, alignItems: "center", padding: "9px 12px", background: "var(--sage-tint)", borderRadius: "var(--r-sm)", color: "#46522F", fontSize: 12.5, fontWeight: 600 }}>
          <Icon name="CircleCheck" size={15} /> Great quality for this size
        </div>
      );
    }
    return null;
  }
  const bad = !q.ok;
  return (
    <div style={{ display: "flex", gap: 9, alignItems: "flex-start", padding: "10px 12px", background: bad ? "#F6E2D2" : "#F3E7C8", border: "1px solid " + (bad ? "#E7C2A6" : "#E2CE97"), borderRadius: "var(--r-sm)", color: bad ? "#8F4124" : "#7A5A14", fontSize: 12.5, fontWeight: 600, lineHeight: 1.4 }}>
      <Icon name="TriangleAlert" size={15} style={{ flex: "none", marginTop: 1 }} />
      <span>{bad ? "This photo may look soft printed at " : "Photo is a little low-res for "}{(window.PS_DATA.SIZES.find(s => s.id === design.size) || {}).label} cm. Use a larger image or zoom out for a crisp print.</span>
    </div>
  );
}

/* open a file dialog and store the image into a specific photo zone */
function uploadToZone(design, update, zid) {
  const inp = document.createElement("input");
  inp.type = "file"; inp.accept = "image/*";
  inp.onchange = e => {
    const file = e.target.files && e.target.files[0]; if (!file) return;
    const r = new FileReader();
    r.onload = () => {
      const src = r.result;
      const img = new Image();
      const commit = meta => update({ photos: { ...(design.photos || {}), [zid]: { src, zoom: 1, ox: 0, oy: 0, meta } } });
      img.onload = () => commit({ w: img.naturalWidth, h: img.naturalHeight });
      img.onerror = () => commit(null);
      img.src = src;
    };
    r.readAsDataURL(file);
  };
  inp.click();
}

/* editor for a single photo zone (used for custom templates incl. collages) */
function PhotoZoneEditor({ design, update, zone, index, total }) {
  const ph = (design.photos || {})[zone.id];
  const open = () => uploadToZone(design, update, zone.id);
  const setZoom = z => {
    const zoom = Math.max(1, Math.min(3, z));
    update({ photos: { ...design.photos, [zone.id]: { ...ph, zoom, ox: clampOffset(ph.ox || 0, zoom), oy: clampOffset(ph.oy || 0, zoom) } } });
  };
  const remove = () => { const next = { ...(design.photos || {}) }; delete next[zone.id]; update({ photos: next }); };

  if (!ph) {
    return (
      <div>
        {total > 1 && <div style={{ fontSize: 11.5, fontWeight: 700, color: "var(--ink-2)", marginBottom: 7 }}>Photo {index + 1}</div>}
        <button className="dropzone" onClick={open} style={{ width: "100%", padding: "20px 16px", display: "flex", flexDirection: "column", alignItems: "center", gap: 8, cursor: "pointer" }}>
          <Icon name="ImageUp" size={24} style={{ color: "var(--clay)" }} />
          <span style={{ fontWeight: 600, fontSize: 14, color: "var(--ink)" }}>{total > 1 ? "Add this photo" : "Upload your photo"}</span>
          <span style={{ fontSize: 12, color: "var(--ink-3)" }}>JPG or PNG · 1500px+ for a crisp print</span>
        </button>
      </div>
    );
  }
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 11, paddingBottom: total > 1 ? 14 : 0, borderBottom: total > 1 && index < total - 1 ? "1px solid var(--line)" : "none" }}>
      <div style={{ display: "flex", gap: 12, alignItems: "center" }}>
        <div style={{ width: 50, height: 50, borderRadius: 9, overflow: "hidden", boxShadow: "var(--sh-sm)", flex: "none" }}>
          <img src={ph.src} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13, fontWeight: 700, color: "var(--ink)" }}>{total > 1 ? "Photo " + (index + 1) : "Your photo"}</div>
          <div style={{ fontSize: 11.5, color: "var(--sage)", fontWeight: 600, display: "flex", alignItems: "center", gap: 5 }}><Icon name="Move" size={12} /> Drag on the poster to reposition</div>
        </div>
        <div style={{ display: "flex", gap: 6 }}>
          <button className="btn btn-soft" style={{ minHeight: 36, padding: "8px 12px", fontSize: 13 }} onClick={open}>Replace</button>
          <button className="btn-icon btn-ghost" style={{ width: 36, height: 36, minHeight: 36 }} title="Remove" onClick={remove}><Icon name="Trash2" size={15} /></button>
        </div>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        <span style={{ fontSize: 11.5, fontWeight: 600, color: "var(--ink-2)", display: "flex", alignItems: "center", gap: 5 }}><Icon name="Search" size={13} /> Zoom</span>
        <button className="btn-icon btn-ghost" style={{ width: 32, height: 32, minHeight: 32 }} onClick={() => setZoom((ph.zoom || 1) - 0.2)}><Icon name="Minus" size={15} /></button>
        <input type="range" className="warm" min={1} max={3} step={0.02} value={ph.zoom || 1} onChange={e => setZoom(parseFloat(e.target.value))} style={{ flex: 1 }} />
        <button className="btn-icon btn-ghost" style={{ width: 32, height: 32, minHeight: 32 }} onClick={() => setZoom((ph.zoom || 1) + 0.2)}><Icon name="Plus" size={15} /></button>
      </div>
    </div>
  );
}

/* Full photo editor used in the Photo tool tray */
function PhotoEditor({ design, update }) {
  // custom template with one or more photo zones → per-zone editors
  if (design.custom && design.zones) {
    const photoZones = design.zones.filter(z => z.type === "photo");
    if (!photoZones.length) {
      return (
        <div style={{ display: "flex", gap: 11, alignItems: "center", padding: "14px 16px", background: "var(--paper-2)", borderRadius: "var(--r-md)", color: "var(--ink-2)", fontSize: 13.5, lineHeight: 1.45 }}>
          <Icon name="Info" size={18} style={{ color: "var(--ink-3)", flex: "none" }} />
          <span>This template has no photo slot — just edit the <b style={{ color: "var(--ink)" }}>Text</b>.</span>
        </div>
      );
    }
    return (
      <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
        {photoZones.map((z, i) => <PhotoZoneEditor key={z.id} design={design} update={update} zone={z} index={i} total={photoZones.length} />)}
      </div>
    );
  }

  // builtin "photo" template → legacy single photo
  const open = usePhoto(update);
  const t = window.PS_DATA.TEMPLATES.find(x => x.id === design.templateId);
  const supported = t && t.kind === "photo";
  const pt = design.photoT || { zoom: 1, ox: 0, oy: 0 };

  if (!supported) {
    return (
      <div style={{ display: "flex", gap: 11, alignItems: "center", padding: "14px 16px", background: "var(--paper-2)", borderRadius: "var(--r-md)", color: "var(--ink-2)", fontSize: 13.5, lineHeight: 1.45 }}>
        <Icon name="Info" size={18} style={{ color: "var(--ink-3)", flex: "none" }} />
        <span>This template is type-only. Switch to the <b style={{ color: "var(--ink)" }}>Photo</b> template to add and position your own image.</span>
      </div>
    );
  }

  if (!design.photo) {
    return (
      <button className="dropzone" onClick={open} style={{ width: "100%", padding: "26px 16px", display: "flex", flexDirection: "column", alignItems: "center", gap: 9, cursor: "pointer" }}>
        <Icon name="ImageUp" size={28} style={{ color: "var(--clay)" }} />
        <span style={{ fontWeight: 600, fontSize: 15, color: "var(--ink)" }}>Upload your photo</span>
        <span style={{ fontSize: 12.5, color: "var(--ink-3)" }}>JPG or PNG · at least 1500px for a crisp print</span>
      </button>
    );
  }

  const setZoom = z => {
    const zoom = Math.max(1, Math.min(3, z));
    update({ photoT: { zoom, ox: clampOffset(pt.ox, zoom), oy: clampOffset(pt.oy, zoom) } });
  };

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      <div style={{ display: "flex", gap: 13, alignItems: "center" }}>
        <div style={{ width: 56, height: 56, borderRadius: 10, overflow: "hidden", boxShadow: "var(--sh-sm)", flex: "none" }}>
          <img src={design.photo} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13.5, fontWeight: 700, color: "var(--ink)" }}>Your photo</div>
          <div style={{ fontSize: 12, color: "var(--sage)", fontWeight: 600, display: "flex", alignItems: "center", gap: 5 }}><Icon name="Move" size={13} /> Drag it on the poster to reposition</div>
        </div>
        <div style={{ display: "flex", gap: 7 }}>
          <button className="btn btn-soft" style={{ minHeight: 38, padding: "9px 14px", fontSize: 13.5 }} onClick={open}>Replace</button>
          <button className="btn-icon btn-ghost" style={{ width: 38, height: 38, minHeight: 38 }} title="Remove" onClick={() => update({ photo: null, photoT: { zoom: 1, ox: 0, oy: 0 } })}><Icon name="Trash2" size={16} /></button>
        </div>
      </div>
      <div>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }}>
          <span style={{ fontSize: 12, fontWeight: 600, color: "var(--ink-2)", display: "flex", alignItems: "center", gap: 6 }}><Icon name="Search" size={14} /> Zoom</span>
          <span style={{ fontSize: 12, color: "var(--ink-3)", fontWeight: 600 }}>{Math.round(pt.zoom * 100)}%</span>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 11 }}>
          <button className="btn-icon btn-ghost" style={{ width: 36, height: 36, minHeight: 36 }} onClick={() => setZoom(pt.zoom - 0.2)}><Icon name="Minus" size={16} /></button>
          <input type="range" className="warm" min={1} max={3} step={0.02} value={pt.zoom} onChange={e => setZoom(parseFloat(e.target.value))} style={{ flex: 1 }} />
          <button className="btn-icon btn-ghost" style={{ width: 36, height: 36, minHeight: 36 }} onClick={() => setZoom(pt.zoom + 0.2)}><Icon name="Plus" size={16} /></button>
        </div>
      </div>
      {(pt.zoom !== 1 || pt.ox !== 0 || pt.oy !== 0) && (
        <button className="btn btn-ghost" style={{ alignSelf: "flex-start", minHeight: 36, padding: "8px 14px", fontSize: 13 }} onClick={() => update({ photoT: { zoom: 1, ox: 0, oy: 0 } })}>
          <Icon name="RotateCcw" size={14} /> Reset position
        </button>
      )}
      <PhotoQualityNote design={design} />
    </div>
  );
}

Object.assign(window, { usePhotoDrag, usePhoto, clampOffset, PhotoEditor, PhotoZoneEditor, PhotoQualityNote });
