// Workspace module — starts with the Trello-style task board
const WS_TAGS = { Accounting: "green", Inventory: "blue", Sales: "amber", Rent: "red", HR: "neutral", Manufacturing: "blue", Marketing: "amber" };

function Workspace() {
  const { useState, useEffect } = React;
  const live = !!(window.API && API.active());
  const [tab, setTab] = useState("board");
  const [cols, setCols] = useState(D.workspace.boardCols);
  const [colIds, setColIds] = useState({});
  const [cards, setCards] = useState(live ? [] : D.workspace.cards);
  const [loading, setLoading] = useState(live);
  const [dragId, setDragId] = useState(null);
  const [dragOver, setDragOver] = useState(null);
  const [sel, setSel] = useState(null);
  const [showNew, setShowNew] = useState(false);
  const [newCol, setNewCol] = useState(null);
  const [addingCol, setAddingCol] = useState(false);
  const [colDraft, setColDraft] = useState("");

  // live backend when signed in through the API; demo data otherwise
  useEffect(() => {
    if (!live) return;
    API.tasks.board().then((b) => {
      setCols(b.columns.map((c) => c.name));
      setColIds(Object.fromEntries(b.columns.map((c) => [c.name, c.id])));
      setCards(b.cards);
      setLoading(false);
    }).catch((e) => {
      console.error(e);
      notify(T("ws.errLoadBoard"));
      setCards(D.workspace.cards);
      setLoading(false);
    });
  }, []);

  useEffect(() => { if (!live) { D.workspace.cards = cards; D.workspace.boardCols = cols; } }, [cards, cols]);

  const apiFail = (e) => { console.error(e); notify(T("ws.errServerNotSaved")); };

  const card = sel ? cards.find((c) => c.id === sel) : null;
  const open = cards.filter((c) => c.col !== "Done").length;
  const dueToday = cards.filter((c) => c.col !== "Done" && c.due === "Jun 13").length;

  const move = (id, col) => {
    setCards((cs) => cs.map((c) => (c.id === id ? { ...c, col } : c)));
    if (live && colIds[col]) API.tasks.update(id, { colId: colIds[col] }).catch(apiFail);
  };
  const setTags = (id, tags) => {
    setCards((cs) => cs.map((c) => (c.id === id ? { ...c, tags } : c)));
    if (live) API.tasks.update(id, { tags }).catch(apiFail);
  };
  const appendImages = (id, imgs) => {
    setCards((cs) => cs.map((c) => (c.id === id ? { ...c, images: [...(c.images || []), ...imgs] } : c)));
  };
  const addImages = (id, files) => {
    if (live) {
      API.tasks.uploadImages(id, files).then((imgs) => {
        appendImages(id, imgs);
        notify(TP("ws.imagesAdded", imgs.length));
      }).catch(apiFail);
      return;
    }
    files.forEach((f) => {
      const r = new FileReader();
      r.onload = () => appendImages(id, [{ src: r.result, name: f.name, who: D.user.name, time: "Jun 13" }]);
      r.readAsDataURL(f);
    });
    notify(TP("ws.imagesAdded", files.length));
  };
  const removeImage = (id, img, idx) => {
    setCards((cs) => cs.map((c) => (c.id === id ? { ...c, images: (c.images || []).filter((_, i) => i !== idx) } : c)));
    if (live && img.id) API.tasks.removeImage(img.id).catch(apiFail);
  };
  const postComment = (id, text) => {
    if (live) {
      API.tasks.comment(id, text).then((c) => {
        setCards((cs) => cs.map((x) => (x.id === id ? { ...x, chat: [...(x.chat || []), c] } : x)));
      }).catch(apiFail);
      return;
    }
    setCards((cs) => cs.map((c) => c.id === id
      ? { ...c, chat: [...(c.chat || []), { who: D.user.name, time: "Jun 13 · 11:58", text }] }
      : c));
  };
  const handleDrop = (col) => {
    if (dragId) {
      const c = cards.find((x) => x.id === dragId);
      if (c && c.col !== col) { move(dragId, col); notify(T("ws.movedCard", { title: c.title, col: TV(col) })); }
    }
    setDragId(null); setDragOver(null);
  };

  const addCol = () => {
    const v = colDraft.trim();
    if (!v) { setAddingCol(false); setColDraft(""); return; }
    if (cols.some((c) => c.toLowerCase() === v.toLowerCase())) { notify(T("ws.listExists", { name: v })); return; }
    setCols((cs) => [...cs, v]);
    if (live) API.tasks.createColumn(v).then((c) => setColIds((m) => ({ ...m, [c.name]: c.id }))).catch(apiFail);
    setAddingCol(false); setColDraft("");
    notify(T("ws.listAdded", { name: v }));
  };

  return (
    <div className="page" data-screen-label="Workspace">
      <KpiBar>
        <Stat label={T("ws.openTasks")} value={String(open)} sub={T("ws.cardsOnBoardN", { n: cards.length })} />
        <Stat label={T("ws.dueToday")} value={String(dueToday)} sub={D.today} />
        <Stat label={T("ws.inReview")} value={String(cards.filter((c) => c.col === "Review").length)} sub={T("ws.waitingSignOff")} />
        <Stat label={T("ws.doneThisWeek")} value={String(cards.filter((c) => c.col === "Done").length)} sub={T("ws.keepItUp")} />
      </KpiBar>

      <Tabs active={tab} onChange={setTab} tabs={[
        { id: "board", label: T("ws.taskBoard"), count: open },
        { id: "calendar", label: T("ws.calendar") },
        { id: "mail", label: T("ws.mail"), count: (D.mail || []).filter((m) => m.folder === "inbox" && m.unread).length || null },
        { id: "chat", label: T("ws.chat") },
        { id: "feed", label: T("ws.feed") }
      ]} />

      {tab === "board" ? (
        <div>
          <div className="toolbar" style={{ padding: "0 0 12px" }}>
            <span className="dim" style={{ fontSize: 13 }}>{loading ? T("ws.loadingBoard") : T("ws.dragHint")}</span>
            <Btn variant="primary" icon="plus" onClick={() => { setNewCol(cols[0]); setShowNew(true); }}>{T("ws.newTask")}</Btn>
          </div>
          <div className="kb" style={{ gridTemplateColumns: "repeat(" + cols.length + ", minmax(0, 1fr)) " + (addingCol ? "210px" : "44px") }}>
            {cols.map((col) => {
              const list = cards.filter((c) => c.col === col);
              return (
                <div key={col}
                  className={"kb-col" + (col === "Done" ? " won" : "") + (dragOver === col ? " over" : "")}
                  onDragOver={(e) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; if (dragOver !== col) setDragOver(col); }}
                  onDragLeave={(e) => { if (!e.currentTarget.contains(e.relatedTarget)) setDragOver(null); }}
                  onDrop={(e) => { e.preventDefault(); handleDrop(col); }}>
                  <div className="kb-head">
                    <span>{TV(col)}</span>
                    <span className="kb-meta">{list.length}</span>
                  </div>
                  {list.map((c) => (
                    <button key={c.id} className={"kb-card" + (dragId === c.id ? " dragging" : "")}
                      draggable="true"
                      onDragStart={(e) => { e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("text/plain", c.id); setDragId(c.id); }}
                      onDragEnd={() => { setDragId(null); setDragOver(null); }}
                      onClick={() => setSel(c.id)}>
                      <span className="kb-tagrow">
                        <Badge tone={WS_TAGS[c.tag] || "neutral"}>{c.tag}</Badge>
                        <span className={"kb-due mono" + (c.due === "Jun 13" && col !== "Done" ? " today" : "")}>{c.due}</span>
                      </span>
                      <span className="kb-title">{c.title}</span>
                      {c.desc ? <span className="kb-client">{c.desc}</span> : null}
                      {(c.tags || []).length > 0 ? (
                        <span className="kb-minitags">{c.tags.map((t) => <span key={t} className="kb-minitag">{t}</span>)}</span>
                      ) : null}
                      <span className="kb-foot">
                        <span className="kb-chatn">
                          {(c.chat || []).length > 0 ? <span><Icon name="send" size={11} /> {(c.chat || []).length}</span> : null}
                          {(c.images || []).length > 0 ? <span><Icon name="image" size={11} /> {(c.images || []).length}</span> : null}
                        </span>
                        <Avatar name={c.who} size={22} />
                      </span>
                    </button>
                  ))}
                  <button className="kb-quickadd" onClick={() => { setNewCol(col); setShowNew(true); }}>
                    <Icon name="plus" size={13} /> {T("ws.addTask")}
                  </button>
                </div>
              );
            })}
            {addingCol ? (
              <div className="kb-col kb-addcol">
                <input className="input" autoFocus placeholder={T("ws.listNamePlaceholder")} value={colDraft}
                  onChange={(e) => setColDraft(e.target.value)}
                  onKeyDown={(e) => { if (e.key === "Enter") addCol(); if (e.key === "Escape") { setAddingCol(false); setColDraft(""); } }} />
                <div className="btnrow">
                  <Btn small variant="primary" onClick={addCol}>{T("common.add")}</Btn>
                  <Btn small onClick={() => { setAddingCol(false); setColDraft(""); }}>{T("common.cancel")}</Btn>
                </div>
              </div>
            ) : (
              <button className="kb-add" onClick={() => setAddingCol(true)} title={T("ws.addList")}>
                <Icon name="plus" size={16} />
              </button>
            )}
          </div>
        </div>
      ) : null}

      {tab === "calendar" ? <CalendarTab /> : null}

      {tab === "chat" ? <ChatTab /> : null}

      {tab === "mail" ? <MailTab /> : null}

      {tab === "feed" ? <FeedTab /> : null}

      <Modal open={!!card} onClose={() => setSel(null)} width={620} height="min(92vh, 940px)"
        title={card ? card.title : ""} sub={card ? (card.ref || refNo(card.id)) + " · " + TV(card.tag) : ""}
        footer={card ? (
          <div className="btnrow">
            {card.col !== "Done" ? <Btn variant="primary" icon="check" onClick={() => { move(card.id, "Done"); notify(T("ws.taskCompleted")); setSel(null); }}>{T("ws.markDone")}</Btn> : null}
            <Btn onClick={() => {
              setCards((cs) => cs.filter((c) => c.id !== card.id));
              if (live) API.tasks.remove(card.id).catch(apiFail);
              setSel(null); notify(T("ws.taskDeleted"));
            }}>{T("common.delete")}</Btn>
          </div>
        ) : null}>
        {card ? (
          <div>
            <div className="amount-hero">
              <Badge tone={WS_TAGS[card.tag] || "neutral"}>{card.tag}</Badge>
              <Badge>{card.col}</Badge>
            </div>
            {card.desc ? <p className="drawer-desc" style={{ marginTop: 0 }}>{card.desc}</p> : null}
            <KV k={T("ws.assignee")} v={card.who} />
            <KV k={T("acct.due")} v={card.due + ", 2026"} />
            <div className="lineitems">
              <div className="li-head">{T("ws.moveTo")}</div>
              <div className="chips" style={{ marginTop: 4 }}>
                {cols.map((s) => (
                  <button key={s} className={"chip" + (card.col === s ? " on" : "")} onClick={() => { move(card.id, s); }}>{TV(s)}</button>
                ))}
              </div>
            </div>
            <TaskTags card={card} onChange={(tags) => setTags(card.id, tags)} />
            <TaskImages card={card}
              onFiles={(files) => addImages(card.id, files)}
              onRemove={(img, idx) => removeImage(card.id, img, idx)} />
            <TaskChat card={card} onPost={(text) => postComment(card.id, text)} />
          </div>
        ) : null}
      </Modal>

      <NewTaskModal open={showNew} cols={cols} initialCol={newCol} onClose={() => setShowNew(false)} onCreate={(t) => {
        if (live) {
          API.tasks.create({ ...t, colId: colIds[t.col] }).then((card) => setCards((cs) => [card, ...cs])).catch(apiFail);
        } else {
          setCards((cs) => [t, ...cs]);
        }
        setShowNew(false);
        notify(T("ws.taskAddedTo", { col: TV(t.col) }));
      }} />
    </div>
  );
}

/* ---------- Task tags ---------- */
function TaskTags({ card, onChange }) {
  const { useState } = React;
  const [adding, setAdding] = useState(false);
  const [draft, setDraft] = useState("");
  const tags = card.tags || [];

  const add = () => {
    const v = draft.trim();
    if (!v) { setAdding(false); setDraft(""); return; }
    if (tags.some((t) => t.toLowerCase() === v.toLowerCase())) { notify(T("ws.tagAlreadyOnTask", { name: v })); return; }
    onChange([...tags, v]);
    setDraft("");
    notify(T("ws.tagAdded", { name: v }));
  };

  return (
    <div className="lineitems">
      <div className="li-head">{T("ws.tags")}{tags.length ? " · " + tags.length : ""}</div>
      <div className="ttags">
        {tags.map((t) => (
          <span key={t} className="ttag">
            {t}
            <button onClick={() => { onChange(tags.filter((x) => x !== t)); notify(T("ws.tagRemoved", { name: t })); }} aria-label={T("ws.removeTag", { name: t })}>
              <Icon name="x" size={10} stroke={2.4} />
            </button>
          </span>
        ))}
        {adding ? (
          <input className="input ttag-input" autoFocus placeholder={T("ws.tagNamePlaceholder")} value={draft}
            onChange={(e) => setDraft(e.target.value)}
            onKeyDown={(e) => { if (e.key === "Enter") add(); if (e.key === "Escape") { setAdding(false); setDraft(""); } }}
            onBlur={() => { if (!draft.trim()) setAdding(false); }} />
        ) : (
          <button className="ttag-add" onClick={() => setAdding(true)}>
            <Icon name="tag" size={12} /> {T("ws.addTag")}
          </button>
        )}
      </div>
    </div>
  );
}

/* ---------- Task images ---------- */
function TaskImages({ card, onFiles, onRemove }) {
  const { useState, useRef } = React;
  const [preview, setPreview] = useState(null);
  const fileRef = useRef(null);
  const imgs = card.images || [];

  const pick = (e) => {
    const files = Array.from(e.target.files || [])
      .filter((f) => f.type.startsWith("image/"))
      .filter((f) => {
        if (f.size > 3 * 1024 * 1024) { notify(T("ws.fileTooLarge", { name: f.name })); return false; }
        return true;
      });
    if (files.length) onFiles(files);
    e.target.value = "";
  };

  return (
    <div className="lineitems">
      <div className="li-head">{T("pf.images")}{imgs.length ? " · " + imgs.length : ""}</div>
      <div className="timgs">
        {imgs.map((im, i) => (
          <div key={i} className="timg" role="button" title={im.name} onClick={() => setPreview(im)}>
            <img src={im.src} alt={im.name} />
            <button className="timg-x" aria-label={T("pf.removeImage")}
              onClick={(e) => { e.stopPropagation(); onRemove(im, i); notify(T("ws.imageRemoved")); }}>
              <Icon name="x" size={11} stroke={2.4} />
            </button>
          </div>
        ))}
        <button className="timg-up" onClick={() => fileRef.current && fileRef.current.click()}>
          <Icon name="image" size={18} />
          {T("ws.upload")}
        </button>
      </div>
      <input ref={fileRef} type="file" accept="image/*" multiple style={{ display: "none" }} onChange={pick} />
      {preview ? (
        <div className="scrim center tlightbox" onClick={() => setPreview(null)}>
          <img src={preview.src} alt={preview.name} />
        </div>
      ) : null}
    </div>
  );
}

/* ---------- Task conversation ---------- */
function TaskChat({ card, onPost }) {
  const { useState } = React;
  const [draft, setDraft] = useState("");
  const msgs = card.chat || [];

  const post = () => {
    const v = draft.trim();
    if (!v) return;
    onPost(v);
    setDraft("");
  };

  return (
    <div className="lineitems">
      <div className="li-head">{T("ws.conversation")}{msgs.length ? " · " + msgs.length : ""}</div>
      <div className="tchat">
        {msgs.map((m, i) => (
          <div key={i} className="feed-comment">
            <Avatar name={m.who} size={28} />
            <div className="feed-cbubble">
              <b>{m.who}</b>
              <span>{m.text}</span>
              <small>{TV(m.time)}</small>
            </div>
          </div>
        ))}
        {msgs.length === 0 ? <p className="dim" style={{ margin: 0, fontSize: 12.5 }}>{T("ws.noComments")}</p> : null}
        <div className="feed-comment">
          <Avatar name={D.user.name} size={28} />
          <input className="input feed-cinput" placeholder={T("feed.writeComment")} value={draft}
            onChange={(e) => setDraft(e.target.value)}
            onKeyDown={(e) => { if (e.key === "Enter") post(); }} />
        </div>
      </div>
    </div>
  );
}

function NewTaskModal({ open, cols, initialCol, onClose, onCreate }) {
  const { useState, useEffect } = React;
  const [title, setTitle] = useState("");
  const [desc, setDesc] = useState("");
  const [col, setCol] = useState(initialCol || "To do");
  const [tag, setTag] = useState("Sales");
  const [who, setWho] = useState(D.user.name);
  const [due, setDue] = useState("2026-06-20");
  const [err, setErr] = useState("");

  useEffect(() => { if (open) { setTitle(""); setDesc(""); setCol(initialCol || cols[0]); setTag("Sales"); setWho(D.user.name); setDue("2026-06-20"); setErr(""); } }, [open]);

  const save = () => {
    if (!title.trim()) { setErr(T("ws.errTaskName")); return; }
    onCreate({ id: "TD-32", title: title.trim(), desc: desc.trim(), col, tag, who, due: prettyDate(due), dueIso: due || null, tags: [], images: [], chat: [] });
  };

  return (
    <Modal open={open} onClose={onClose} title={T("ws.newTask")} sub={T("ws.goesToList", { col: TV(col) })}
      footer={<div className="btnrow"><Btn variant="primary" icon="check" onClick={save}>{T("ws.addTask")}</Btn><Btn onClick={onClose}>{T("common.cancel")}</Btn></div>}>
      <Field label={T("ws.task")} error={err}>
        <Input placeholder={T("ws.taskPlaceholder")} value={title} onChange={(e) => setTitle(e.target.value)}
          onKeyDown={(e) => { if (e.key === "Enter") save(); }} />
      </Field>
      <Field label={T("ws.detailsOptional")}>
        <textarea className="input area" rows="2" placeholder={T("ws.detailsPlaceholder")} value={desc} onChange={(e) => setDesc(e.target.value)}></textarea>
      </Field>
      <div className="formgrid">
        <Field label={T("ws.list")}>
          <SearchSelect options={cols} value={col} onChange={setCol} />
        </Field>
        <Field label={T("ws.area")}>
          <SearchSelect options={Object.keys(WS_TAGS)} value={tag} onChange={setTag} />
        </Field>
        <Field label={T("ws.assignee")}>
          <SearchSelect options={["Lena Ortiz", "Tom Vance", "Dana Whitfield", "Ava Reyes", "Noah Brandt", "Priya Nair"]} value={who} onChange={setWho} />
        </Field>
        <Field label={T("acct.due")}>
          <Input type="date" value={due} onChange={(e) => setDue(e.target.value)} />
        </Field>
      </div>
    </Modal>
  );
}
window.Workspace = Workspace;
