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

// ============ ЕТАПИ Й ЗАДАЧІ ============
function PWStages({ obj, tasks, onOpenTask, onToggleTask }) {
  const stages = [...window.DATA.STAGES, ...(window.DATA.CORRECTION_STAGES || [])];
  const objTasks = tasks.filter(t => t.obj === obj.id);
  const [open, setOpen] = React.useState(() => ({ [obj.activeStage]: true }));

  const visible = stages.filter(s => {
    const planned = obj.plan?.[s.id] || 0;
    const has = objTasks.some(t => t.stage === s.id);
    return planned > 0 || has;
  });

  return (
    <div>
      <window.PWStageStrip obj={obj} tasks={tasks} />
      <div style={{ height: 16 }}></div>
      {visible.map(s => {
        const list = objTasks.filter(t => t.stage === s.id);
        const done = list.filter(t => t.status === "done").length;
        const planned = obj.plan?.[s.id] || 0;
        const isActive = s.id === obj.activeStage;
        const isCompleted = obj.completedStages?.includes(s.id) || (planned > 0 && done >= planned);
        const isOpen = open[s.id];
        const isCorr = (s.id || "").startsWith("c-");
        return (
          <div key={s.id} className={`pw-stage ${isActive ? "is-active" : ""} ${isCompleted ? "is-completed" : ""}`}>
            <div className="pw-stage-head" onClick={() => setOpen(o => ({ ...o, [s.id]: !o[s.id] }))}>
              <svg className="pw-stage-caret" width="12" height="12" viewBox="0 0 14 14" fill="none" style={{ transform: isOpen ? "rotate(90deg)" : "none" }}><path d="M5 3l4 4-4 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
              <span className="pw-stage-name">{s.name}</span>
              {isCorr && <span className="status-tag tone-amber">коригування</span>}
              {isActive && !isCompleted && <span className="status-tag tone-live">активний</span>}
              {isCompleted && <span className="status-tag tone-neutral">завершено</span>}
              <span className="pw-stage-count">{done} з {planned || list.length} задач</span>
            </div>
            {isOpen && (
              <div className="pw-stage-body">
                {list.length === 0
                  ? <div className="empty" style={{ padding: "14px 0" }}>Задач ще не створено. Декомпозуйте етап з шаблону.</div>
                  : <div className="task-list">{list.map(t => <window.TaskRow key={t.id} task={t} onOpen={onOpenTask} onToggle={onToggleTask} />)}</div>
                }
                <button className="btn btn-sm" style={{ marginTop: 10 }}>+ Задача в «{s.short}»</button>
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ============ ГРАФІК (реальний Гант по об'єкту) ============
function pwMonths(fromIso, toIso) {
  const res = [];
  let [y, m] = fromIso.split("-").map(Number);
  const [ty, tm] = toIso.split("-").map(Number);
  let guard = 0;
  while ((y < ty || (y === ty && m <= tm)) && guard++ < 48) {
    res.push({ y, m });
    m++; if (m > 12) { m = 1; y++; }
  }
  return res;
}
const PW_MON = ["січ", "лют", "бер", "квіт", "трав", "черв", "лип", "серп", "вер", "жовт", "лист", "груд"];
function pwMoneyShort(n) {
  if (n >= 1e6) return (n / 1e6).toFixed(1).replace(".0", "") + " млн";
  if (n >= 1e3) return Math.round(n / 1e3) + "к";
  return "" + n;
}

function PWGantt({ obj, tasks }) {
  const sched = window.PM.scheduleFor(obj.id);
  if (!sched) return <div className="empty" style={{ padding: 24 }}>Графік для об'єкта ще не сформовано.</div>;
  const months = pwMonths(sched.from, sched.to);
  const span = window.PM.ms(sched.to) - window.PM.ms(sched.from);
  const xPct = (iso) => Math.max(0, Math.min(100, (window.PM.ms(iso) - window.PM.ms(sched.from)) / span * 100));
  const todayFrac = Math.max(0, Math.min(1, (window.PM.ms(window.PM.TODAY_ISO) - window.PM.ms(sched.from)) / span));

  const allStages = [...window.DATA.STAGES, ...(window.DATA.CORRECTION_STAGES || [])];
  const rows = allStages.filter(s => sched.stages[s.id]).map(s => {
    const [start, end] = sched.stages[s.id];
    const planned = obj.plan?.[s.id] || 0;
    const done = tasks.filter(t => t.obj === obj.id && t.stage === s.id && t.status === "done").length;
    const isActive = s.id === obj.activeStage;
    const isCompleted = obj.completedStages?.includes(s.id) || window.PM.ms(end) < window.PM.ms(window.PM.TODAY_ISO) && !isActive;
    return { s, start, end, isActive, isCompleted, planned, done };
  });

  const k = window.PM.contractFor(obj.id);
  const markers = k ? k.schedule
    .filter(s => window.PM.ms(s.dueDate) >= window.PM.ms(sched.from) && window.PM.ms(s.dueDate) <= window.PM.ms(sched.to))
    .map(s => ({ x: xPct(s.dueDate), amount: s.amount, label: s.stage, paid: !!s.paidDate, date: s.dueDate })) : [];

  const LABEL_W = 200;

  return (
    <div>
      <div className="toolbar" style={{ marginBottom: 14 }}>
        <div style={{ fontSize: 13, color: "var(--ink-2)" }}>
          Календарний графік по етапах · {window.formatDate(sched.from)} — {window.formatDate(sched.to)}
        </div>
        <div style={{ marginLeft: "auto", display: "flex", gap: 16, fontSize: 11.5, color: "var(--ink-3)" }}>
          <span className="pw-leg"><span className="pw-leg-sw is-completed"></span>завершено</span>
          <span className="pw-leg"><span className="pw-leg-sw is-active"></span>активний</span>
          <span className="pw-leg"><span className="pw-leg-sw is-future"></span>попереду</span>
          <span className="pw-leg"><span className="pw-leg-diamond"></span>платіж</span>
        </div>
      </div>

      <div className="pw-gantt">
        <div className="pw-gantt-head" style={{ gridTemplateColumns: `${LABEL_W}px 1fr` }}>
          <div className="pw-gantt-corner">Етап</div>
          <div className="pw-gantt-months" style={{ gridTemplateColumns: `repeat(${months.length}, 1fr)` }}>
            {months.map((mo, i) => {
              const isCur = mo.y === 2026 && mo.m === 5;
              return <div key={i} className={`pw-gantt-month ${isCur ? "is-current" : ""}`}>{PW_MON[mo.m - 1]}<span className="pw-gantt-month-yr">{String(mo.y).slice(2)}</span></div>;
            })}
          </div>
        </div>

        <div className="pw-gantt-body">
          <div className="pw-gantt-today" style={{ left: `calc(${LABEL_W}px + (100% - ${LABEL_W}px) * ${todayFrac})` }}>
            <span className="pw-gantt-today-cap">сьогодні</span>
          </div>

          {rows.map(({ s, start, end, isActive, isCompleted, planned, done }) => {
            const left = xPct(start), width = Math.max(2, xPct(end) - xPct(start));
            const cls = isCompleted ? "is-completed" : isActive ? "is-active" : "is-future";
            return (
              <div className="pw-gantt-row" key={s.id} style={{ gridTemplateColumns: `${LABEL_W}px 1fr` }}>
                <div className="pw-gantt-label">
                  <span className="pw-gantt-label-name">{s.name}</span>
                  <span className="pw-gantt-label-sub">{window.PM.dm(start)}—{window.PM.dm(end)}{planned > 0 ? ` · ${done}/${planned}` : ""}</span>
                </div>
                <div className="pw-gantt-track">
                  <div className={`pw-gantt-bar ${cls}`} style={{ left: left + "%", width: width + "%" }} title={`${s.name}: ${window.formatDate(start)} — ${window.formatDate(end)}`}>
                    <span className="pw-gantt-bar-lbl">{s.short}</span>
                  </div>
                </div>
              </div>
            );
          })}

          {markers.length > 0 && (
            <div className="pw-gantt-row pw-gantt-ms" style={{ gridTemplateColumns: `${LABEL_W}px 1fr` }}>
              <div className="pw-gantt-label"><span className="pw-gantt-label-name">Платежі за договором</span></div>
              <div className="pw-gantt-track">
                {markers.map((m, i) => (
                  <div key={i} className={`pw-gantt-marker ${m.paid ? "is-paid" : ""}`} style={{ left: m.x + "%" }} title={`${m.label}: ${window.formatMoney(m.amount)} ₴ · ${window.formatDate(m.date)}${m.paid ? " · сплачено" : ""}`}>
                    <span className="pw-gantt-diamond"></span>
                    <span className="pw-gantt-marker-lbl">{pwMoneyShort(m.amount)}</span>
                  </div>
                ))}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ============ КОМАНДА ОБ'ЄКТА ============
function PWTeam({ obj, tasks }) {
  const objTasks = tasks.filter(t => t.obj === obj.id);
  const sections = window.PM.sectionsFor(obj.id);
  const members = (obj.team || []).map(id => {
    const p = window.getTeam(id);
    const active = objTasks.filter(t => t.assignee === id && t.status !== "done");
    const late = active.filter(t => t.status === "late").length;
    const marks = sections.filter(s => s.lead === id).map(s => s.mark);
    const hours = objTasks.filter(t => t.assignee === id).reduce((a, t) => a + (window.PM.taskExtras(t.id).timeLogged || 0), 0);
    return { p, active: active.length, late, marks, hours };
  });
  const maxActive = Math.max(1, ...members.map(m => m.active));

  return (
    <div>
      <div className="hint-box" style={{ marginTop: 0 }}>
        <b>Команда об'єкта.</b> Хто за які розділи відповідає, скільки активних задач і витрачених годин саме на цьому об'єкті.
      </div>
      <div className="pw-team-cards">
        {members.map(({ p, active, late, marks, hours }) => (
          <div key={p.id} className="pw-tc">
            <div className="pw-tc-top">
              <div className="team-avatar" style={{ width: 40, height: 40, fontSize: 14 }}>{p.initials}</div>
              <div className="pw-tc-id">
                <div className="pw-tc-name">{p.name}</div>
                <div className="pw-tc-role">{p.role}</div>
              </div>
              {p.id === obj.team[0] && <span className="status-tag tone-blue">ГІП</span>}
            </div>
            <div className="pw-tc-marks">
              {marks.length > 0 ? marks.map(m => <span key={m} className="pw-mark pw-mark-sm">{m}</span>)
                : <span className="pw-dash" style={{ fontSize: 12 }}>розділів не веде</span>}
            </div>
            <div className="pw-tc-stats">
              <div className="pw-tc-stat"><div className="pw-tc-num">{active}</div><div className="pw-tc-lbl">активних задач</div></div>
              <div className="pw-tc-stat"><div className={`pw-tc-num ${late > 0 ? "is-late" : ""}`}>{late}</div><div className="pw-tc-lbl">прострочено</div></div>
              <div className="pw-tc-stat"><div className="pw-tc-num">{hours ? hours + " год" : "—"}</div><div className="pw-tc-lbl">витрачено</div></div>
            </div>
            <div className="pw-tc-bar"><div className="pw-tc-bar-fill" style={{ width: (active / maxActive * 100) + "%" }}></div></div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ============ ФІНАНСИ ОБ'ЄКТА ============
function PWFinance({ obj }) {
  const k = window.PM.contractFor(obj.id);
  const expenses = (window.DATA.EXPENSES || []).filter(e => e.obj === obj.id);
  const directCost = expenses.reduce((a, e) => a + (e.amount || 0), 0);
  if (!k) return <div className="empty" style={{ padding: 24 }}>Договір по об'єкту не знайдено.</div>;
  const paid = k.schedule.filter(s => s.paidDate).reduce((a, s) => a + s.amount, 0);
  const overdue = k.schedule.filter(s => !s.paidDate && window.PM.daysTo(s.dueDate) < 0).reduce((a, s) => a + s.amount, 0);
  const remaining = k.total - paid;

  return (
    <div>
      <div className="kpi-row">
        <div className="kpi"><div className="kpi-label">Сума договору</div><div className="kpi-value">{pwMoneyShort(k.total)} <span style={{ fontSize: 14, color: "var(--ink-3)" }}>₴</span></div><div className="kpi-sub">№ {k.number} від {window.formatDate(k.date)}</div></div>
        <div className="kpi"><div className="kpi-label">Оплачено</div><div className="kpi-value" style={{ color: "var(--live)" }}>{pwMoneyShort(paid)} <span style={{ fontSize: 14, color: "var(--ink-3)" }}>₴</span></div><div className="kpi-sub">{Math.round(paid / k.total * 100)}% від суми</div></div>
        <div className={`kpi ${overdue > 0 ? "is-warn" : ""}`}><div className="kpi-label">Прострочена дебіторка</div><div className="kpi-value">{overdue > 0 ? pwMoneyShort(overdue) : "0"} <span style={{ fontSize: 14, color: "var(--ink-3)" }}>₴</span></div><div className="kpi-sub">{overdue > 0 ? "потребує дзвінка" : "усе вчасно"}</div></div>
        <div className="kpi"><div className="kpi-label">Прямі витрати</div><div className="kpi-value">{directCost > 0 ? pwMoneyShort(directCost) : "0"} <span style={{ fontSize: 14, color: "var(--ink-3)" }}>₴</span></div><div className="kpi-sub">субпідряд · експертиза</div></div>
      </div>

      <div className="section-head" style={{ marginTop: 8 }}><h2 className="section-h2">Графік платежів</h2><span className="section-sub">{k.schedule.length} траншів</span></div>
      <table className="data-table">
        <thead><tr><th>Етап оплати</th><th className="num-col">%</th><th className="num-col">Сума</th><th>Термін</th><th>Статус</th></tr></thead>
        <tbody>
          {k.schedule.map((s, i) => {
            const days = window.PM.daysTo(s.dueDate);
            let tone = "neutral", label = "Очікується";
            if (s.paidDate) { tone = "live"; label = "Сплачено"; }
            else if (days < 0) { tone = "warn"; label = `Прострочено ${Math.abs(days)} дн`; }
            else if (days <= 30) { tone = "amber"; label = `Через ${days} дн`; }
            return (
              <tr key={i} className={!s.paidDate && days < 0 ? "row-overdue" : ""}>
                <td><div className="cell-name">{s.stage}</div></td>
                <td className="num-col">{s.pct}%</td>
                <td className="num-col num-bold">{window.formatMoney(s.amount)} ₴</td>
                <td className="td-mono" style={{ fontSize: 12 }}>{window.formatDate(s.dueDate)}{s.paidDate && <div style={{ fontSize: 11, color: "var(--live)" }}>сплач. {window.formatDate(s.paidDate)}</div>}</td>
                <td><span className={`status-tag tone-${tone}`}>{label}</span></td>
              </tr>
            );
          })}
        </tbody>
        <tfoot><tr><td>Разом</td><td className="num-col">100%</td><td className="num-col num-bold">{window.formatMoney(k.total)} ₴</td><td colSpan="2" style={{ color: "var(--ink-3)", fontSize: 12 }}>залишок {window.formatMoney(remaining)} ₴</td></tr></tfoot>
      </table>

      {expenses.length > 0 && (
        <>
          <div className="section-head" style={{ marginTop: 24 }}><h2 className="section-h2">Прямі витрати об'єкта</h2><span className="section-sub">{expenses.length}</span></div>
          <table className="data-table">
            <thead><tr><th>Витрата</th><th>Постачальник</th><th className="num-col">Сума</th><th>Статус</th></tr></thead>
            <tbody>
              {expenses.map(e => (
                <tr key={e.id}>
                  <td><div className="cell-name">{e.title}</div></td>
                  <td style={{ fontSize: 12.5, color: "var(--ink-2)" }}>{e.supplier}</td>
                  <td className="num-col num-bold">{window.formatMoney(e.amount)} ₴</td>
                  <td><span className={`status-tag tone-${e.paid ? "live" : "neutral"}`}>{e.paid ? "сплачено" : "заплановано"}</span></td>
                </tr>
              ))}
            </tbody>
          </table>
        </>
      )}
    </div>
  );
}

// ============ НАГЛЯД ТА ДОЗВІЛЬНІ ============
const PW_SUPERVISION = {
  "ukp-89": [
    { date: "2026-05-26", who: "ok", title: "Перевірка вузлів примикання покрівлі", photos: 8, remarks: 2 },
    { date: "2026-04-15", who: "ok", title: "Контроль монтажу вентиляції", photos: 12, remarks: 0 },
    { date: "2026-03-22", who: "ap", title: "Зварювальні роботи каркасу", photos: 15, remarks: 1 },
    { date: "2026-02-10", who: "ok", title: "Бетонування плит перекриття", photos: 22, remarks: 0 },
  ],
};

function PWSupervision({ obj }) {
  const permits = window.PM.permitsFor(obj.id);
  const journal = PW_SUPERVISION[obj.id] || [];
  const PSTATUS = { received: { t: "live", l: "Отримано" }, pending: { t: "warn", l: "Простій" }, in_progress: { t: "amber", l: "В процесі" } };

  return (
    <div>
      <div className="section-head" style={{ marginTop: 0 }}><h2 className="section-h2">Дозвільні документи та узгодження</h2><span className="section-sub">{permits.length}</span></div>
      {permits.length === 0
        ? <div className="empty">Дозвільних по об'єкту не зафіксовано.</div>
        : <table className="data-table">
            <thead><tr><th>Тип</th><th>Документ</th><th>Орган</th><th>Дата</th><th>Статус</th></tr></thead>
            <tbody>
              {permits.map((p, i) => {
                const st = PSTATUS[p.status] || PSTATUS.pending;
                return (
                  <tr key={i}>
                    <td><span className="doc-type">{p.kind}</span></td>
                    <td><div className="cell-name">{p.title}</div>{p.note && <div className="cell-sub">{p.note}</div>}</td>
                    <td style={{ fontSize: 12.5 }}>{p.body}</td>
                    <td className="td-mono" style={{ fontSize: 12 }}>{window.formatDate(p.date)}</td>
                    <td><span className={`status-tag tone-${st.t}`}>{st.l}</span></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
      }

      <div className="section-head" style={{ marginTop: 24 }}>
        <h2 className="section-h2">Журнал авторського нагляду</h2>
        <span className="section-sub">{journal.length ? `${journal.length} виїздів` : "об'єкт не на нагляді"}</span>
      </div>
      {journal.length === 0
        ? <div className="hint-box" style={{ marginTop: 0 }}>Об'єкт ще не на стадії авторського нагляду. Журнал з'явиться після початку будівництва.</div>
        : <div className="lead-stack">
            {journal.map((e, i) => {
              const p = window.getTeam(e.who);
              return (
                <div key={i} className="lead-card">
                  <div className="lead-card-head">
                    <div className="lead-card-stage"><span className="empl-chip empl-staff">АН</span><span className="td-mono" style={{ fontSize: 12, color: "var(--ink-3)" }}>{window.formatDate(e.date)}</span></div>
                  </div>
                  <div className="lead-card-name">{e.title}</div>
                  <div className="lead-card-meta"><span>{p?.name}</span></div>
                  <div className="lead-card-foot">
                    <div><div className="lead-value-label">фото</div><div className="lead-value-num">{e.photos}</div></div>
                    <div><div className="lead-action-label">зауваження</div><div className="lead-action-text" style={{ color: e.remarks > 0 ? "var(--late)" : "var(--live)", fontWeight: 600 }}>{e.remarks > 0 ? `${e.remarks}` : "немає"}</div></div>
                    <button className="btn btn-ghost">Відкрити</button>
                  </div>
                </div>
              );
            })}
          </div>
      }
    </div>
  );
}

window.PWStages = PWStages;
window.PWGantt = PWGantt;
window.PWTeam = PWTeam;
window.PWFinance = PWFinance;
window.PWSupervision = PWSupervision;
