// Management Dashboard - KPI cards + donut + bar + line + drill-down

const DashboardPage = ({ tenant, period, setPeriod, tasks, taskHistory, subprocesses, users, positions, departments, divisions, mainProcesses, processes, onGoMatrix, tweaks }) => {
  const [statusFilter, setStatusFilter] = useState(null); // drill-down
  const [deptFilter, setDeptFilter] = useState(null);
  const [divFilter, setDivFilter] = useState(null);
  const [posFilter, setPosFilter] = useState(null);

  const THAI_MONTHS = ["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."];
  const periodLabel = `${THAI_MONTHS[period.month-1]} ${period.year+543}`;
  const ymKey = `${period.year}-${String(period.month).padStart(2,"0")}`;

  // ---- Build "period tasks": enumerate EVERY due date in the selected month using isDueOn ----
  // For each (sub-process, due-date) pair:
  //   - if history has an entry for that date → use its status (P/A/C/S)
  //   - else if date <= today → status="P" (รอจัดทำ — work needed, not yet done)
  //   - else (future) → status="blank" (ยังไม่ถึงกำหนด)
  // Past blank instances are marked overdue (R hasn't done overdue work).
  // ad-hoc tasks: use current snapshot directly (no scheduled due dates).
  const periodTasks = useMemo(() => {
    const out = [];
    const today = window.TODAY || new Date().toISOString().slice(0, 10);
    const [yearStr, monthStr] = ymKey.split("-");
    const year = parseInt(yearStr, 10);
    const month = parseInt(monthStr, 10);
    const daysInMonth = window.lastDayOfMonth ? window.lastDayOfMonth(year, month) : new Date(year, month, 0).getDate();

    subprocesses.forEach(sp => {
      if (sp.track_status === false) return; // "ดูอย่างเดียว" — exclude from KPIs

      if (sp.frequency === "ad-hoc") {
        // ad-hoc: use snapshot. Only count if it has a real status (started).
        const cur = tasks.find(t => t.sub_process_id === sp.id);
        if (cur && cur.status && cur.status !== "blank") {
          out.push({
            sub_process_id: sp.id, status: cur.status,
            due_date: cur.due_date || today, updated: cur.updated || "",
            overdue: !!cur.overdue && cur.status !== "S", frequency: sp.frequency,
          });
        }
        return;
      }

      const hist = taskHistory?.[sp.id] || [];
      for (let d = 1; d <= daysInMonth; d++) {
        const dateStr = `${ymKey}-${String(d).padStart(2, "0")}`;
        if (!window.isDueOn(sp, dateStr)) continue;

        const histEntry = hist.find(h => h.date === dateStr);
        const isPast = dateStr < today;
        const isToday = dateStr === today;

        let status, updated, overdue;
        if (histEntry) {
          status = histEntry.status || "blank";
          updated = histEntry.updated || "";
          overdue = isPast && status !== "S";
        } else if (isPast || isToday) {
          status = "P"; // due but no one has done it yet
          updated = "";
          overdue = isPast;
        } else {
          status = "blank"; // future, not yet due
          updated = "";
          overdue = false;
        }

        out.push({
          sub_process_id: sp.id, status, due_date: dateStr, updated,
          overdue, frequency: sp.frequency,
        });
      }
    });
    return out;
  }, [subprocesses, taskHistory, tasks, ymKey]);

  // Apply division / department / position filter to periodTasks.
  // Position filter (strict — "งานที่ฉันต้องลงมือ"): keep ONLY tasks where the position
  // is R (ผู้จัดทำ) or A (ผู้ตรวจสอบ). C/I are observer roles and are excluded so
  // KPI counts reflect the user's actionable workload.
  // Each kept task is tagged `_role` = "R" or "A" so downstream KPIs can be role-aware.
  const filteredTasks = useMemo(() => {
    const out = [];
    periodTasks.forEach(t => {
      const sp = subprocesses.find(s => s.id === t.sub_process_id);
      if (!sp) return;
      const pos = positions.find(p => p.id === sp.R);
      if (!pos) return;
      if (divFilter && pos.division_id !== divFilter) return;
      if (deptFilter && pos.department_id !== deptFilter) return;
      let role = null;
      if (posFilter) {
        if (sp.R === posFilter) role = "R";
        else if (sp.A === posFilter) role = "A";
        else return; // C / I → excluded under Option A
      }
      out.push({ ...t, _role: role });
    });
    return out;
  }, [periodTasks, subprocesses, positions, divFilter, deptFilter, posFilter]);

  // Helper — is the position "actively responsible" for tasks in this status?
  //   R cares about: P (รอจัดทำ — เขาต้องทำ), C (แก้ไข — เขาต้องแก้), S (สำเร็จ), blank (รออนาคต)
  //   A cares about: A (รอตรวจ — เขาต้องอนุมัติ), S (สำเร็จ), blank (รออนาคต)
  // Returns true when no position filter is set (count everything).
  const isActiveForRoleStatus = (role, status) => {
    if (!role) return true; // no position filter → no role-aware gating
    if (role === "R") return status === "P" || status === "C" || status === "S" || status === "blank";
    if (role === "A") return status === "A" || status === "S" || status === "blank";
    return false;
  };

  // KPI counts — role-aware when a Position filter is active.
  //   total : same role-aware logic as the per-status cards so they always sum to total
  //           (e.g. Sales Manager who is A on a P-status task isn't counted as "their" task)
  //   per-status: only count if the position is the "active" owner of that status
  const counts = useMemo(() => {
    let total = 0;
    const by = { blank:0, P:0, A:0, C:0, S:0, overdue:0 };
    filteredTasks.forEach(t => {
      if (isActiveForRoleStatus(t._role, t.status)) {
        total++;
        by[t.status] = (by[t.status] || 0) + 1;
        if (t.overdue && t.status !== "S") by.overdue++;
      }
    });
    return { total, ...by };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [filteredTasks]);

  const completionRate = counts.total ? Math.round(counts.S / counts.total * 100) : 0;

  // status distribution (donut)
  const donut = [
    { k:"S", l:"สำเร็จ", v:counts.S, color:"#10b981" },
    { k:"A", l:"รอตรวจสอบ", v:counts.A, color:"#7c3aed" },
    { k:"P", l:"รอจัดทำ", v:counts.P, color:"#3b82f6" },
    { k:"C", l:"มี Comment", v:counts.C, color:"#f59e0b" },
    { k:"blank", l:"ยังไม่ถึงกำหนด", v:counts.blank, color:"#cbd5e1" },
  ];

  // dept completion (bar)
  const deptStats = useMemo(() => {
    const map = {};
    filteredTasks.forEach(t => {
      const sp = subprocesses.find(s => s.id === t.sub_process_id);
      if (!sp) return;
      const pos = positions.find(p => p.id === sp.R);
      if (!pos) return;
      const d = departments.find(dp => dp.id === pos.department_id);
      if (!d) return;
      if (!map[d.id]) map[d.id] = { id:d.id, name:d.name, short:d.short, total:0, s:0, c:0, a:0, p:0, b:0 };
      map[d.id].total++;
      if (t.status==="S") map[d.id].s++;
      else if (t.status==="C") map[d.id].c++;
      else if (t.status==="A") map[d.id].a++;
      else if (t.status==="P") map[d.id].p++;
      else map[d.id].b++;
    });
    return Object.values(map).map(d => ({ ...d, pct: d.total ? Math.round(d.s/d.total*100) : 0 })).sort((a,b)=>b.pct-a.pct);
  }, [filteredTasks, subprocesses, positions, departments]);

  // monthly trend — compute from taskHistory across the last 6 months
  const trend = useMemo(() => {
    const months = [];
    for (let i = 5; i >= 0; i--) {
      const d = new Date(period.year, period.month - 1, 1);
      d.setMonth(d.getMonth() - i);
      const key = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}`;
      let total = 0, s = 0;
      subprocesses.forEach(sp => {
        const hist = taskHistory?.[sp.id] || [];
        hist.filter(h => h.date.slice(0,7) === key).forEach(h => {
          const pos = positions.find(p => p.id === sp.R);
          if (divFilter && pos?.division_id !== divFilter) return;
          if (deptFilter && pos?.department_id !== deptFilter) return;
          total++; if (h.status === "S") s++;
        });
      });
      months.push({ m: THAI_MONTHS[d.getMonth()], key, rate: total ? Math.round(s/total*100) : 0, total });
    }
    return months;
  }, [taskHistory, subprocesses, positions, period, divFilter, deptFilter]);

  // Top 10 waiting approval — when filtering by position, only show tasks where
  // that position is the A (the one expected to approve), not just any A-status task.
  const waitingApproval = useMemo(() => {
    return filteredTasks
      .filter(t => t.status === "A" && (!posFilter || t._role === "A"))
      .slice(0, 10)
      .map(t => {
        const sp = subprocesses.find(s=>s.id===t.sub_process_id);
        const r = positions.find(p=>p.id===sp?.R);
        const a = positions.find(p=>p.id===sp?.A);
        const rUser = users.find(u=>u.positions.includes(sp?.R));
        const aUser = users.find(u=>u.positions.includes(sp?.A));
        return { ...t, sp, r, a, rUser, aUser };
      });
  }, [filteredTasks, subprocesses, positions, users, posFilter]);

  // filtered drill-down list — same role-aware rule as KPI counts when statusFilter active
  const drillRows = useMemo(() => {
    return filteredTasks.filter(t => {
      if (statusFilter && t.status !== statusFilter) return false;
      if (statusFilter && !isActiveForRoleStatus(t._role, statusFilter)) return false;
      return true;
    }).map(t => {
      const sp = subprocesses.find(s=>s.id===t.sub_process_id);
      const proc = processes.find(p=>p.id===sp?.process_id);
      const mp = mainProcesses.find(m=>m.id===sp?.main_process_id);
      const r = positions.find(p=>p.id===sp?.R);
      const a = positions.find(p=>p.id===sp?.A);
      const rUser = users.find(u=>u.positions.includes(sp?.R));
      const aUser = users.find(u=>u.positions.includes(sp?.A));
      return { task:t, sp, proc, mp, r, a, rUser, aUser };
    });
  }, [filteredTasks, statusFilter, subprocesses, processes, mainProcesses, positions, users]);

  const hasAnyFilter = divFilter || deptFilter || posFilter || statusFilter;

  return (
    <div className="p-6 space-y-5">
      <PageHeader
        eyebrow={`${tenant.company_short} · ${periodLabel}`}
        title="Management Dashboard"
        subtitle="ภาพรวมสถานะการจัดทำงานตามหลัก RACI Matrix"
        right={<>
          <Button icon="download" variant="secondary" onClick={()=>{
            downloadCsv(`${tenant.tenant_code}_dashboard_${period.year}-${String(period.month).padStart(2,"0")}.csv`,
              ["Sub-process","Main Process","Process","R","A","Due","Status","Last Update"],
              drillRows.map(r => [r.sp.name, r.mp?.name, r.proc?.name, r.rUser?.full_name||"", r.aUser?.full_name||"", r.task.due_date, STATUS_META[r.task.status]?.label, r.task.updated||""]));
          }}>ส่งออกรายงาน</Button>
          <Button icon="arrowRight" onClick={()=>onGoMatrix()}>เปิด RACI Matrix</Button>
        </>}
      />

      {/* Filter bar */}
      <div className="bg-white rounded-2xl border border-ink-100 px-4 py-3 flex items-center gap-3 flex-wrap">
        <div className="flex items-center gap-2 text-[12px] text-ink-500">
          <Icon name="filter" size={13} className="text-ink-400"/>
          <span className="font-semibold uppercase tracking-wider text-[10.5px] text-ink-500">ตัวกรอง</span>
        </div>

        {/* Period */}
        <div className="flex items-center gap-1.5 h-9 px-2.5 bg-ink-50 border border-ink-200 rounded-lg text-[12.5px]">
          <Icon name="calendar" size={12} className="text-ink-500"/>
          <select value={period.month} onChange={e=>setPeriod(p=>({...p, month:+e.target.value}))} className="bg-transparent font-medium focus:outline-none">
            {THAI_MONTHS.map((m,i)=><option key={i} value={i+1}>{m}</option>)}
          </select>
          <select value={period.year} onChange={e=>setPeriod(p=>({...p, year:+e.target.value}))} className="bg-transparent font-mono font-medium focus:outline-none">
            {(() => { const cy = new Date().getFullYear(); return [cy-2, cy-1, cy, cy+1]; })().map(y=><option key={y} value={y}>{y+543}</option>)}
          </select>
        </div>

        {/* Division */}
        <Select value={divFilter || ""} onChange={e=>{ setDivFilter(e.target.value || null); setDeptFilter(null); setPosFilter(null); }} className="!w-[170px]">
          <option value="">ทุก Division</option>
          {divisions.map(d => <option key={d.id} value={d.id}>{d.name}</option>)}
        </Select>

        {/* Department */}
        <Select value={deptFilter || ""} onChange={e=>{ setDeptFilter(e.target.value || null); setPosFilter(null); }} className="!w-[180px]">
          <option value="">ทุก Department</option>
          {departments.filter(d => !divFilter || d.division_id === divFilter).map(d => <option key={d.id} value={d.id}>{d.name}</option>)}
        </Select>

        {/* Position — cascade from Department/Division */}
        <Select value={posFilter || ""} onChange={e=>setPosFilter(e.target.value || null)} className="!w-[180px]">
          <option value="">ทุก Position</option>
          {positions
            .filter(p => (!divFilter || p.division_id === divFilter) && (!deptFilter || p.department_id === deptFilter))
            .map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
        </Select>

        {hasAnyFilter && (
          <button onClick={()=>{ setStatusFilter(null); setDivFilter(null); setDeptFilter(null); setPosFilter(null); }}
            className="text-[12px] text-brand-600 hover:text-brand-700 font-medium flex items-center gap-1">
            <Icon name="x" size={12}/>ล้างตัวกรองทั้งหมด
          </button>
        )}

        <div className="ml-auto text-[11.5px] text-ink-500 font-mono">
          {counts.total} / {periodTasks.length} งาน
        </div>
      </div>

      {/* KPI strip */}
      <div className="grid grid-cols-2 lg:grid-cols-4 xl:grid-cols-8 gap-3">
        <KpiCard icon="table" tone="indigo" label={posFilter ? "งานที่ฉันต้องลงมือ" : "งานทั้งหมด"} value={counts.total} trend={`ใน${periodLabel}`} onClick={()=>setStatusFilter(null)}/>
        <KpiCard icon="clock" tone="slate" label="ยังไม่ถึงกำหนด" value={counts.blank} trend="พร้อมจัดทำในอนาคต" onClick={()=>setStatusFilter("blank")} active={statusFilter==="blank"}/>
        <KpiCard icon="play" tone="sky" label="รอจัดทำ (P)" value={counts.P} trend="ผู้รับผิดชอบ R" onClick={()=>setStatusFilter("P")} active={statusFilter==="P"}/>
        <KpiCard icon="checkCircle" tone="violet" label="รอตรวจสอบ (A)" value={counts.A} trend="ผู้ตรวจสอบ A" onClick={()=>setStatusFilter("A")} active={statusFilter==="A"}/>
        <KpiCard icon="message" tone="amber" label="แก้ไข (C)" value={counts.C} trend="มี Comment" onClick={()=>setStatusFilter("C")} active={statusFilter==="C"}/>
        <KpiCard icon="checkCircle" tone="emerald" label="สำเร็จ (S)" value={counts.S} trend={`${completionRate}% completion`} onClick={()=>setStatusFilter("S")} active={statusFilter==="S"}/>
        <KpiCard icon="alert" tone="rose" label="เลยกำหนด" value={counts.overdue} trend="ต้องเร่งดำเนินการ"/>
        <KpiCard icon="trending" tone="indigo" label="Completion Rate" value={completionRate + "%"} trend={`ของ${periodLabel}`}/>
      </div>

      {/* charts row */}
      <div className="grid grid-cols-12 gap-4">
        {/* Donut */}
        <div className="col-span-12 lg:col-span-4 bg-white rounded-2xl border border-ink-100 p-5">
          <div className="flex items-center justify-between mb-3">
            <div>
              <div className="text-[13.5px] font-semibold text-ink-900">การกระจายสถานะ</div>
              <div className="text-[11.5px] text-ink-500">งานทั้งหมด {counts.total} รายการ</div>
            </div>
            <Icon name="pie" size={14} className="text-ink-400"/>
          </div>
          <DonutChart data={donut} total={counts.total} center={completionRate + "%"} centerLabel="Completion"/>
          <div className="mt-3 space-y-1.5">
            {donut.map(d => {
              const pct = counts.total ? Math.round(d.v/counts.total*100) : 0;
              return (
                <button key={d.k} onClick={()=>setStatusFilter(statusFilter===d.k?null:d.k)} className={`w-full flex items-center justify-between gap-3 px-2 py-1 rounded-md text-left transition ${statusFilter===d.k?"bg-ink-100":"hover:bg-ink-50"}`}>
                  <div className="flex items-center gap-2 min-w-0">
                    <span className="w-2.5 h-2.5 rounded-sm shrink-0" style={{background:d.color}}/>
                    <span className="text-[12px] text-ink-700 truncate">{d.l}</span>
                  </div>
                  <div className="flex items-center gap-2 font-mono">
                    <span className="text-[12px] font-semibold text-ink-900 w-6 text-right">{d.v}</span>
                    <span className="text-[11px] text-ink-500 w-9 text-right">{pct}%</span>
                  </div>
                </button>
              );
            })}
          </div>
        </div>

        {/* Bar - departments */}
        <div className="col-span-12 lg:col-span-5 bg-white rounded-2xl border border-ink-100 p-5">
          <div className="flex items-center justify-between mb-3">
            <div>
              <div className="text-[13.5px] font-semibold text-ink-900">Completion rate ตามฝ่าย</div>
              <div className="text-[11.5px] text-ink-500">เปรียบเทียบความสำเร็จของแต่ละ Department</div>
            </div>
            <Icon name="bar" size={14} className="text-ink-400"/>
          </div>
          <div className="space-y-2.5">
            {deptStats.slice(0, 8).map(d => (
              <button key={d.id} onClick={()=>setDeptFilter(deptFilter===d.id?null:d.id)} className="w-full text-left">
                <div className="flex items-center justify-between text-[12px] mb-1">
                  <div className="flex items-center gap-2">
                    <span className="w-7 h-5 rounded text-[10px] font-bold text-ink-700 bg-ink-100 flex items-center justify-center">{d.short}</span>
                    <span className="text-ink-800 font-medium truncate">{d.name}</span>
                  </div>
                  <div className="flex items-center gap-2 font-mono">
                    <span className="text-ink-500 text-[11px]">{d.s}/{d.total}</span>
                    <span className={`font-semibold ${d.pct>=80?"text-emerald-600":d.pct>=50?"text-amber-600":"text-rose-600"}`}>{d.pct}%</span>
                  </div>
                </div>
                <div className="h-2 bg-ink-100 rounded-full overflow-hidden flex">
                  <div className="bg-emerald-500" style={{width:`${(d.s/d.total)*100}%`}}/>
                  <div className="bg-violet-500" style={{width:`${(d.a/d.total)*100}%`}}/>
                  <div className="bg-amber-500" style={{width:`${(d.c/d.total)*100}%`}}/>
                  <div className="bg-blue-500" style={{width:`${(d.p/d.total)*100}%`}}/>
                  <div className="bg-ink-300" style={{width:`${(d.b/d.total)*100}%`}}/>
                </div>
              </button>
            ))}
          </div>
          <div className="mt-3 pt-3 border-t border-ink-100 flex items-center gap-3 flex-wrap text-[10.5px] text-ink-500">
            <LegendDot color="bg-emerald-500" label="S สำเร็จ"/>
            <LegendDot color="bg-violet-500" label="A รอตรวจสอบ"/>
            <LegendDot color="bg-amber-500" label="C แก้ไข"/>
            <LegendDot color="bg-blue-500" label="P รอจัดทำ"/>
            <LegendDot color="bg-ink-300" label="ยังไม่ถึงกำหนด"/>
          </div>
        </div>

        {/* Trend + ranking */}
        <div className="col-span-12 lg:col-span-3 space-y-4">
          <div className="bg-white rounded-2xl border border-ink-100 p-5">
            <div className="flex items-center justify-between mb-2">
              <div>
                <div className="text-[13.5px] font-semibold text-ink-900">Trend Completion</div>
                <div className="text-[11.5px] text-ink-500">6 เดือนล่าสุด</div>
              </div>
              <Icon name="trending" size={14} className="text-ink-400"/>
            </div>
            <LineChart data={trend} width={260} height={120}/>
          </div>

          <div className="bg-white rounded-2xl border border-ink-100 p-4">
            <div className="text-[13.5px] font-semibold text-ink-900 mb-2">Top 3 ฝ่ายที่สำเร็จสูงสุด</div>
            <div className="space-y-2">
              {deptStats.slice(0,3).map((d,i) => (
                <div key={d.id} className="flex items-center gap-2">
                  <div className={`w-6 h-6 rounded-md text-white font-bold text-[11px] flex items-center justify-center ${i===0?"bg-amber-500":i===1?"bg-ink-400":"bg-amber-700"}`}>#{i+1}</div>
                  <div className="flex-1 text-[12px] text-ink-800 truncate">{d.name}</div>
                  <div className="font-mono text-[12px] font-semibold text-emerald-600">{d.pct}%</div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>

      {/* Lower row: waiting approval + drilldown list */}
      <div className="grid grid-cols-12 gap-4">
        <div className="col-span-12 lg:col-span-5 bg-white rounded-2xl border border-ink-100 overflow-hidden">
          <div className="px-4 py-3 border-b border-ink-100 flex items-center justify-between">
            <div>
              <div className="text-[13.5px] font-semibold text-ink-900">Top {waitingApproval.length} งานรอตรวจสอบ</div>
              <div className="text-[11.5px] text-ink-500">งานที่รอการ Approve โดยผู้ตรวจสอบ (A)</div>
            </div>
            <Badge color="violet" icon="checkCircle">{waitingApproval.length} งาน</Badge>
          </div>
          {waitingApproval.length === 0 ? (
            <EmptyState icon="checkCircle" title="ไม่มีงานรอตรวจสอบ" subtitle="ยอดเยี่ยมเลย!" />
          ) : (
            <div className="divide-y divide-ink-100">
              {waitingApproval.map(t => (
                <div key={t.sub_process_id} className="px-4 py-2.5 hover:bg-ink-50/60 flex items-center gap-3">
                  <RaciBadge kind="A" size="sm"/>
                  <div className="flex-1 min-w-0">
                    <div className="text-[12.5px] font-medium text-ink-900 truncate">{t.sp.name}</div>
                    <div className="text-[10.5px] text-ink-500 truncate">R: {displayName(t.rUser) || "—"} · A: {displayName(t.aUser) || "—"}</div>
                  </div>
                  <div className="text-right">
                    <div className="text-[10.5px] text-ink-500">Due</div>
                    <div className="text-[11px] font-mono text-ink-700">{t.due_date}</div>
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* drilldown */}
        <div className="col-span-12 lg:col-span-7 bg-white rounded-2xl border border-ink-100 overflow-hidden">
          <div className="px-4 py-3 border-b border-ink-100 flex items-center justify-between gap-3 flex-wrap">
            <div className="flex items-center gap-2">
              <div className="text-[13.5px] font-semibold text-ink-900">รายการงาน (Drill-down)</div>
              {(statusFilter || deptFilter || divFilter || posFilter) && (
                <button onClick={()=>{ setStatusFilter(null); setDeptFilter(null); setDivFilter(null); setPosFilter(null); }} className="text-[11px] text-brand-600 hover:underline">ล้างตัวกรอง</button>
              )}
            </div>
            <div className="flex items-center gap-1.5 flex-wrap">
              {statusFilter && <Badge color="indigo">สถานะ: {STATUS_META[statusFilter].label}</Badge>}
              {deptFilter && <Badge color="indigo">ฝ่าย: {departments.find(d=>d.id===deptFilter)?.name}</Badge>}
              {posFilter && <Badge color="indigo">ตำแหน่ง: {positions.find(p=>p.id===posFilter)?.name}</Badge>}
              <Badge color="slate">{drillRows.length} รายการ</Badge>
            </div>
          </div>
          <div className="px-4 py-2 border-b border-ink-100 bg-amber-50/60 text-[11px] text-amber-800 flex items-center gap-2">
            <Icon name="info" size={11} className="shrink-0"/>
            <span>Dashboard นับรวมงานของ <strong>ทุกวัน/ทุกงวด</strong> ในเดือนที่เลือก · งาน <strong>Daily</strong> 1 ตัวจะมีหลาย instances (1 ต่อวัน) · คลิกแถวเพื่อ <strong>เปิดดูใน RACI Matrix ที่วันที่นั้น</strong></span>
          </div>
          <div className="max-h-[440px] overflow-y-auto thin-scroll">
            {drillRows.length === 0 ? (
              <EmptyState title="ไม่พบงานในตัวกรองนี้" subtitle="ลองเปลี่ยนตัวกรองหรือล้างเงื่อนไข"/>
            ) : (
              <table className="w-full text-[12px]">
                <thead className="sticky top-0 z-10 bg-ink-50/80 backdrop-blur">
                  <tr className="text-ink-500 text-[10.5px] uppercase tracking-wider">
                    {["Sub-process","R / A","วันที่ของงวด","Status","Last update",""].map(h=><th key={h} className="text-left font-semibold px-3 py-2 border-b border-ink-200">{h}</th>)}
                  </tr>
                </thead>
                <tbody>
                  {drillRows.map((r, i) => (
                    <tr key={`${r.task.sub_process_id}-${r.task.due_date}-${i}`}
                        onClick={() => onGoMatrix(r.task.due_date)}
                        className="border-b border-ink-100 hover:bg-brand-50/40 cursor-pointer transition group">
                      <td className="px-3 py-2.5">
                        <div className="text-ink-900 font-medium truncate max-w-[260px]">{r.sp.name}</div>
                        <div className="text-[10.5px] text-ink-500 truncate max-w-[260px]">{r.mp?.name} · {r.proc?.name}</div>
                      </td>
                      <td className="px-3 py-2.5">
                        <div className="flex items-center gap-1.5">
                          <Avatar name={r.rUser?.full_name} size={20}/>
                          <span className="text-ink-700 truncate max-w-[120px]">{displayName(r.rUser) || "—"}</span>
                        </div>
                        <div className="text-[10.5px] text-ink-500 mt-0.5">A: {displayName(r.aUser) || "—"}</div>
                      </td>
                      <td className="px-3 py-2.5">
                        <div className="font-mono text-ink-700">{r.task.due_date}</div>
                        <Badge color="slate" className="!text-[9.5px] mt-0.5">{r.task.frequency || r.sp.frequency}</Badge>
                      </td>
                      <td className="px-3 py-2.5"><StatusPill status={r.task.status}/></td>
                      <td className="px-3 py-2.5 font-mono text-[10.5px] text-ink-500">{r.task.updated || "—"}</td>
                      <td className="px-2 py-2.5 text-right">
                        <span className="opacity-0 group-hover:opacity-100 text-[10.5px] text-brand-600 font-medium inline-flex items-center gap-1">เปิดใน Matrix<Icon name="arrowRight" size={11}/></span>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

// ---- Donut Chart (SVG) ----
const DonutChart = ({ data, total, center, centerLabel }) => {
  const size = 180, r = 70, stroke = 22, c = 2*Math.PI*r;
  let acc = 0;
  return (
    <div className="relative flex items-center justify-center" style={{height:size}}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="#eef0f6" strokeWidth={stroke}/>
        {data.map((d,i) => {
          if (!total || d.v===0) return null;
          const len = (d.v/total)*c;
          const off = (acc/total)*c;
          acc += d.v;
          return (
            <circle key={i} cx={size/2} cy={size/2} r={r} fill="none" stroke={d.color} strokeWidth={stroke}
              strokeDasharray={`${len} ${c-len}`} strokeDashoffset={-off} transform={`rotate(-90 ${size/2} ${size/2})`} strokeLinecap="butt"/>
          );
        })}
      </svg>
      <div className="absolute inset-0 flex flex-col items-center justify-center">
        <div className="text-[26px] font-bold text-ink-900 font-mono">{center}</div>
        <div className="text-[10.5px] text-ink-500 uppercase tracking-wider">{centerLabel}</div>
      </div>
    </div>
  );
};

// ---- Line Chart (SVG) ----
const LineChart = ({ data, width=260, height=120 }) => {
  const pad = { l:24, r:8, t:10, b:18 };
  const W = width - pad.l - pad.r, H = height - pad.t - pad.b;
  const max = 100, min = 0;
  const xs = (i) => pad.l + (i/(data.length-1))*W;
  const ys = (v) => pad.t + (1 - (v-min)/(max-min))*H;
  const path = data.map((d,i) => `${i===0?"M":"L"}${xs(i)},${ys(d.rate)}`).join(" ");
  const areaPath = `${path} L${xs(data.length-1)},${pad.t+H} L${xs(0)},${pad.t+H} Z`;
  return (
    <svg width={width} height={height} viewBox={`0 0 ${width} ${height}`} className="overflow-visible">
      <defs>
        <linearGradient id="trendGrad" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor="#6366f1" stopOpacity="0.3"/>
          <stop offset="100%" stopColor="#6366f1" stopOpacity="0"/>
        </linearGradient>
      </defs>
      {[0,50,100].map(v => (
        <line key={v} x1={pad.l} x2={pad.l+W} y1={ys(v)} y2={ys(v)} stroke="#eef0f6" strokeDasharray="3 3"/>
      ))}
      <path d={areaPath} fill="url(#trendGrad)"/>
      <path d={path} fill="none" stroke="#6366f1" strokeWidth="2"/>
      {data.map((d,i) => (
        <g key={i}>
          <circle cx={xs(i)} cy={ys(d.rate)} r={3} fill="#fff" stroke="#6366f1" strokeWidth="2"/>
          <text x={xs(i)} y={pad.t+H+12} textAnchor="middle" fontSize="10" fill="#8b96ad" fontFamily="JetBrains Mono">{d.m}</text>
        </g>
      ))}
    </svg>
  );
};

const LegendDot = ({ color, label }) => (
  <span className="inline-flex items-center gap-1"><span className={`w-2 h-2 rounded-sm ${color}`}/><span>{label}</span></span>
);

Object.assign(window, { DashboardPage });
