// Shared components: icons, sidebar, topbar, level chips, helpers
// All components exported to window for cross-file access.

const { useState, useEffect, useMemo, useRef } = React;
const D = window.LR_DATA;

// ====== Icons (inline SVG) ======
const Icon = ({ name, size = 18 }) => {
  const paths = {
    dashboard: <><rect x="3" y="3" width="7" height="9" rx="1.5" /><rect x="14" y="3" width="7" height="5" rx="1.5" /><rect x="14" y="12" width="7" height="9" rx="1.5" /><rect x="3" y="16" width="7" height="5" rx="1.5" /></>,
    matrix: <><rect x="3" y="3" width="6" height="6" rx="1" /><rect x="3" y="13" width="6" height="6" rx="1" /><rect x="13" y="3" width="6" height="6" rx="1" /><rect x="13" y="13" width="6" height="6" rx="1" /><line x1="11" y1="6" x2="13" y2="6" /><line x1="11" y1="16" x2="13" y2="16" /><line x1="6" y1="11" x2="6" y2="13" /><line x1="16" y1="11" x2="16" y2="13" /></>,
    calendar: <><rect x="3" y="5" width="18" height="16" rx="2" /><line x1="3" y1="10" x2="21" y2="10" /><line x1="8" y1="3" x2="8" y2="7" /><line x1="16" y1="3" x2="16" y2="7" /></>,
    clipboard: <><rect x="6" y="4" width="12" height="17" rx="2" /><rect x="9" y="2" width="6" height="4" rx="1" /><line x1="9" y1="10" x2="15" y2="10" /><line x1="9" y1="14" x2="15" y2="14" /><line x1="9" y1="18" x2="13" y2="18" /></>,
    alert: <><path d="M12 3 L22 20 H2 Z" /><line x1="12" y1="10" x2="12" y2="14" /><circle cx="12" cy="17" r="0.6" fill="currentColor" /></>,
    chart: <><polyline points="3,17 9,11 13,15 21,7" /><polyline points="15,7 21,7 21,13" /></>,
    user: <><circle cx="12" cy="8" r="4" /><path d="M4 21 Q4 14 12 14 Q20 14 20 21" /></>,
    users: <><circle cx="9" cy="8" r="3.5" /><path d="M3 20 Q3 14 9 14 Q15 14 15 20" /><circle cx="17" cy="9" r="2.5" /><path d="M14 17 Q14 13 17 13 Q21 13 21 17" /></>,
    book: <><path d="M4 4 H11 Q12 5 12 6 V20 Q12 19 11 19 H4 Z" /><path d="M20 4 H13 Q12 5 12 6 V20 Q12 19 13 19 H20 Z" /></>,
    plus: <><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></>,
    search: <><circle cx="11" cy="11" r="6" /><line x1="16" y1="16" x2="21" y2="21" /></>,
    bell: <><path d="M6 9 Q6 4 12 4 Q18 4 18 9 V14 L20 17 H4 L6 14 Z" /><path d="M10 20 Q11 21 12 21 Q13 21 14 20" /></>,
    settings: <><circle cx="12" cy="12" r="3" /><path d="M12 2 V5 M12 19 V22 M2 12 H5 M19 12 H22 M4.9 4.9 L7 7 M17 17 L19.1 19.1 M4.9 19.1 L7 17 M17 7 L19.1 4.9" /></>,
    filter: <><polygon points="3,5 21,5 14,13 14,20 10,18 10,13" /></>,
    download: <><path d="M12 4 V15" /><polyline points="7,11 12,16 17,11" /><line x1="4" y1="20" x2="20" y2="20" /></>,
    check: <polyline points="5,12 10,17 19,7" />,
    edit: <><path d="M4 20 L4 16 L16 4 L20 8 L8 20 Z" /><line x1="14" y1="6" x2="18" y2="10" /></>,
    chevronRight: <polyline points="9,5 16,12 9,19" />,
    chevronDown: <polyline points="5,9 12,16 19,9" />,
    clock: <><circle cx="12" cy="12" r="9" /><polyline points="12,6 12,12 16,14" /></>,
    sparkles: <><path d="M12 3 L13.5 9 L19 10.5 L13.5 12 L12 18 L10.5 12 L5 10.5 L10.5 9 Z" /><path d="M19 3 L19.6 5 L21 5.6 L19.6 6 L19 8 L18.4 6 L17 5.6 L18.4 5 Z" /></>,
    pulse: <polyline points="3,12 7,12 9,8 12,18 15,9 17,12 21,12" />,
    target: <><circle cx="12" cy="12" r="9" /><circle cx="12" cy="12" r="5" /><circle cx="12" cy="12" r="1" fill="currentColor" /></>,
    signature: <><path d="M3 18 Q8 8 12 14 Q14 17 19 10" /><line x1="3" y1="21" x2="21" y2="21" /></>,
    moon: <path d="M20 14 A8 8 0 0 1 10 4 A9 9 0 1 0 20 14 Z" />,
    sun: <><circle cx="12" cy="12" r="4" /><path d="M12 3 V5 M12 19 V21 M3 12 H5 M19 12 H21 M5.6 5.6 L7 7 M17 17 L18.4 18.4 M5.6 18.4 L7 17 M17 7 L18.4 5.6" /></>,
    logout: <><path d="M9 4 H6 Q4 4 4 6 V18 Q4 20 6 20 H9" /><polyline points="14,8 18,12 14,16" /><line x1="9" y1="12" x2="18" y2="12" /></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      {paths[name] || null}
    </svg>
  );
};

// ====== Helpers ======
function initials(name) {
  const t = name.replace(/^(น\.ส\.|นาง|นาย)/, '').trim();
  return t.slice(0, 1);
}
function levelClass(score) {
  return `lvl-${Math.max(1, Math.min(5, score))}`;
}
function levelLabel(score) {
  const lv = D.LEVELS.find(l => l.n === score);
  return lv ? lv.label : '—';
}
function staffName(id) {
  if (id === 'group') return 'ทีมพยาบาล (Group)';
  const s = D.staffById(id);
  return s ? `${s.title}${s.name}` : id;
}
function staffShort(id) {
  if (id === 'group') return 'Group';
  const s = D.staffById(id);
  return s ? s.name : id;
}
function avg(arr) { return arr.length ? arr.reduce((a,b)=>a+b,0)/arr.length : 0; }

// ====== LevelChip ======
const LevelChip = ({ level, size = 'sm' }) => {
  let lv;
  if (typeof level === 'string') {
    lv = D.levelById(level);
  } else if (typeof level === 'number') {
    const n = Math.max(1, Math.min(5, Math.round(level)));
    lv = D.LEVELS.find(l => l.n === n);
  }
  if (!lv) return null;
  return <span className={`lvl lvl-${lv.n}`}>{lv.label}</span>;
};

// ====== Avatar ======
const Avatar = ({ name, size = 30 }) => (
  <div className="avatar" style={{ width: size, height: size, fontSize: size * 0.4 }}>
    {initials(name)}
  </div>
);

// ====== Role helpers ======
const ROLE_LEVELS = { dept_head: 5, unit_head: 4, shift_head: 3, supervisor: 2, supervisee: 1, admin: 5 };

// role can be a string OR a JSON-array string e.g. '["dept_head","supervisor"]'
function parseRoles(role) {
  if (!role) return ['supervisee'];
  if (Array.isArray(role)) return role;
  try { const p = JSON.parse(role); if (Array.isArray(p)) return p; } catch {}
  return [role];
}
function roleLevel(role) {
  return Math.max(...parseRoles(role).map(r => ROLE_LEVELS[r] || 1));
}
function isSupervisorRole(role) { return roleLevel(role) >= 2; }
function primaryRole(role) {
  const roles = parseRoles(role);
  return roles.reduce((best, r) => (ROLE_LEVELS[r]||1) > (ROLE_LEVELS[best]||1) ? r : best, roles[0]);
}

// ====== Sidebar ======
const Sidebar = ({ current, onNav, role }) => {
  const lv = roleLevel(role);
  const isSupRole = lv >= 2;

  // minLevel: 2=supervisor+, 3=shift_head+, 4=unit_head+, 5=dept_head only
  const supervisorItems = [
    { id: 'dashboard',  label: 'Dashboard',          icon: 'dashboard',  minLevel: 2 },
    { id: 'matrix',     label: 'Skill Matrix',        icon: 'matrix',     minLevel: 2, badge: String(D.STAFF.length) },
    { id: 'planning',   label: 'แผน & ปฏิทิน',       icon: 'calendar',   minLevel: 2 },
    { id: 'evaluation', label: 'หัวข้อนิเทศ',         icon: 'clipboard',  minLevel: 4 },
    { id: 'records',    label: 'บันทึกการนิเทศ',      icon: 'clipboard',  minLevel: 2 },
    { id: 'cases',      label: 'Case Review',          icon: 'alert',      minLevel: 2, badge: String(D.CASES.length) },
    { id: 'analytics',  label: 'Analytics',            icon: 'chart',      minLevel: 3 },
    { id: 'staff',      label: 'บุคลากร',              icon: 'users',      minLevel: 4 },
    { id: 'knowledge',  label: 'คลังความรู้',          icon: 'book',       minLevel: 2 },
    { id: 'users',      label: 'จัดการผู้ใช้งาน',     icon: 'settings',   minLevel: 4 },
  ].filter(it => it.minLevel <= lv);

  const superviseeItems = [
    { id: 'mydashboard', label: 'หน้าฉัน',            icon: 'dashboard' },
    { id: 'myplan',      label: 'แผนพัฒนาฉัน',        icon: 'target' },
    { id: 'records',     label: 'บันทึกการนิเทศ',      icon: 'clipboard' },
    { id: 'knowledge',   label: 'คลังความรู้',          icon: 'book' },
  ];

  const list = isSupRole ? supervisorItems : superviseeItems;

  const roleLabel = {
    dept_head: 'หัวหน้ากลุ่มงาน', unit_head: 'หัวหน้างาน',
    shift_head: 'หัวหน้าเวร', supervisor: 'ผู้นิเทศ', supervisee: 'ผู้รับการนิเทศ', admin: 'ผู้ดูแลระบบ',
  }[role] || role;

  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-mark">ห</div>
        <div className="brand-text">
          <strong>นิเทศห้องคลอด</strong>
          <span>รพ.ศรีสะเกษ</span>
        </div>
      </div>
      <div className="nav-section-title">{isSupRole ? 'งานนิเทศ' : 'หน้าหลัก'}</div>
      {list.map(it => (
        <button
          key={it.id}
          className={`nav-item ${current === it.id ? 'active' : ''}`}
          onClick={() => onNav(it.id)}
        >
          <span className="nav-icon"><Icon name={it.icon} /></span>
          <span className="nav-label">{it.label}</span>
          {it.badge && <span className="nav-badge">{it.badge}</span>}
        </button>
      ))}
      <div style={{ flex: 1 }} />
      <div className="nav-section-title">บัญชี</div>
      <div className="nav-item" style={{ cursor: 'default', opacity: 0.7 }}>
        <span className="nav-icon"><Icon name="user" /></span>
        <span className="nav-label" style={{ fontSize: 11 }}>{roleLabel}</span>
      </div>
      <button className="nav-item" onClick={() => onNav('settings')}>
        <span className="nav-icon"><Icon name="settings" /></span>
        <span className="nav-label">ตั้งค่า</span>
      </button>
      <button className="nav-item" onClick={() => onNav('login')}>
        <span className="nav-icon"><Icon name="logout" /></span>
        <span className="nav-label">ออกจากระบบ</span>
      </button>
    </aside>
  );
};

// ====== Topbar ======
const Topbar = ({ title, crumbs, role, onRoleChange, user, onTweaksToggle }) => {
  const u = D.staffById(user);
  return (
    <div className="topbar">
      <div>
        {crumbs && <div className="crumbs">{crumbs}</div>}
        <h1>{title}</h1>
      </div>
      <div className="topbar-actions">
        <div className="role-switcher">
          <button className={role === 'supervisor' ? 'active' : ''} onClick={() => onRoleChange('supervisor')}>Supervisor</button>
          <button className={role === 'supervisee' ? 'active' : ''} onClick={() => onRoleChange('supervisee')}>Supervisee</button>
        </div>
        <button className="icon-btn" title="แจ้งเตือน"><Icon name="bell" size={16} /></button>
        <button className="icon-btn" title="Tweaks" onClick={onTweaksToggle}><Icon name="settings" size={16} /></button>
        {u && (
          <div className="user-pill">
            <Avatar name={u.name} />
            <div>
              <div className="name">{u.title}{u.name.split(' ')[0]}</div>
              <div className="meta">{D.POSITIONS[u.pos].replace('พยาบาลวิชาชีพ', 'พว.')}</div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

// ====== Radar chart (SVG) ======
const Radar = ({ axes, values, size = 240, maxVal = 5 }) => {
  const cx = size / 2, cy = size / 2, r = size / 2 - 30;
  const n = axes.length;
  const angle = (i) => -Math.PI / 2 + (i * 2 * Math.PI) / n;
  const point = (i, v) => {
    const a = angle(i);
    const rr = (v / maxVal) * r;
    return [cx + rr * Math.cos(a), cy + rr * Math.sin(a)];
  };
  const rings = [1, 2, 3, 4, 5];
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      {rings.map(rg => (
        <polygon
          key={rg}
          points={axes.map((_, i) => point(i, rg).join(',')).join(' ')}
          fill="none"
          stroke="var(--c-border)"
          strokeWidth="1"
        />
      ))}
      {axes.map((_, i) => {
        const [x, y] = point(i, maxVal);
        return <line key={i} x1={cx} y1={cy} x2={x} y2={y} stroke="var(--c-border-soft)" strokeWidth="1" />;
      })}
      <polygon
        points={values.map((v, i) => point(i, v).join(',')).join(' ')}
        fill="var(--c-primary)" fillOpacity="0.18"
        stroke="var(--c-primary)" strokeWidth="2"
      />
      {values.map((v, i) => {
        const [x, y] = point(i, v);
        return <circle key={i} cx={x} cy={y} r="3" fill="var(--c-primary)" />;
      })}
      {axes.map((ax, i) => {
        const a = angle(i);
        const lx = cx + (r + 16) * Math.cos(a);
        const ly = cy + (r + 16) * Math.sin(a);
        return (
          <text
            key={i}
            x={lx} y={ly}
            textAnchor="middle"
            dominantBaseline="middle"
            fontSize="10"
            fontFamily="var(--font-mono)"
            fill="var(--c-ink-soft)"
          >
            {ax}
          </text>
        );
      })}
    </svg>
  );
};

// ====== Donut chart ======
const Donut = ({ segments, size = 140, thickness = 18 }) => {
  const r = (size - thickness) / 2;
  const c = 2 * Math.PI * r;
  const total = segments.reduce((s, x) => s + x.value, 0) || 1;
  let off = 0;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--c-surface-2)" strokeWidth={thickness} />
      {segments.map((s, i) => {
        const len = (s.value / total) * c;
        const el = (
          <circle
            key={i}
            cx={size/2} cy={size/2} r={r} fill="none"
            stroke={s.color} strokeWidth={thickness}
            strokeDasharray={`${len} ${c - len}`}
            strokeDashoffset={-off}
            transform={`rotate(-90 ${size/2} ${size/2})`}
            strokeLinecap="butt"
          />
        );
        off += len;
        return el;
      })}
    </svg>
  );
};

// ====== Bar chart (compact) ======
const BarChart = ({ data, height = 140, max }) => {
  const m = max || Math.max(...data.map(d => d.value));
  return (
    <div style={{ display: 'flex', alignItems: 'flex-end', gap: 6, height }}>
      {data.map((d, i) => (
        <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
          <div style={{
            width: '100%',
            height: `${(d.value / m) * (height - 24)}px`,
            background: d.color || 'var(--c-primary)',
            borderRadius: '4px 4px 0 0',
            minHeight: 4,
          }} />
          <div style={{ fontSize: 10, color: 'var(--c-ink-muted)', fontFamily: 'var(--font-mono)' }}>{d.label}</div>
        </div>
      ))}
    </div>
  );
};

// ====== Line chart ======
const LineChart = ({ data, width = 360, height = 120 }) => {
  const max = Math.max(...data) * 1.1;
  const min = Math.min(...data) * 0.9;
  const w = width, h = height;
  const stepX = w / (data.length - 1);
  const pts = data.map((v, i) => [i * stepX, h - ((v - min) / (max - min || 1)) * (h - 10) - 5]);
  const path = 'M ' + pts.map(p => p.join(',')).join(' L ');
  const area = `M 0,${h} L ` + pts.map(p => p.join(',')).join(' L ') + ` L ${w},${h} Z`;
  return (
    <svg width="100%" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none" style={{ display: 'block' }}>
      <path d={area} fill="var(--c-primary-soft)" />
      <path d={path} fill="none" stroke="var(--c-primary)" strokeWidth="2" />
      {pts.map((p, i) => <circle key={i} cx={p[0]} cy={p[1]} r="3" fill="var(--c-primary)" />)}
    </svg>
  );
};

Object.assign(window, {
  Icon, LevelChip, Avatar, Sidebar, Topbar, Radar, Donut, BarChart, LineChart,
  initials, levelClass, levelLabel, staffName, staffShort, avg,
  parseRoles, roleLevel, primaryRole, isSupervisorRole,
});
