/* detail.jsx — Detail side panel + New Task modal. Exported to window. */

function TagSelect({ kind, value, onChange }) {
  const { Ic, Store } = window;
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  const opts = kind === "cat" ? Store.CATEGORIES : Store.PRIORITIES;
  const meta = opts[value];
  React.useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", h); return () => document.removeEventListener("mousedown", h);
  }, []);
  const I = meta && meta.icon ? Ic[meta.icon] : null;
  return (
    <span ref={ref} style={{ position: "relative", display: "inline-block" }}>
      <button className="tag" style={{ color: meta.color, background: meta.bg, cursor: "pointer" }}
        onClick={() => setOpen(o => !o)} title="Alterar">
        {I && <I size={12} />}{meta.label} <Ic.Chevron size={11} />
      </button>
      {open && (
        <div className="dropdown" style={{ bottom: "auto", top: "calc(100% + 6px)", left: 0, right: "auto", minWidth: 150 }}>
          {Object.entries(opts).map(([k, m]) => {
            const MI = m.icon ? Ic[m.icon] : null;
            return (
              <button key={k} onClick={() => { onChange(k); setOpen(false); window.FX.sfx.play("click"); }}>
                <span className="tag" style={{ color: m.color, background: m.bg }}>{MI && <MI size={12} />}{m.label}</span>
              </button>
            );
          })}
        </div>
      )}
    </span>
  );
}

function Lightbox({ images, index, onClose, onNav, onDelete }) {
  const { Ic, FX } = window;
  const n = images.length;
  const go = (d) => { onNav((index + d + n) % n); FX.sfx.play("click"); };
  React.useEffect(() => {
    const h = (e) => {
      if (e.key === "Escape") onClose();
      else if (e.key === "ArrowRight") go(1);
      else if (e.key === "ArrowLeft") go(-1);
    };
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, [index, n]);
  return (
    <div className="lightbox" onClick={onClose} role="dialog" aria-label="Visualizador de imagem">
      <button className="lb-close" onClick={onClose} aria-label="Fechar"><Ic.Close size={22} /></button>
      <div className="lb-counter">{index + 1} / {n}</div>
      {n > 1 && (
        <button className="lb-nav prev" onClick={(e) => { e.stopPropagation(); go(-1); }} aria-label="Anterior">
          <Ic.Chevron size={26} style={{ transform: "rotate(90deg)" }} />
        </button>
      )}
      <img className="lb-img" src={images[index]} alt={"Imagem " + (index + 1)} onClick={(e) => e.stopPropagation()} />
      {n > 1 && (
        <button className="lb-nav next" onClick={(e) => { e.stopPropagation(); go(1); }} aria-label="Próxima">
          <Ic.Chevron size={26} style={{ transform: "rotate(-90deg)" }} />
        </button>
      )}
      <div className="lb-strip" onClick={(e) => e.stopPropagation()}>
        {images.map((u, i) => (
          <button key={i} className={"lb-dot" + (i === index ? " on" : "")}
            style={{ backgroundImage: `url("${u}")` }} onClick={() => onNav(i)} aria-label={"Imagem " + (i + 1)} />
        ))}
      </div>
      <button className="lb-del" onClick={(e) => { e.stopPropagation(); onDelete(index); }}>
        <Ic.Trash size={15} /> Excluir
      </button>
    </div>
  );
}

function VideoItem({ video, index, onDel }) {
  const { Ic } = window;
  const [playing, setPlaying] = React.useState(false);
  const m = (video.url || "").match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/|shorts\/|live\/|v\/))([\w-]{11})/);
  const ytid = m ? m[1] : null;

  return (
    <div className="vid-item">
      {playing && ytid ? (
        <iframe className="vid-iframe"
          src={"https://www.youtube-nocookie.com/embed/" + ytid + "?autoplay=1&rel=0"}
          title={"Vídeo " + (index + 1)}
          frameBorder="0" loading="lazy"
          allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
          allowFullScreen></iframe>
      ) : (
        <button type="button" className="vid-thumb"
                onClick={() => setPlaying(true)}
                title="Tocar vídeo">
          {ytid ? (
            <img src={"https://img.youtube.com/vi/" + ytid + "/hqdefault.jpg"}
                 alt={"Vídeo " + (index + 1)} loading="lazy"
                 onError={(e) => { e.currentTarget.src = "https://img.youtube.com/vi/" + ytid + "/0.jpg"; }} />
          ) : (
            <div style={{display:"grid",placeItems:"center",height:"100%",color:"var(--txt-3)",fontSize:13}}>Vídeo</div>
          )}
          <span className="vid-play"><Ic.Play size={26} /></span>
        </button>
      )}
      <button className="vid-del" onClick={() => onDel(index)} aria-label="Remover vídeo">
        <Ic.Trash size={15} />
      </button>
      <a className="vid-open-yt" href={video.url} target="_blank" rel="noopener noreferrer">
        Abrir no YouTube ↗
      </a>
    </div>
  );
}

function DetailPanel({ task, onClose, onUpdate, onMoveStatus, onDelete, dispatch }) {
  const { Ic, Store, FX } = window;
  const [newCheck, setNewCheck] = React.useState("");
  const [lightbox, setLightbox] = React.useState(null); // image index | null
  const [dragOver, setDragOver] = React.useState(false);
  const [replaceIdx, setReplaceIdx] = React.useState(null);
  const [vidUrl, setVidUrl] = React.useState("");
  const [vidErr, setVidErr] = React.useState("");
  const titleRef = React.useRef(null);
  const descRef = React.useRef(null);
  const fileRef = React.useRef(null);
  const replaceRef = React.useRef(null);
  if (!task) return null;

  const pct = Store.taskProgress(task);
  const cat = Store.CATEGORIES[task.category];

  const commitTitle = () => {
    const v = titleRef.current.innerText.trim();
    if (v && v !== task.title) onUpdate(task.id, { title: v });
    else titleRef.current.innerText = task.title;
  };
  const commitDesc = () => {
    const v = descRef.current.innerText.trim();
    if (v !== task.desc) onUpdate(task.id, { desc: v });
  };

  const toggleCheck = (cid, done) => {
    dispatch({ type: "TOGGLE_CHECK", id: task.id, cid });
    FX.sfx.play(done ? "uncheck" : "check");
  };
  const addCheck = () => {
    const v = newCheck.trim(); if (!v) return;
    dispatch({ type: "ADD_CHECK", id: task.id, text: v }); setNewCheck("");
  };
  const remaining = 12 - task.images.length;
  const addFiles = (fileList) => {
    const files = [...(fileList || [])].slice(0, remaining);
    if (!files.length) return;
    let added = 0;
    files.forEach(f => FX.readImageFile(f, 1280, (url) => {
      if (url) { dispatch({ type: "ADD_IMAGE", id: task.id, url }); added++; if (added === 1) FX.sfx.play("click"); }
    }));
  };
  const onDrop = (e) => {
    e.preventDefault(); setDragOver(false);
    if (e.dataTransfer && e.dataTransfer.files) addFiles(e.dataTransfer.files);
  };
  const delImage = (i) => { dispatch({ type: "DEL_IMAGE", id: task.id, index: i }); FX.sfx.play("uncheck");
    setLightbox(lb => lb == null ? lb : (i < lb ? lb - 1 : (i === lb ? null : lb))); };
  const pickReplace = (i) => { setReplaceIdx(i); if (replaceRef.current) replaceRef.current.click(); };
  const onReplaceFile = (e) => {
    const f = e.target.files && e.target.files[0]; e.target.value = "";
    if (f == null || replaceIdx == null) return;
    const at = replaceIdx; setReplaceIdx(null);
    FX.readImageFile(f, 1280, (url) => { if (url) { dispatch({ type: "REPLACE_IMAGE", id: task.id, index: at, url }); FX.sfx.play("click"); } });
  };
  const ytId = (url) => {
    if (!url) return null;
    const m = url.match(/(?:youtu\.be\/|youtube\.com\/(?:watch\?v=|embed\/|shorts\/|live\/|v\/))([\w-]{11})/);
    if (m) return m[1];
    if (/^[\w-]{11}$/.test(url.trim())) return url.trim();
    return null;
  };
  const addVideo = () => {
    const id = ytId(vidUrl.trim());
    if (!id) { setVidErr("Cole um link válido do YouTube."); return; }
    dispatch({ type: "ADD_VIDEO", id: task.id, video: { id, url: vidUrl.trim() } });
    setVidUrl(""); setVidErr(""); FX.sfx.play("click");
  };
  const delVideo = (i) => { dispatch({ type: "DEL_VIDEO", id: task.id, index: i }); FX.sfx.play("uncheck"); };
  const videos = task.videos || [];

  return (
    <>
      <div className="scrim" onClick={onClose} />
      <aside className="detail" role="dialog" aria-label={"Tarefa: " + task.title}>
        <button className="detail-close" onClick={onClose} aria-label="Fechar"><Ic.Close size={20} /></button>
        <div className="detail-scroll">
          <h2 ref={titleRef} contentEditable suppressContentEditableWarning
            onBlur={commitTitle}
            onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); titleRef.current.blur(); } }}>
            {task.title}
          </h2>

          <div className="detail-tags">
            <TagSelect kind="cat" value={task.category} onChange={(v) => onUpdate(task.id, { category: v })} />
            <span className="sep">|</span>
            <TagSelect kind="prio" value={task.priority} onChange={(v) => onUpdate(task.id, { priority: v })} />
          </div>

          <div className="section">
            <div className="section-label">Status</div>
            <div className="status-switch">
              {Store.COLUMNS.map(c => (
                <button key={c.id} className={task.status === c.id ? "on" : ""}
                  onClick={() => onMoveStatus(task.id, c.id)}>{c.title}</button>
              ))}
            </div>
          </div>

          <div className="section">
            <h3>Descrição</h3>
            <div className="detail-desc" ref={descRef} contentEditable suppressContentEditableWarning
              onBlur={commitDesc} data-ph="Adicione uma descrição...">
              {task.desc}
            </div>
          </div>

          <div className="section">
            <h3 style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
              <span>Imagens anexadas</span>
              <span style={{ fontSize: 13, fontWeight: 600, color: "var(--txt-3)" }}>{task.images.length}/12</span>
            </h3>
            <div className="gallery">
              {task.images.map((url, i) => (
                <button key={i} className="gal-thumb" style={{ backgroundImage: `url("${url}")` }}
                  onClick={() => { setLightbox(i); FX.sfx.play("click"); }} aria-label={"Ver imagem " + (i + 1)}>
                  <span className="gal-actions">
                    <span className="gal-act" role="button" title="Substituir" aria-label="Substituir imagem"
                      onClick={(e) => { e.stopPropagation(); pickReplace(i); }}>
                      <Ic.Replace size={14} />
                    </span>
                    <span className="gal-act del" role="button" title="Excluir" aria-label="Excluir imagem"
                      onClick={(e) => { e.stopPropagation(); delImage(i); }}>
                      <Ic.Trash size={14} />
                    </span>
                  </span>
                  <span className="gal-zoom"><Ic.Search size={16} /></span>
                </button>
              ))}
              {task.images.length < 12 && (
                <button className={"gal-add" + (dragOver ? " over" : "")}
                  onClick={() => fileRef.current && fileRef.current.click()}
                  onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
                  onDragLeave={() => setDragOver(false)} onDrop={onDrop}>
                  <Ic.Plus size={20} />
                  <span>Anexar</span>
                </button>
              )}
            </div>
            <input ref={fileRef} type="file" accept="image/*" multiple hidden
              onChange={(e) => { addFiles(e.target.files); e.target.value = ""; }} />
            <input ref={replaceRef} type="file" accept="image/*" hidden onChange={onReplaceFile} />
            {task.images.length === 0 && (
              <p className="gal-hint">Clique em "Anexar" ou arraste imagens aqui — até 12. Clique numa imagem para ver em tela cheia.</p>
            )}
          </div>

          <div className="section">
            <h3 style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
              <span>Vídeos</span>
              <span style={{ fontSize: 13, fontWeight: 600, color: "var(--txt-3)" }}>{videos.length}</span>
            </h3>
            <div className="vid-list">
              {videos.map((v, i) => (
                <VideoItem key={v.id + "-" + i} video={v} index={i} onDel={delVideo} />
              ))}
            </div>
            <div className={"vid-add" + (vidErr ? " err" : "")}>
              <Ic.Play size={18} />
              <input value={vidUrl} placeholder="Cole o link do YouTube..."
                onChange={(e) => { setVidUrl(e.target.value); setVidErr(""); }}
                onKeyDown={(e) => { if (e.key === "Enter") addVideo(); }} />
              <button className="vid-add-btn" onClick={addVideo}>Adicionar</button>
            </div>
            {vidErr && <p className="form-err" style={{ marginTop: 8 }}>{vidErr}</p>}
          </div>

          <div className="section">
            <h3 style={{ display: "flex", alignItems: "center", gap: 10 }}>
              Anexos <span className="attach-count"><Ic.Paperclip size={16} /> {task.images.length}</span>
            </h3>
          </div>

          <div className="section">
            <h3 style={{ display:"flex", alignItems:"center", justifyContent:"space-between" }}>
              <span>Checklist</span>
              <span style={{ fontSize: 13, fontWeight: 600, color: pct >= 100 ? "var(--gold)" : "var(--txt-3)" }}>{pct}%</span>
            </h3>
            <div className="check-list">
              {task.checklist.map(c => (
                <div key={c.id} className={"check-item" + (c.done ? " done" : "")}
                  onClick={() => toggleCheck(c.id, c.done)}>
                  <span className="check-box"><Ic.Check size={15} /></span>
                  <span className="check-text">{c.text}</span>
                  <button className="check-del" aria-label="Remover"
                    onClick={(e) => { e.stopPropagation(); dispatch({ type: "DEL_CHECK", id: task.id, cid: c.id }); }}>
                    <Ic.Trash size={15} />
                  </button>
                </div>
              ))}
              <div className="check-add">
                <Ic.Plus size={16} />
                <input value={newCheck} placeholder="Adicionar item..."
                  onChange={e => setNewCheck(e.target.value)}
                  onKeyDown={e => { if (e.key === "Enter") addCheck(); }} onBlur={addCheck} />
              </div>
            </div>
          </div>

          <div className="detail-actions">
            <button className="btn-ghost danger" onClick={() => onDelete(task.id)}>
              <Ic.Trash size={16} /> Excluir tarefa
            </button>
          </div>
        </div>

        <div className="detail-foot">
          <span className="who">
            <Ic.User size={15} /> Criado por {task.createdBy}
          </span>
          <span className="date"><Ic.Calendar size={15} /> {task.createdAt}</span>
        </div>
      </aside>
      {lightbox != null && task.images[lightbox] && (
        <Lightbox images={task.images} index={lightbox}
          onClose={() => setLightbox(null)} onNav={setLightbox} onDelete={delImage} />
      )}
    </>
  );
}

function NewTaskModal({ defaultStatus, onClose, onCreate }) {
  const { Ic, Store } = window;
  const [title, setTitle] = React.useState("");
  const [desc, setDesc] = React.useState("");
  const [category, setCategory] = React.useState("projeto");
  const [priority, setPriority] = React.useState("baixa");
  const [status, setStatus] = React.useState(defaultStatus || "todo");
  const titleRef = React.useRef(null);
  React.useEffect(() => { titleRef.current && titleRef.current.focus(); }, []);

  const submit = (e) => {
    e.preventDefault();
    if (!title.trim()) { titleRef.current.focus(); return; }
    onCreate({ title: title.trim(), desc: desc.trim(), category, priority, status });
  };

  return (
    <div className="modal" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <form className="modal-box" onSubmit={submit}>
        <h2>Nova Tarefa</h2>
        <p className="sub">Adicione uma missão ao seu quadro.</p>

        <div className="field">
          <label>Título</label>
          <input ref={titleRef} className="input" value={title}
            onChange={e => setTitle(e.target.value)} placeholder="Ex: Bug: spawn de veículo" />
        </div>
        <div className="field">
          <label>Descrição</label>
          <textarea className="textarea" value={desc}
            onChange={e => setDesc(e.target.value)} placeholder="Detalhe o que precisa ser feito..." />
        </div>
        <div className="field">
          <label>Categoria</label>
          <div className="seg">
            {Object.entries(Store.CATEGORIES).map(([k, m]) => {
              const I = m.icon ? Ic[m.icon] : null;
              return (
                <button type="button" key={k} className={"seg-btn" + (category === k ? " on" : "")}
                  onClick={() => setCategory(k)}
                  style={category === k ? { color: m.color, borderColor: m.color, background: m.bg } : {}}>
                  {I && <I size={14} />} {m.label}
                </button>
              );
            })}
          </div>
        </div>
        <div className="field">
          <label>Prioridade</label>
          <div className="seg">
            {Object.entries(Store.PRIORITIES).map(([k, m]) => (
              <button type="button" key={k} className={"seg-btn" + (priority === k ? " on" : "")}
                onClick={() => setPriority(k)}
                style={priority === k ? { color: m.color, borderColor: m.color, background: m.bg } : {}}>
                {m.label}
              </button>
            ))}
          </div>
        </div>
        <div className="field">
          <label>Coluna</label>
          <div className="seg">
            {Store.COLUMNS.map(c => (
              <button type="button" key={c.id} className={"seg-btn" + (status === c.id ? " on" : "")}
                onClick={() => setStatus(c.id)}
                style={status === c.id ? { color: "var(--accent)", borderColor: "var(--accent)" } : {}}>
                {c.title}
              </button>
            ))}
          </div>
        </div>

        <div className="modal-foot">
          <button type="button" className="btn-ghost" onClick={onClose}>Cancelar</button>
          <button type="submit" className="btn-primary"><Ic.Plus size={18} /> Criar tarefa</button>
        </div>
      </form>
    </div>
  );
}

Object.assign(window, { DetailPanel, NewTaskModal, TagSelect, Lightbox });
