// project-workspace.jsx — повноцінний робочий простір ОДНОГО об'єкта (екран ГІПа)
// Вкладки: Огляд · Розділи · Етапи й задачі · Графік · Команда · Фінанси · Нагляд
// Вкладки Етапи/Графік/Команда/Фінанси/Нагляд — у project-workspace-tabs.jsx

const PW_TABS = [
  { id: "overview",    label: "Огляд" },
  { id: "sections",    label: "Розділи" },
  { id: "stages",      label: "Етапи й задачі" },
  { id: "gantt",       label: "Графік" },
  { id: "team",        label: "Команда" },
  { id: "finance",     label: "Фінанси" },
  { id: "supervision", label: "Нагляд" },
];

// ---- Зведення ризиків/уваги через усі дані ERP по об'єкту ----
function pwBuildAlerts(obj, tasks) {
  const a = [];
  const objTasks = tasks.filter(t => t.obj === obj.id);
  objTasks.filter(t => t.status === "late").forEach(t =>
    a.push({ tone: "warn", kind: "Прострочено", title: t.title, meta: window.getTeam(t.assignee)?.name || "" }));
  window.PM.sectionsFor(obj.id).filter(s => s.status === "remarks").forEach(s =>
    a.push({ tone: "warn", kind: "Зауваження", title: `${s.mark} · ${s.name}`, meta: s.note || "" }));
  (window.DATA.INVOICES || []).filter(i => i.obj === obj.id && i.status === "overdue").forEach(i =>
    a.push({ tone: "warn", kind: "Дебіторка", title: `Рахунок ${i.number} · ${window.formatMoney(i.amount)} ₴`, meta: `прострочка ${i.lateDays} дн` }));
  window.PM.permitsFor(obj.id).filter(p => p.status === "pending").forEach(p =>
    a.push({ tone: "amber", kind: p.kind, title: p.title, meta: `${p.body}${p.note ? " · " + p.note : ""}` }));
  const k = window.PM.contractFor(obj.id);
  if (k) k.schedule.filter(s => !s.paidDate).forEach(s => {
    const d = window.PM.daysTo(s.dueDate);
    if (d >= 0 && d <= 30) a.push({ tone: "blue", kind: "Платіж", title: `${s.stage} · ${window.formatMoney(s.amount)} ₴`, meta: `через ${d} дн · ${window.PM.dm(s.dueDate)}` });
  });
  (obj.team || []).forEach(id => {
    const p = window.getTeam(id);
    if (p && p.kep) {
      const st = window.kepStatus(p.kep.validUntil);
      if (st.state !== "active") a.push({ tone: st.state === "expired" ? "warn" : "amber", kind: "КЕП", title: p.name, meta: `${st.label.toLowerCase()} · до ${window.formatDate(p.kep.validUntil)}` });
    }
  });
  return a;
}

// ---- Інфо по етапах (для смужки етапів) ----
function pwStageInfo(obj, tasks, stage) {
  const list = tasks.filter(t => t.obj === obj.id && t.stage === stage.id);
  const done = list.filter(t => t.status === "done").length;
  const late = list.filter(t => t.status === "late").length;
  const live = list.filter(t => t.status === "live").length;
  const planned = obj.plan?.[stage.id] || 0;
  const isCompleted = obj.completedStages?.includes(stage.id) || (planned > 0 && done >= planned);
  const isActive = stage.id === obj.activeStage;
  const isSkipped = planned === 0 && !isCompleted && !isActive;
  return { stage, list, done, late, live, planned, total: list.length, isCompleted, isActive, isSkipped };
}

// ======================= ШЕЛЛ =======================
function ProjectWorkspace({ objId, tasks, onOpenTask, onToggleTask, onBack, role }) {
  const obj = window.getObject(objId);
  const [tab, setTab] = React.useState("overview");
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onBack(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onBack]);

  if (!obj) return <div className="page"><div className="empty">Об'єкт не знайдено.</div></div>;

  const client = window.DATA.CLIENTS?.find(c => c.short && obj.client.includes(c.short)) || null;
  const gip = window.getTeam(obj.team?.[0]);
  const scopeLabel = window.EXPERTISE_SCOPE_LABELS?.[obj.expertiseScope]?.label || "—";
  const dlDays = obj.deadlineISO ? window.PM.daysTo(obj.deadlineISO) : null;

  return (
    <div className="page pw">
      {/* ── Хедер об'єкта ── */}
      <div className="pw-top">
        <button className="pw-back" onClick={onBack} title="До списку об'єктів (Esc)">
          <svg width="15" height="15" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
          <span>Об'єкти</span>
        </button>
        <div className="pw-top-main">
          <div className="pw-top-id">
            <span className="pw-code">{obj.code}</span>
            <span className="obj-grade">{obj.grade}</span>
            <span className="pw-scope">{scopeLabel}</span>
          </div>
          <h1 className="pw-name">{obj.name}</h1>
          <div className="pw-top-meta">
            <span>{obj.client}</span>
            <span className="dot"></span>
            <span>{obj.address}</span>
            <span className="dot"></span>
            <span>{obj.workType === "reconstruction" ? "Реконструкція" : obj.workType === "schema" ? "Схема намірів" : "Нове будівництво"}</span>
          </div>
        </div>
        <div className="pw-top-side">
          <div className="pw-top-team">
            {(obj.team || []).map(id => {
              const p = window.getTeam(id);
              return <div key={id} className="team-avatar" title={`${p?.name} · ${p?.role}`} style={{ width: 30, height: 30, fontSize: 11 }}>{p?.initials}</div>;
            })}
          </div>
          <button className="btn btn-ghost">Drive ↗</button>
        </div>
      </div>

      {/* ── Вкладки ── */}
      <div className="tab-bar pw-tabs">
        {PW_TABS.map(tb => {
          let c = null;
          if (tb.id === "sections") c = window.PM.sectionsFor(obj.id).length;
          if (tb.id === "stages") c = tasks.filter(t => t.obj === obj.id && t.status !== "done").length;
          return (
            <button key={tb.id} className={`tab ${tab === tb.id ? "is-active" : ""}`} onClick={() => setTab(tb.id)}>
              {tb.label}{c != null && c > 0 && <span className="tab-count">{c}</span>}
            </button>
          );
        })}
      </div>

      {/* ── Контент ── */}
      {tab === "overview"    && <PWOverview obj={obj} tasks={tasks} gip={gip} client={client} dlDays={dlDays} onOpenTask={onOpenTask} onToggleTask={onToggleTask} setTab={setTab} />}
      {tab === "sections"    && <PWSections obj={obj} tasks={tasks} onOpenTask={onOpenTask} onToggleTask={onToggleTask} />}
      {tab === "stages"      && window.PWStages      && <window.PWStages      obj={obj} tasks={tasks} onOpenTask={onOpenTask} onToggleTask={onToggleTask} />}
      {tab === "gantt"       && window.PWGantt       && <window.PWGantt       obj={obj} tasks={tasks} />}
      {tab === "team"        && window.PWTeam        && <window.PWTeam        obj={obj} tasks={tasks} />}
      {tab === "finance"     && window.PWFinance     && <window.PWFinance     obj={obj} />}
      {tab === "supervision" && window.PWSupervision && <window.PWSupervision obj={obj} />}
    </div>
  );
}

// ======================= СМУЖКА ЕТАПІВ =======================
function PWStageStrip({ obj, tasks }) {
  const stages = window.DATA.STAGES;
  const correction = window.DATA.CORRECTION_STAGES || [];
  const hasCorr = correction.some(s => (obj.plan?.[s.id] || 0) > 0 || tasks.some(t => t.obj === obj.id && t.stage === s.id));
  const renderStrip = (arr, label) => (
    <div className="stage-strip-wrap" style={{ padding: 0, marginTop: label === "Коригування" ? 10 : 0 }}>
      <div className="stage-strip-label">{label}</div>
      <div className="stage-strip">
        {arr.map((s, i) => {
          const info = pwStageInfo(obj, tasks, s);
          const isEstimate = s.id === "expertise" && obj.expertiseScope === "estimate";
          return (
            <React.Fragment key={s.id}>
              {i > 0 && <div className="stage-strip-sep"></div>}
              <div className={`stage-chip ${info.isActive ? "is-active" : ""} ${info.isCompleted ? "is-completed" : ""} ${info.isSkipped ? "is-skipped" : ""} ${info.late > 0 ? "has-late" : ""}`}>
                <div className="stage-chip-head">
                  <span className="stage-chip-name">{s.short}</span>
                  {info.isCompleted && <svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2.5 6.5L4.8 9L9.5 3.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>}
                  {info.isActive && !info.isCompleted && <span className="stage-chip-dot"></span>}
                </div>
                <div className="stage-chip-progress">
                  {info.planned > 0 ? <span>{info.done}<span className="stage-chip-of">/{info.planned}</span></span> : <span className="stage-chip-empty">—</span>}
                </div>
                {isEstimate && <div className="stage-chip-note">тільки кошторис</div>}
                {info.late > 0 && <div className="stage-chip-note is-late">{info.late} прострочено</div>}
                {info.late === 0 && info.live > 0 && <div className="stage-chip-note is-live">{info.live} у роботі</div>}
              </div>
            </React.Fragment>
          );
        })}
      </div>
    </div>
  );
  return (
    <div className="pw-card">
      <div className="pw-card-h">Життєвий цикл об'єкта</div>
      {renderStrip(stages, "Основний цикл")}
      {hasCorr && renderStrip(correction, "Коригування")}
    </div>
  );
}

// ======================= ОГЛЯД =======================
function PWOverview({ obj, tasks, gip, client, dlDays, onOpenTask, onToggleTask, setTab }) {
  const prog = window.PM.sectionProgress(obj.id);
  const sum = window.PM.sectionSummary(obj.id);
  const alerts = pwBuildAlerts(obj, tasks);
  const k = window.PM.contractFor(obj.id);
  const paid = k ? k.schedule.filter(s => s.paidDate).reduce((a, s) => a + s.amount, 0) : 0;
  const total = k ? k.total : 0;
  const paidPct = total ? Math.round(paid / total * 100) : 0;
  const objTasks = tasks.filter(t => t.obj === obj.id);
  const activeTasks = objTasks.filter(t => t.status !== "done").length;
  const activity = window.PM.activityFor(obj.id);

  // Наступні віхи: майбутні платежі + дедлайни розділів
  const milestones = [];
  if (k) k.schedule.filter(s => !s.paidDate).forEach(s => milestones.push({ date: s.dueDate, kind: "Платіж", title: s.stage, val: `${window.formatMoney(s.amount)} ₴` }));
  window.PM.sectionsFor(obj.id).filter(s => !window.PM.SECTION_STATUS[s.status].done && s.due).forEach(s =>
    milestones.push({ date: s.due, kind: "Розділ", title: `${s.mark} · ${s.name}`, val: "" }));
  milestones.sort((a, b) => window.PM.ms(a.date) - window.PM.ms(b.date));
  const nextMs = milestones.filter(m => window.PM.daysTo(m.date) >= -3).slice(0, 6);

  return (
    <div className="pw-grid">
      <div className="pw-main">
        {/* KPI */}
        <div className="kpi-row" style={{ marginBottom: 20 }}>
          <div className="kpi">
            <div className="kpi-label">Готовність документації</div>
            <div className="kpi-value">{prog}<span style={{ fontSize: 16, color: "var(--ink-3)" }}>%</span></div>
            <div className="kpi-sub">{sum.sheets} аркушів · {sum.total} розділів</div>
          </div>
          <div className="kpi">
            <div className="kpi-label">Розділи видано</div>
            <div className="kpi-value">{sum.issued}<span style={{ fontSize: 16, color: "var(--ink-3)" }}>/{sum.total}</span></div>
            <div className="kpi-sub">{sum.remarks > 0 ? <span style={{ color: "var(--late)" }}>{sum.remarks} із зауваженнями</span> : "без зауважень"}</div>
          </div>
          <div className={`kpi ${dlDays != null && dlDays < 7 ? "is-warn" : ""}`}>
            <div className="kpi-label">До дедлайну</div>
            <div className="kpi-value">{dlDays != null ? dlDays : "—"}<span style={{ fontSize: 15, color: "var(--ink-3)" }}> дн</span></div>
            <div className="kpi-sub">{obj.activeStage === "supervision" ? "авт. нагляд" : `здача ${obj.deadline}`}</div>
          </div>
          <div className="kpi">
            <div className="kpi-label">Оплачено за договором</div>
            <div className="kpi-value">{paidPct}<span style={{ fontSize: 16, color: "var(--ink-3)" }}>%</span></div>
            <div className="kpi-sub">{window.formatMoney(paid)} з {window.formatMoney(total)} ₴</div>
          </div>
        </div>

        {/* Потребує уваги */}
        <div className="pw-card">
          <div className="pw-card-h">
            Потребує уваги
            {alerts.length > 0 && <span className="pw-card-count">{alerts.length}</span>}
          </div>
          {alerts.length === 0
            ? <div className="pw-ok"><svg width="15" height="15" viewBox="0 0 12 12" fill="none"><path d="M2.5 6.5L4.8 9L9.5 3.5" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg> За об'єктом усе в нормі — ризиків і прострочень немає.</div>
            : <div className="pw-alerts">
                {alerts.map((al, i) => (
                  <div key={i} className={`pw-alert tone-${al.tone}`}>
                    <span className="pw-alert-dot"></span>
                    <span className="pw-alert-kind">{al.kind}</span>
                    <span className="pw-alert-title">{al.title}</span>
                    {al.meta && <span className="pw-alert-meta">{al.meta}</span>}
                  </div>
                ))}
              </div>
          }
        </div>

        <PWStageStrip obj={obj} tasks={tasks} />

        {/* Наступні віхи */}
        <div className="pw-card">
          <div className="pw-card-h">Наступні віхи</div>
          <div className="pw-ms">
            {nextMs.length === 0 ? <div className="empty" style={{ padding: "8px 0" }}>Найближчих віх немає.</div> :
              nextMs.map((m, i) => {
                const d = window.PM.daysTo(m.date);
                const over = d < 0;
                return (
                  <div key={i} className="pw-ms-row">
                    <div className={`pw-ms-date ${over ? "is-over" : ""}`}>
                      <span className="pw-ms-dm">{window.PM.dm(m.date)}</span>
                      <span className="pw-ms-dd">{over ? `${Math.abs(d)} дн тому` : d === 0 ? "сьогодні" : `через ${d} дн`}</span>
                    </div>
                    <span className={`pw-ms-kind ${m.kind === "Платіж" ? "is-pay" : ""}`}>{m.kind}</span>
                    <span className="pw-ms-title">{m.title}</span>
                    {m.val && <span className="pw-ms-val">{m.val}</span>}
                  </div>
                );
              })}
          </div>
        </div>
      </div>

      {/* Права колонка */}
      <div className="pw-rail">
        <div className="pw-card">
          <div className="pw-card-h">Паспорт об'єкта</div>
          <dl className="info-grid pw-passport">
            <div><dt>Шифр</dt><dd className="td-mono">{obj.code}</dd></div>
            <div><dt>Клас наслідків</dt><dd>{obj.grade} · {obj.gradeKind === "calculated" ? "розрахунок" : "попередній"}</dd></div>
            <div><dt>Замовник</dt><dd>{obj.client}</dd></div>
            <div><dt>Договір</dt><dd>{obj.contract}</dd></div>
            <div><dt>Активний етап</dt><dd>{window.getStage(obj.activeStage)?.name}</dd></div>
            <div><dt>Ревізія</dt><dd>{obj.revision}</dd></div>
            <div><dt>ГІП</dt><dd>{gip?.name || "—"}</dd></div>
            <div><dt>Активних задач</dt><dd>{activeTasks}</dd></div>
          </dl>
        </div>

        <div className="pw-card">
          <div className="pw-card-h">Команда об'єкта</div>
          <div className="pw-team">
            {(obj.team || []).map(id => {
              const p = window.getTeam(id);
              const mine = objTasks.filter(t => t.assignee === id && t.status !== "done").length;
              const late = objTasks.filter(t => t.assignee === id && t.status === "late").length;
              return (
                <div key={id} className="pw-team-row">
                  <div className="team-avatar" style={{ width: 30, height: 30, fontSize: 11 }}>{p?.initials}</div>
                  <div className="pw-team-meta">
                    <div className="pw-team-name">{p?.name}</div>
                    <div className="pw-team-role">{p?.role}</div>
                  </div>
                  <div className="pw-team-tasks">
                    <span>{mine} задач</span>
                    {late > 0 && <span className="pw-team-late">{late} простр.</span>}
                  </div>
                </div>
              );
            })}
          </div>
        </div>

        <div className="pw-card">
          <div className="pw-card-h">Активність</div>
          <div className="pw-feed">
            {activity.map((ev, i) => {
              const p = window.getTeam(ev.by);
              return (
                <div key={i} className="pw-feed-row">
                  <div className="team-avatar" style={{ width: 24, height: 24, fontSize: 9 }}>{p?.initials}</div>
                  <div className="pw-feed-body">
                    <div className="pw-feed-text"><b>{p?.name?.split(" ")[0]}</b> {ev.text}</div>
                    <div className="pw-feed-date">{ev.date}</div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

// ======================= РОЗДІЛИ (склад документації) =======================
function PWSections({ obj, tasks, onOpenTask, onToggleTask }) {
  const sections = window.PM.sectionsFor(obj.id);
  const SS = window.PM.SECTION_STATUS;
  const [filter, setFilter] = React.useState("all");
  const [openMark, setOpenMark] = React.useState(null);
  const sum = window.PM.sectionSummary(obj.id);

  const filters = [
    { id: "all", label: "Усі" },
    { id: "active", label: "У роботі" },
    { id: "review", label: "Нормоконтроль" },
    { id: "remarks", label: "Зауваження" },
    { id: "issued", label: "Видано" },
  ];
  const match = (s) => {
    if (filter === "all") return true;
    if (filter === "active") return s.status === "in_progress" || s.status === "not_started";
    if (filter === "review") return s.status === "review";
    if (filter === "remarks") return s.status === "remarks";
    if (filter === "issued") return SS[s.status].done || s.status === "expertise";
    return true;
  };
  const rows = sections.filter(match);

  return (
    <div>
      <div className="hint-box" style={{ marginTop: 0 }}>
        <b>Склад проєктної документації.</b> Реєстр марок (розділів) з виконавцем, нормоконтролем, ревізією та готовністю.
        Натисніть на рядок — побачите примітку і задачі по розділу.
      </div>

      <div className="toolbar">
        <div className="filter-pill" role="tablist">
          {filters.map(f => (
            <button key={f.id} className={`filter-pill-item ${filter === f.id ? "is-active" : ""}`} onClick={() => setFilter(f.id)}>
              <span className="filter-pill-label">{f.label}</span>
            </button>
          ))}
        </div>
        <div style={{ marginLeft: "auto", fontSize: 12.5, color: "var(--ink-3)" }}>
          {sum.total} розділів · <b style={{ color: "var(--live)" }}>{sum.issued} видано</b> · {sum.sheets} аркушів
        </div>
      </div>

      <div className="pw-sec-table">
        <div className="pw-sec-head">
          <div className="pw-sec-c-mark">Марка</div>
          <div className="pw-sec-c-name">Розділ</div>
          <div className="pw-sec-c-people">Виконавець · НК</div>
          <div className="pw-sec-c-status">Статус</div>
          <div className="pw-sec-c-rev">Зм.</div>
          <div className="pw-sec-c-sheets">Арк.</div>
          <div className="pw-sec-c-prog">Готовність</div>
          <div className="pw-sec-c-due">Дедлайн</div>
        </div>
        {rows.map(s => {
          const meta = SS[s.status];
          const lead = window.getTeam(s.lead);
          const checker = window.getTeam(s.checker);
          const open = openMark === s.mark;
          const dueDays = s.due ? window.PM.daysTo(s.due) : null;
          const dueOver = dueDays != null && dueDays < 0 && !meta.done;
          const secTasks = tasks.filter(t => t.obj === obj.id && t.section === s.mark);
          return (
            <div key={s.mark} className={`pw-sec-group ${open ? "is-open" : ""}`}>
              <div className={`pw-sec-row tone-${meta.tone}`} onClick={() => setOpenMark(open ? null : s.mark)}>
                <div className="pw-sec-c-mark"><span className="pw-mark">{s.mark}</span></div>
                <div className="pw-sec-c-name">
                  <div className="pw-sec-name">{s.name}</div>
                  {s.note && <div className="pw-sec-note">{s.note}</div>}
                </div>
                <div className="pw-sec-c-people">
                  <div className="pw-people">
                    <span className="team-avatar" style={{ width: 24, height: 24, fontSize: 9 }} title={`Виконавець: ${lead?.name}`}>{lead?.initials}</span>
                    <span className="pw-people-sep">·</span>
                    <span className="team-avatar pw-av-ghost" style={{ width: 24, height: 24, fontSize: 9 }} title={`Нормоконтроль: ${checker?.name}`}>{checker?.initials}</span>
                  </div>
                </div>
                <div className="pw-sec-c-status"><span className={`status-tag tone-${meta.tone}`}>{meta.label}</span></div>
                <div className="pw-sec-c-rev">{s.rev > 0 ? <span className="pw-rev">Зм.{s.rev}</span> : <span className="pw-dash">—</span>}</div>
                <div className="pw-sec-c-sheets td-mono">{s.sheets || "—"}</div>
                <div className="pw-sec-c-prog">
                  <div className="pw-prog">
                    <div className="pw-prog-bar"><div className={`pw-prog-fill ${meta.done ? "is-done" : ""}`} style={{ width: s.pct + "%" }}></div></div>
                    <span className="pw-prog-val">{s.pct}%</span>
                  </div>
                </div>
                <div className={`pw-sec-c-due td-mono ${dueOver ? "is-over" : ""}`}>{s.due ? window.PM.dm(s.due) : "—"}</div>
              </div>
              {open && (
                <div className="pw-sec-expand">
                  <div className="pw-sec-expand-grid">
                    <div><span className="pw-kv-k">Виконавець</span><span className="pw-kv-v">{lead?.name} · {lead?.role}</span></div>
                    <div><span className="pw-kv-k">Нормоконтроль</span><span className="pw-kv-v">{checker?.name}</span></div>
                    <div><span className="pw-kv-k">Ревізія</span><span className="pw-kv-v">{s.rev > 0 ? `Зміна ${s.rev}` : "Перша редакція"}</span></div>
                    <div><span className="pw-kv-k">Дедлайн</span><span className="pw-kv-v">{s.due ? window.formatDate(s.due) : "—"}{dueDays != null && !meta.done ? ` · ${dueDays < 0 ? Math.abs(dueDays) + " дн прострочки" : "через " + dueDays + " дн"}` : ""}</span></div>
                  </div>
                  <div className="pw-sec-tasks-h">Задачі розділу{secTasks.length > 0 ? ` · ${secTasks.length}` : ""}</div>
                  {secTasks.length === 0
                    ? <div className="empty" style={{ padding: "10px 0" }}>Окремих задач по розділу ще не створено.</div>
                    : <div className="task-list">{secTasks.map(t => <window.TaskRow key={t.id} task={t} onOpen={onOpenTask} onToggle={onToggleTask} />)}</div>
                  }
                  <button className="btn btn-sm" style={{ marginTop: 10 }}>+ Задача в розділ {s.mark}</button>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

window.ProjectWorkspace = ProjectWorkspace;
window.PWStageStrip = PWStageStrip;
