// === DetailEditor — 상품 상세설명 블록 에디터 ===
// 상품관리 → 행 클릭 → 상세설명 탭에서 사용.
//
// 블록 모델:
//   { id, type:'image', url, source:'naver'|'isvm'|'pc'|'external', pending?:boolean, error?:string }
//   { id, type:'text',  text }
//   { id, type:'html',  html }   (round-trip 보존용 — 사용자가 직접 편집 가능)
//
// 외부 인터페이스:
//   <DetailEditor
//      initialHtml={cur.detailContent}     // 처음 한 번만 사용 (라이브 데이터)
//      isvmCode={product.sku || ...}       // ISVM 이미지 가져오기 버튼용 (없으면 버튼 숨김)
//      onChange={(html) => setEdit("detailContent", html)} // 블록 변경 즉시 직렬화해서 호출
//   />
// 사용자 입력이 한 글자 바뀔 때마다 호출되므로 onChange는 가벼워야 함.

function _uid() {
  return "b-" + Date.now().toString(36) + "-" + Math.random().toString(36).slice(2, 8);
}

function DetailEditor({ initialHtml, isvmCode, onChange }) {
  // 초기 파싱 — initialHtml은 처음 한 번만 (사용자가 편집 중인데 외부에서 덮으면 안 됨).
  const [blocks, setBlocks] = useState(() => {
    try {
      const parsed = window.API.parseSmartEditorHtml(initialHtml || "");
      return parsed.map(b => ({ ...b, id: b.id || _uid() }));
    } catch (err) {
      console.warn("[DetailEditor] 초기 파싱 실패", err);
      return [];
    }
  });
  const [busy, setBusy] = useState(null);     // { done, total, label }
  const [showPreview, setShowPreview] = useState(false);
  const [showSourceHtml, setShowSourceHtml] = useState(false);
  const fileInputRef = useRef(null);
  const dragSrcId = useRef(null);

  // blocks → HTML 직렬화 후 부모에게 알림 (pending 이미지는 빈 URL로 보내지 말고 그대로 두되 저장 시점에 막음)
  useEffect(() => {
    if (!onChange) return;
    // pending/error는 URL이 있으면 포함, 없으면 스킵
    const cleaned = blocks
      .filter(b => b.type !== "image" || (b.url && !b.error))
      .map(b => {
        if (b.type === "image") return { type: "image", url: b.url };
        if (b.type === "text") return { type: "text", text: b.text || "" };
        if (b.type === "html") return { type: "html", html: b.html || "" };
        return b;
      });
    const html = window.API.buildSmartEditorHtml(cleaned);
    onChange(html);
  }, [blocks]);

  const updateBlock = (id, patch) =>
    setBlocks(prev => prev.map(b => b.id === id ? { ...b, ...patch } : b));
  const removeBlock = (id) =>
    setBlocks(prev => prev.filter(b => b.id !== id));
  const moveBlock = (id, dir) =>
    setBlocks(prev => {
      const idx = prev.findIndex(b => b.id === id);
      if (idx < 0) return prev;
      const target = dir === "up" ? idx - 1 : idx + 1;
      if (target < 0 || target >= prev.length) return prev;
      const next = prev.slice();
      [next[idx], next[target]] = [next[target], next[idx]];
      return next;
    });
  const insertBlockAt = (block, position = -1) =>
    setBlocks(prev => {
      const next = prev.slice();
      if (position < 0 || position > next.length) next.push(block);
      else next.splice(position, 0, block);
      return next;
    });

  // === 블록 추가 액션들 ===
  const addText = () => {
    insertBlockAt({ id: _uid(), type: "text", text: "" });
  };
  const addHtmlBlock = () => {
    insertBlockAt({ id: _uid(), type: "html", html: "" });
  };

  // PC 파일 즉시 업로드 → 네이버 URL 받아서 image 블록 추가
  const handlePcFiles = async (fileList) => {
    const files = Array.from(fileList || []);
    if (files.length === 0) return;
    // 우선 pending 블록들로 placeholder 추가 (사용자가 진행 상황 확인 가능)
    const pendings = files.map(f => ({
      id: _uid(), type: "image", url: "", source: "pc",
      pending: true, fileName: f.name,
    }));
    setBlocks(prev => [...prev, ...pendings]);

    setBusy({ done: 0, total: files.length, label: "PC 이미지 업로드 중" });
    let done = 0;
    for (let i = 0; i < files.length; i++) {
      const f = files[i];
      const id = pendings[i].id;
      try {
        const url = await window.API.naverUploadImageFile(f);
        updateBlock(id, { url, pending: false, error: undefined });
      } catch (err) {
        console.error("[PC 업로드 실패]", f.name, err);
        updateBlock(id, { pending: false, error: err.message || "업로드 실패" });
        toast("이미지 업로드 실패: " + f.name);
      }
      done++;
      setBusy({ done, total: files.length, label: "PC 이미지 업로드 중" });
    }
    setBusy(null);
    toast(files.length + "장 업로드 완료");
  };

  // URL로 이미지 추가 (외부 URL이면 네이버 업로드 거쳐서 변환)
  const addImageFromUrl = async () => {
    const url = window.prompt("이미지 URL을 입력하세요");
    if (!url || !url.trim()) return;
    const trimmed = url.trim();
    const isNaver = /(shop-phinf\.pstatic\.net|phinf\.pstatic\.net|naver\.com)/.test(trimmed);
    if (isNaver) {
      insertBlockAt({ id: _uid(), type: "image", url: trimmed, source: "naver" });
      return;
    }
    // 외부 URL — 프록시 거쳐 네이버로 업로드
    const id = _uid();
    insertBlockAt({ id, type: "image", url: "", source: "external", pending: true });
    setBusy({ done: 0, total: 1, label: "외부 이미지 네이버 업로드 중" });
    try {
      const naverUrl = await window.API.naverUploadImageFromUrl(trimmed);
      updateBlock(id, { url: naverUrl, pending: false, error: undefined });
      toast("이미지 업로드 완료");
    } catch (err) {
      console.error("[URL 업로드 실패]", err);
      updateBlock(id, { pending: false, error: err.message || "업로드 실패" });
      toast("이미지 업로드 실패: " + err.message);
    }
    setBusy(null);
  };

  // ISVM 코드로 다중 이미지 가져오기 — 외부 URL이라 네이버 업로드는 사용자가 "저장 누르기 전 일괄" 또는 즉시
  const importIsvmImages = async () => {
    if (!isvmCode) { toast("ISVM 상품 코드가 없습니다"); return; }
    setBusy({ done: 0, total: 1, label: "ISVM 이미지 조회 중" });
    let isvmImgs = [];
    try {
      isvmImgs = await window.API.isvmFetchProductImages(isvmCode);
    } catch (err) {
      console.error("[ISVM 조회 실패]", err);
      toast("ISVM 이미지 조회 실패: " + err.message);
      setBusy(null);
      return;
    }
    if (!isvmImgs || isvmImgs.length === 0) {
      toast("ISVM에서 가져온 이미지가 없습니다");
      setBusy(null);
      return;
    }
    // 모두 pending 블록으로 일괄 추가
    const pendings = isvmImgs.map(img => ({
      id: _uid(), type: "image", url: "", source: "isvm",
      pending: true, _source_url: img.url,
    }));
    setBlocks(prev => [...prev, ...pendings]);

    // 네이버에 순차 업로드
    let done = 0;
    setBusy({ done: 0, total: isvmImgs.length, label: "ISVM 이미지 네이버에 업로드 중" });
    for (let i = 0; i < isvmImgs.length; i++) {
      const id = pendings[i].id;
      const src = isvmImgs[i].url;
      try {
        const naverUrl = await window.API.naverUploadImageFromUrl(src);
        updateBlock(id, { url: naverUrl, pending: false, error: undefined });
      } catch (err) {
        console.warn("[ISVM→네이버 업로드 실패]", src, err.message);
        updateBlock(id, { pending: false, error: err.message || "업로드 실패" });
      }
      done++;
      setBusy({ done, total: isvmImgs.length, label: "ISVM 이미지 네이버에 업로드 중" });
    }
    setBusy(null);
    toast("ISVM 이미지 " + isvmImgs.length + "장 처리 완료");
  };

  // === 드래그 앤 드롭 (HTML5 native) — 블록 순서 변경 ===
  const onDragStart = (e, id) => {
    dragSrcId.current = id;
    e.dataTransfer.effectAllowed = "move";
    try { e.dataTransfer.setData("text/plain", id); } catch {}
  };
  const onDragOver = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; };
  const onDropOn = (e, targetId) => {
    e.preventDefault();
    const srcId = dragSrcId.current || e.dataTransfer.getData("text/plain");
    if (!srcId || srcId === targetId) return;
    setBlocks(prev => {
      const srcIdx = prev.findIndex(b => b.id === srcId);
      const tgtIdx = prev.findIndex(b => b.id === targetId);
      if (srcIdx < 0 || tgtIdx < 0) return prev;
      const next = prev.slice();
      const [moved] = next.splice(srcIdx, 1);
      next.splice(tgtIdx, 0, moved);
      return next;
    });
    dragSrcId.current = null;
  };

  // === 본체 ===
  const hasPending = blocks.some(b => b.pending);
  const hasError = blocks.some(b => b.error);
  const imageCount = blocks.filter(b => b.type === "image" && b.url).length;
  const previewHtml = window.API.buildSmartEditorHtml(
    blocks.filter(b => b.type !== "image" || (b.url && !b.error))
          .map(b => b.type === "image" ? { type: "image", url: b.url } : b)
  );

  return (
    <div className="detail-editor">
      <div className="detail-editor__toolbar">
        <button className="btn btn-sm" type="button" onClick={addText} disabled={!!busy}>
          <window.I.Plus size={12} /> 텍스트
        </button>
        <button className="btn btn-sm" type="button" onClick={() => fileInputRef.current?.click()} disabled={!!busy}>
          <window.I.Plus size={12} /> 이미지 (PC)
        </button>
        <input ref={fileInputRef} type="file" accept="image/*" multiple style={{ display: "none" }}
               onChange={e => { handlePcFiles(e.target.files); e.target.value = ""; }} />
        <button className="btn btn-sm" type="button" onClick={addImageFromUrl} disabled={!!busy}>
          <window.I.Plus size={12} /> URL
        </button>
        {isvmCode && (
          <button className="btn btn-sm" type="button" onClick={importIsvmImages} disabled={!!busy} title={"ISVM 상품 " + isvmCode + "의 모든 이미지를 일괄로 가져옵니다"}>
            <window.I.Download size={12} /> ISVM 가져오기
          </button>
        )}
        <div className="right" />
        <span className="text-xs muted">
          블록 {blocks.length}개 · 이미지 {imageCount}장
          {hasPending && <> · <strong style={{ color: "var(--warning)" }}>업로드 중</strong></>}
          {hasError && <> · <strong style={{ color: "var(--danger)" }}>오류 있음</strong></>}
        </span>
        <button className={"btn btn-sm " + (showPreview ? "btn-primary" : "")} type="button" onClick={() => setShowPreview(s => !s)} disabled={!!busy}>
          <window.I.Eye size={12} /> 미리보기
        </button>
        <button className={"btn btn-sm " + (showSourceHtml ? "btn-primary" : "")} type="button" onClick={() => setShowSourceHtml(s => !s)} disabled={!!busy}>
          <window.I.Code size={12} /> HTML
        </button>
      </div>

      {busy && (
        <div className="detail-editor__progress">
          <div className="text-xs muted" style={{ marginBottom: 4 }}>
            {busy.label}: {busy.done} / {busy.total}
          </div>
          <div className="detail-editor__progress-bar">
            <div className="detail-editor__progress-fill" style={{ width: (busy.total > 0 ? Math.round(busy.done / busy.total * 100) : 0) + "%" }} />
          </div>
        </div>
      )}

      {showPreview && (
        <div className="detail-editor__preview">
          <div className="text-xs muted" style={{ marginBottom: 6 }}>미리보기 (네이버 표시와 유사)</div>
          <div className="detail-editor__preview-body" dangerouslySetInnerHTML={{ __html: previewHtml }} />
        </div>
      )}

      {showSourceHtml && (
        <div className="detail-editor__source">
          <div className="text-xs muted" style={{ marginBottom: 6 }}>SmartEditor HTML (저장 직전 형태)</div>
          <textarea className="input textarea font-mono" rows={8} value={previewHtml} readOnly
                    style={{ fontSize: 11, lineHeight: 1.4 }} />
        </div>
      )}

      {!showPreview && (
        <div className="detail-editor__blocks">
          {blocks.length === 0 && (
            <div className="detail-editor__empty">
              <div className="text-sm muted">
                상세설명이 비어있습니다. 위 툴바에서 텍스트나 이미지를 추가하세요.
              </div>
            </div>
          )}
          {blocks.map((b, idx) => (
            <div key={b.id}
                 className={"detail-editor__block detail-editor__block--" + b.type + (b.pending ? " is-pending" : "") + (b.error ? " has-error" : "")}
                 draggable={!busy}
                 onDragStart={(e) => onDragStart(e, b.id)}
                 onDragOver={onDragOver}
                 onDrop={(e) => onDropOn(e, b.id)}>
              <div className="detail-editor__block-handle" title="드래그해서 순서 변경">
                <window.I.ChevronUp size={14} />
                <span className="text-xs muted" style={{ fontFamily: "monospace" }}>{idx + 1}</span>
                <window.I.ChevronDown size={14} />
              </div>
              <div className="detail-editor__block-body">
                {b.type === "image" && (
                  <DetailEditorImageBlock block={b} onTextChange={(alt) => updateBlock(b.id, { alt })} />
                )}
                {b.type === "text" && (
                  <textarea
                    className="input textarea"
                    rows={Math.max(2, Math.min(10, ((b.text || "").split(/\n/).length + 1)))}
                    placeholder="텍스트를 입력하세요. 줄바꿈은 그대로 표시됩니다."
                    value={b.text || ""}
                    onChange={e => updateBlock(b.id, { text: e.target.value })}
                  />
                )}
                {b.type === "html" && (
                  <div className="flex-col gap-1">
                    <div className="text-xs muted">원본 HTML (편집 가능)</div>
                    <textarea
                      className="input textarea font-mono"
                      rows={6}
                      placeholder="<div>...</div>"
                      value={b.html || ""}
                      onChange={e => updateBlock(b.id, { html: e.target.value })}
                      style={{ fontSize: 11, lineHeight: 1.4 }}
                    />
                  </div>
                )}
              </div>
              <div className="detail-editor__block-actions">
                <button className="btn btn-icon btn-sm" type="button" onClick={() => moveBlock(b.id, "up")} disabled={idx === 0 || !!busy} title="위로">
                  <window.I.ArrowUp size={12} />
                </button>
                <button className="btn btn-icon btn-sm" type="button" onClick={() => moveBlock(b.id, "down")} disabled={idx === blocks.length - 1 || !!busy} title="아래로">
                  <window.I.ArrowDown size={12} />
                </button>
                <button className="btn btn-icon btn-sm btn-danger" type="button" onClick={() => removeBlock(b.id)} disabled={!!busy} title="삭제">
                  <window.I.Trash size={12} />
                </button>
              </div>
            </div>
          ))}
          {blocks.length > 0 && (
            <div className="detail-editor__add-end">
              <button className="btn btn-sm btn-ghost" type="button" onClick={addText} disabled={!!busy}>
                <window.I.Plus size={12} /> 텍스트 추가
              </button>
              <button className="btn btn-sm btn-ghost" type="button" onClick={() => fileInputRef.current?.click()} disabled={!!busy}>
                <window.I.Plus size={12} /> 이미지 추가
              </button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function DetailEditorImageBlock({ block }) {
  if (block.pending) {
    return (
      <div className="detail-editor__image-pending">
        <div className="detail-editor__spinner" />
        <div className="text-xs muted">
          {block.fileName ? "업로드 중: " + block.fileName : "네이버로 업로드 중..."}
        </div>
      </div>
    );
  }
  if (block.error) {
    return (
      <div className="detail-editor__image-error">
        <window.I.AlertCircle size={20} stroke="var(--danger)" />
        <div className="text-sm" style={{ color: "var(--danger)" }}>업로드 실패: {block.error}</div>
        {block._source_url && <div className="text-xs muted" style={{ wordBreak: "break-all" }}>원본: {block._source_url}</div>}
      </div>
    );
  }
  if (!block.url) {
    return <div className="detail-editor__image-error">URL이 없습니다</div>;
  }
  return (
    <div className="detail-editor__image-preview">
      <img src={block.url} alt="" loading="lazy" />
      <div className="detail-editor__image-meta">
        <span className={"badge " + (block.source === "naver" ? "badge-success" : "")}>
          {block.source === "naver" ? "네이버" : block.source === "isvm" ? "ISVM→네이버" : block.source === "pc" ? "PC→네이버" : "외부→네이버"}
        </span>
        <span className="text-xs muted" style={{ wordBreak: "break-all", fontFamily: "monospace" }}>
          {block.url.length > 80 ? block.url.slice(0, 80) + "…" : block.url}
        </span>
      </div>
    </div>
  );
}

window.DetailEditor = DetailEditor;
