/**
 * ProfessionalDashboard.jsx
 * Interactive portal for dentists, hygienists, dental assistants, and front desk.
 * Routes: #dentist-portal, #hygienist-portal
 *
 * Core features:
 * - Journey-aware: onboarding wizard for new users, command center for active users
 * - AI-driven "Your Next Move" card based on workflow stage
 * - Interactive agent cards with live pending-task badges
 * - Role-specific menus, sections, and tool suggestions
 * - HITL queue summary with urgency detection
 * - Sidebar navigation adjusts per role + workflow stage
 */

const { useState, useEffect, useCallback, useRef } = React;

// ─── Design tokens ────────────────────────────────────────────────────────────
const T = {
  navy: '#1B3557', mint: '#52C4A0', cream: '#FAF9F7', white: '#FFFFFF',
  slate: '#64748B', light: '#E2E8F0', lightBg: '#F8FAFC',
  green: '#2D6A4F', greenLight: '#74C69D',
  red: '#EF4444', amber: '#F59E0B', purple: '#7C3AED',
  radius: { sm: 8, md: 12, lg: 16, xl: 20 },
  shadow: { sm: '0 2px 8px rgba(27,53,87,0.06)', md: '0 6px 20px rgba(27,53,87,0.10)', lg: '0 16px 48px rgba(27,53,87,0.14)' },
};

// ─── Inline SVG icon ──────────────────────────────────────────────────────────
const SvgIcon = ({ d, size = 18, color = 'currentColor', style }) =>
  React.createElement('svg', { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round', style },
    React.createElement('path', { d })
  );

const ICONS = {
  grid:        'M3 3h7v7H3z M14 3h7v7h-7z M14 14h7v7h-7z M3 14h7v7H3z',
  cpu:         'M9 3H5a2 2 0 00-2 2v4m6-6h10a2 2 0 012 2v4M9 3v18m0 0h10a2 2 0 002-2V9M9 21H5a2 2 0 01-2-2V9m0 0h18',
  clock:       'M12 22a10 10 0 100-20 10 10 0 000 20z M12 6v6l4 2',
  users:       'M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2 M23 21v-2a4 4 0 00-3-3.87 M16 3.13a4 4 0 010 7.75',
  dollar:      'M12 1v22 M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6',
  barChart:    'M18 20V10 M12 20V4 M6 20v-6',
  chevRight:   'M9 18l6-6-6-6',
  chevDown:    'M6 9l6 6 6-6',
  arrowRight:  'M5 12h14 M12 5l7 7-7 7',
  check:       'M20 6L9 17l-5-5',
  alert:       'M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z M12 9v4 M12 17h.01',
  star:        'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z',
  settings:    'M12 20a8 8 0 100-16 8 8 0 000 16z M12 14a2 2 0 100-4 2 2 0 000 4z',
  plus:        'M12 5v14 M5 12h14',
  zap:         'M13 2L3 14h9l-1 8 10-12h-9l1-8z',
  home:        'M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z M9 22V12h6v10',
  book:        'M4 19.5A2.5 2.5 0 016.5 17H20 M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z',
  briefcase:   'M20 7H4a2 2 0 00-2 2v11a2 2 0 002 2h16a2 2 0 002-2V9a2 2 0 00-2-2z M16 21V5a2 2 0 00-2-2h-4a2 2 0 00-2 2v16',
  refresh:     'M23 4v6h-6 M1 20v-6h6 M3.51 9a9 9 0 0114.85-3.36L23 10 M1 14l4.64 4.36A9 9 0 0020.49 15',
  calendar:    'M3 4h18v18H3z M16 2v4 M8 2v4 M3 10h18',
  x:           'M18 6L6 18 M6 6l12 12',
  lock:        'M19 11H5a2 2 0 00-2 2v7a2 2 0 002 2h14a2 2 0 002-2v-7a2 2 0 00-2-2z M17 11V7a5 5 0 00-10 0v4',
  trendUp:     'M23 6l-9.5 9.5-5-5L1 18 M17 6h6v6',
  phone:       'M22 16.92v3a2 2 0 01-2.18 2A19.79 19.79 0 013.07 9.81 19.79 19.79 0 01.15 1.18 2 2 0 012.13 0h3a2 2 0 012 1.72c.127.96.361 1.903.7 2.81a2 2 0 01-.45 2.11L6.91 7.91a16 16 0 006.16 6.16l1.27-.45a2 2 0 012.11.45c.907.339 1.85.573 2.81.7A2 2 0 0122 16.92z',
};

// ─── Agent catalog ─────────────────────────────────────────────────────────────
const AGENTS = {
  receptionist:         { label: 'AI Receptionist',       icon: 'phone',     tier: 'basic',    desc: 'Answers calls, books appointments, handles FAQs 24/7' },
  intake:               { label: 'AI Patient Intake',     icon: 'users',     tier: 'basic',    desc: 'Digital forms, medical history, pre-visit consent' },
  experience:           { label: 'AI Patient Experience', icon: 'star',      tier: 'basic',    desc: 'Post-visit follow-ups, satisfaction tracking, reviews' },
  hygiene_recall:       { label: 'AI Hygiene Recall',     icon: 'refresh',   tier: 'basic',    desc: 'Automated recall campaigns, appointment reminders' },
  schedule_optimizer:   { label: 'AI Schedule Optimizer', icon: 'calendar',  tier: 'basic',    desc: 'Fill cancellations, optimize chair time, reduce gaps' },
  claim_submission:     { label: 'AI Claim Submission',   icon: 'zap',       tier: 'pro',      desc: 'Submit claims to 900+ payers with real-time scrubbing' },
  claim_scrubbing:      { label: 'AI Claim Scrubbing',    icon: 'check',     tier: 'pro',      desc: 'Catch errors before submission, reduce denials' },
  eob_posting:          { label: 'AI EOB Posting',        icon: 'dollar',    tier: 'pro',      desc: 'Automatically post EOBs, flag discrepancies' },
  ar_collections:       { label: 'AI A/R Collections',   icon: 'trendUp',   tier: 'pro',      desc: 'Aging report automation, patient balance follow-up' },
  treatment_planner:    { label: 'AI Treatment Planner',  icon: 'cpu',       tier: 'pro',      desc: 'CDT code suggestions, plan templates, case acceptance' },
  case_acceptance:      { label: 'AI Case Acceptance',    icon: 'star',      tier: 'pro',      desc: 'Present treatment plans, track acceptance rates' },
  revenue_analytics:    { label: 'AI Revenue Analytics',  icon: 'barChart',  tier: 'pro',      desc: 'Revenue cycle insights, payer mix, production trends' },
  copilot:              { label: 'AI Copilot',            icon: 'zap',       tier: 'clinical', desc: 'Real-time clinical assistance during patient encounters' },
  scribe:               { label: 'AI Scribe',             icon: 'book',      tier: 'clinical', desc: 'Voice-to-SOAP notes, CDT coding, treatment docs' },
  practice_manager:     { label: 'AI Practice Manager',   icon: 'briefcase', tier: 'clinical', desc: 'KPIs, staffing insights, compliance monitoring' },
};

const TIER_COLORS = { basic: T.mint, pro: T.navy, clinical: T.purple };

/** Canonical SPA shell for practitioner dashboards (apex / is teaser, not the SPA). */
function findSpaHash(route) {
  const h = String(route || 'dentist-portal').replace(/^#/, '');
  return `/find/#${h}`;
}

/** Practice Suite — Office Management Agents (ai-receptionist, intake, etc.). */
const SUITE_AGENTS_HREF = '/for-dentists/suite/#office';

/** Onboarding step id → persisted flag on td_pro_ctx / journey API. */
const ONBOARDING_STEP_DONE = {
  profile: 'step_profile_complete',
  agent: 'step_first_agent_active',
  patient: 'step_first_patient_processed',
  review: 'step_hitl_reviewed',
  billing: 'step_billing_configured',
};

function isOnboardingStepDone(onboarding, stepId) {
  const key = ONBOARDING_STEP_DONE[stepId];
  return key ? !!onboarding?.[key] : !!onboarding?.[`step_${stepId}_complete`];
}

/** Sidebar shortcuts to static portal surfaces (auth, suite, ops). */
const PORTAL_QUICK_LINKS = [
  { label: 'Practice Suite', href: '/for-dentists/suite/' },
  { label: 'Practitioner sign-in', href: '/portal/practitioner/' },
  { label: 'Beta tester', href: '/portal/tester/' },
  { label: 'Operations admin', href: '/portal/operations/' },
];

// ─── Onboarding steps ─────────────────────────────────────────────────────────
const ONBOARDING_FLOW = [
  { id: 'profile',     label: 'Complete your profile',      desc: 'Add NPI, specialty, and practice details',           cta: 'Set up profile',    route: '/for-dentists/#find-npi', icon: 'users'   },
  { id: 'agent',       label: 'Activate your first agent',  desc: 'Start with the AI Receptionist',                      cta: 'Activate now',      route: SUITE_AGENTS_HREF, icon: 'phone'   },
  { id: 'patient',     label: 'Process a patient',          desc: 'Let the intake agent handle your first new patient',  cta: 'Run intake',        route: findSpaHash('forms'),           icon: 'users'   },
  { id: 'review',      label: 'Review AI output',           desc: 'Approve your first HITL flagged item',               cta: 'Go to queue',       route: '/command/',                     icon: 'check'   },
  { id: 'billing',     label: 'Set up billing',             desc: 'Connect to your payer for claim automation',         cta: 'Configure billing', route: '/for-dentists/suite/#treatment-plan', icon: 'dollar'  },
];

// ─── Role-specific nav ─────────────────────────────────────────────────────────
const NAV_BY_ROLE = {
  dentist: [
    { id: 'dashboard', label: 'Dashboard',  icon: 'grid',     href: findSpaHash('dentist-portal'),  badge: null },
    { id: 'agents',    label: 'Agents',     icon: 'cpu',      href: SUITE_AGENTS_HREF,          badge: null },
    { id: 'hitl',      label: 'Queue',      icon: 'clock',    href: '/command/',                   badge: 'hitl' },
    { id: 'patients',  label: 'Patients',   icon: 'users',    href: findSpaHash('forms'),          badge: null },
    { id: 'billing',   label: 'Billing',    icon: 'dollar',   href: '/for-dentists/suite/#treatment-plan', badge: null },
    { id: 'reports',   label: 'Reports',    icon: 'barChart', href: '/for-dentists/suite/#practice-dna', badge: null },
    { id: 'settings',  label: 'Settings',   icon: 'settings', href: '/portal/practitioner/',         badge: null },
  ],
  hygienist: [
    { id: 'dashboard', label: 'Home',       icon: 'home',     href: findSpaHash('hygienist-portal'), badge: null },
    { id: 'schedule',  label: 'Schedule',   icon: 'calendar', href: findSpaHash('schedule'),       badge: null },
    { id: 'recall',    label: 'Recall',     icon: 'refresh',  href: findSpaHash('recall'),         badge: 'recall' },
    { id: 'ce',        label: 'CE Hub',     icon: 'book',     href: findSpaHash('ce-hub'),         badge: null },
    { id: 'jobs',      label: 'Jobs',       icon: 'briefcase',href: findSpaHash('jobs'),           badge: null },
  ],
  front_desk: [
    { id: 'dashboard', label: 'Dashboard',  icon: 'grid',     href: findSpaHash('dentist-portal'),  badge: null },
    { id: 'schedule',  label: 'Schedule',   icon: 'calendar', href: findSpaHash('schedule'),       badge: null },
    { id: 'patients',  label: 'Patients',   icon: 'users',    href: findSpaHash('forms'),          badge: null },
    { id: 'billing',   label: 'Billing',    icon: 'dollar',   href: '/for-dentists/suite/#treatment-plan', badge: null },
    { id: 'agents',    label: 'Agents',     icon: 'cpu',      href: SUITE_AGENTS_HREF,          badge: null },
  ],
};

// ─── Main component ────────────────────────────────────────────────────────────
function ProfessionalDashboard({ role: propRole }) {
  const role = propRole || localStorage.getItem('td_role') || 'dentist';
  const proCtxRaw = localStorage.getItem('td_pro_ctx');
  const proCtx = (() => { try { return JSON.parse(proCtxRaw || '{}'); } catch { return {}; } })();

  const [activeNav, setActiveNav] = useState('dashboard');
  const [onboarding, setOnboarding] = useState(null);
  const [loading, setLoading] = useState(true);
  const [hitlCount, setHitlCount] = useState(proCtx.pendingHitl || 0);
  const [recallCount, setRecallCount] = useState(0);
  const [isFirstVisit] = useState(!proCtx.onboardingComplete);
  const [testerPerms, setTesterPerms] = useState(
    () => (window.TdAuth && window.TdAuth.readTesterPermissions ? window.TdAuth.readTesterPermissions() : [])
  );
  const [testerMeta, setTesterMeta] = useState(() => {
    try { return JSON.parse(localStorage.getItem('td_tester_meta') || '{}'); } catch { return {}; }
  });

  const can = useCallback((featureId) => {
    if (!testerPerms.length) return true;
    return window.TdAuth && window.TdAuth.hasTesterPermission
      ? window.TdAuth.hasTesterPermission(featureId)
      : true;
  }, [testerPerms]);

  // Derive nav items and feature config for role
  const navItems = (NAV_BY_ROLE[role] || NAV_BY_ROLE.dentist).filter((item) => {
    const fid = `nav:${item.id}`;
    return can(fid);
  });

  useEffect(() => {
    let cancelled = false;
    (async () => {
      if (window.TdAuth && window.TdAuth.refreshTesterPermissions) {
        const res = await window.TdAuth.refreshTesterPermissions();
        if (!cancelled && res.ok && res.is_tester) {
          setTesterPerms(res.permissions || []);
          setTesterMeta({
            account_id: res.account_id,
            expires_at: res.expires_at,
            label: res.label,
          });
        }
      }
      const localOnboarding = {
        step_profile_complete: !!proCtx.npi,
        step_first_agent_active: (proCtx.agentsActivated || []).length > 0,
        step_first_patient_processed: proCtx.firstPatientProcessed || false,
        step_hitl_reviewed: proCtx.firstHitlReviewed || false,
        step_billing_configured: proCtx.billingConfigured || false,
        workflow_stage: proCtx.workflowStage || 'onboarding',
        pending_hitl_count: proCtx.pendingHitl || 0,
        agents_used: proCtx.agentsActivated || [],
      };
      if (!cancelled) {
        setOnboarding(localOnboarding);
        setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, []);

  const nextAction = deriveNextAction(onboarding, role);
  const workflowStage = onboarding?.workflow_stage || 'onboarding';
  const completedSteps = onboarding ? ONBOARDING_FLOW.filter(s => isOnboardingStepDone(onboarding, s.id)).length : 0;
  const onboardingProgress = Math.round((completedSteps / ONBOARDING_FLOW.length) * 100);

  const sidebarBadges = { hitl: hitlCount, recall: recallCount };

  if (loading) return React.createElement(PortalLoadingScreen, { role });

  return React.createElement('div', {
    className: 'pro-dashboard animate-fade-in-up',
    style: { display: 'flex', minHeight: '100vh' }
  },

    // ── Sidebar ──────────────────────────────────────────────────────────────
    React.createElement(PortalSidebar, {
      role, navItems, activeNav, onNavigate: setActiveNav,
      badges: sidebarBadges, proCtx, onboardingProgress,
    }),

    // ── Main content ─────────────────────────────────────────────────────────
    React.createElement('main', { style: { flex: 1, padding: '32px 32px 64px', minWidth: 0, maxWidth: 900 } },

      // Page header
      React.createElement(PortalHeader, { role, proCtx, workflowStage }),

      React.createElement('div', { className: 'disclaimer-banner' },
        'AI-assisted tools provide information, not diagnosis. Clinical outputs require licensed review before patient use. ',
        React.createElement('a', { href: '/methodology/', className: 'methodology-link' }, 'Methodology')
      ),

      testerPerms.length > 0 && React.createElement('div', {
        className: 'preview-banner',
        style: { marginBottom: 16, fontSize: 13, lineHeight: 1.5 },
      },
        React.createElement('strong', null, 'Beta tester access'),
        ' — ',
        testerMeta.label || 'Limited preview',
        testerMeta.expires_at
          ? ` · expires ${new Date(testerMeta.expires_at).toLocaleDateString()}`
          : '',
        ' · ',
        testerPerms.length,
        ' feature',
        testerPerms.length === 1 ? '' : 's',
        ' enabled',
      ),

      // Onboarding progress banner (show until complete)
      can('feature:onboarding') && onboardingProgress < 100 && React.createElement(OnboardingProgressBanner, {
        steps: ONBOARDING_FLOW, onboarding, progress: onboardingProgress,
      }),

      // Next Move card (always visible, updates per stage)
      nextAction && React.createElement(NextMoveCard, { action: nextAction, stage: workflowStage }),

      // HITL queue summary
      can('feature:hitl_card') && hitlCount > 0 && React.createElement(HitlQueueCard, { count: hitlCount, overdueCount: Math.floor(hitlCount * 0.3) }),

      // Role-specific content
      role === 'hygienist'
        ? React.createElement(HygienistContent, { proCtx, can })
        : React.createElement(DentistContent, { onboarding, proCtx, role, can }),
    ),
  );
}

// ─── Sidebar ──────────────────────────────────────────────────────────────────
function PortalSidebar({ role, navItems, activeNav, onNavigate, badges, proCtx, onboardingProgress }) {
  const roleColor = role === 'hygienist' ? T.green : T.navy;

  return React.createElement('aside', {
    style: {
      width: 220, flexShrink: 0, background: roleColor,
      display: 'flex', flexDirection: 'column',
      minHeight: '100vh', position: 'sticky', top: 0,
    }
  },
    // Logo
    React.createElement('div', { style: { padding: '28px 20px 20px' } },
      React.createElement('span', { style: { color: 'white', fontSize: 13, fontWeight: 800, letterSpacing: -0.5 } }, 'TheDentist.ai'),
      React.createElement('div', { style: { fontSize: 11, color: 'rgba(255,255,255,0.5)', marginTop: 2, letterSpacing: 1, textTransform: 'uppercase' } },
        role === 'hygienist' ? 'Smile Mentors' : 'Dentist Apprentice OS'
      ),
    ),

    // Practice info
    React.createElement('div', { style: { padding: '0 16px 16px', borderBottom: '1px solid rgba(255,255,255,0.12)' } },
      React.createElement('div', {
        style: {
          background: 'rgba(255,255,255,0.1)', borderRadius: T.radius.md,
          padding: '10px 12px', display: 'flex', alignItems: 'center', gap: 10,
        }
      },
        React.createElement('div', {
          style: { width: 32, height: 32, borderRadius: 8, background: role === 'hygienist' ? T.greenLight : T.mint, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }
        }, React.createElement(SvgIcon, { d: ICONS.users, size: 16, color: 'white' })),
        React.createElement('div', { style: { minWidth: 0 } },
          React.createElement('div', { style: { color: 'white', fontSize: 12, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } },
            proCtx.practiceName || (role === 'hygienist' ? 'Your Portal' : 'Your Practice')
          ),
          React.createElement('div', { style: { color: 'rgba(255,255,255,0.5)', fontSize: 11 } },
            proCtx.subscriptionTier ? proCtx.subscriptionTier + ' plan' : 'Free trial'
          ),
        ),
      ),
      // Onboarding progress ring
      onboardingProgress < 100 && React.createElement('div', { style: { marginTop: 10, display: 'flex', alignItems: 'center', gap: 8 } },
        React.createElement('div', { style: { flex: 1, height: 3, background: 'rgba(255,255,255,0.2)', borderRadius: 2 } },
          React.createElement('div', { style: { width: `${onboardingProgress}%`, height: '100%', background: role === 'hygienist' ? T.greenLight : T.mint, borderRadius: 2, transition: 'width 0.5s ease' } })
        ),
        React.createElement('span', { style: { color: 'rgba(255,255,255,0.6)', fontSize: 11, flexShrink: 0 } }, `${onboardingProgress}% set up`),
      ),
    ),

    // Nav items
    React.createElement('nav', { style: { flex: 1, padding: '12px 8px' } },
      navItems.map(item => {
        const isActive = activeNav === item.id;
        const badgeCount = item.badge ? (badges[item.badge] || 0) : 0;
        return React.createElement('a', {
          key: item.id,
          href: item.href,
          onClick: e => {
            const isDashboard = item.id === 'dashboard';
            const onFindSpa = typeof window !== 'undefined'
              && (window.location.pathname === '/find' || window.location.pathname.startsWith('/find/'));
            if (isDashboard && onFindSpa) {
              e.preventDefault();
              onNavigate(item.id);
              const target = item.href.split('#')[1] || 'dentist-portal';
              if ((window.location.hash || '').replace('#', '') !== target) {
                window.location.hash = target;
              }
              return;
            }
            onNavigate(item.id);
          },
          style: {
            display: 'flex', alignItems: 'center', gap: 10,
            padding: '9px 12px', borderRadius: T.radius.md, marginBottom: 2,
            background: isActive ? 'rgba(255,255,255,0.12)' : 'transparent',
            textDecoration: 'none', transition: 'background 0.15s',
            cursor: 'pointer',
          },
          onMouseEnter: e => { if (!isActive) e.currentTarget.style.background = 'rgba(255,255,255,0.07)'; },
          onMouseLeave: e => { if (!isActive) e.currentTarget.style.background = 'transparent'; },
        },
          React.createElement(SvgIcon, { d: ICONS[item.icon] || ICONS.grid, size: 16, color: isActive ? 'white' : 'rgba(255,255,255,0.55)' }),
          React.createElement('span', { style: { color: isActive ? 'white' : 'rgba(255,255,255,0.55)', fontSize: 13, fontWeight: isActive ? 600 : 400, flex: 1 } }, item.label),
          badgeCount > 0 && React.createElement('span', {
            style: { background: T.red, color: 'white', borderRadius: 20, padding: '1px 6px', fontSize: 10, fontWeight: 700, minWidth: 18, textAlign: 'center' }
          }, badgeCount > 99 ? '99+' : badgeCount),
        );
      })
    ),

    // Portal shortcuts + back to consumer site
    React.createElement('div', { style: { padding: '12px 8px', borderTop: '1px solid rgba(255,255,255,0.1)' } },
      PORTAL_QUICK_LINKS.map(link =>
        React.createElement('a', {
          key: link.href,
          href: link.href,
          style: {
            display: 'flex', alignItems: 'center', gap: 8,
            padding: '6px 12px', textDecoration: 'none', borderRadius: T.radius.md,
            marginBottom: 2,
          },
          onMouseEnter: e => { e.currentTarget.style.background = 'rgba(255,255,255,0.07)'; },
          onMouseLeave: e => { e.currentTarget.style.background = 'transparent'; },
        },
          React.createElement('span', { style: { color: 'rgba(255,255,255,0.45)', fontSize: 11 } }, link.label),
        )
      ),
      React.createElement('a', {
        href: '/',
        style: { display: 'flex', alignItems: 'center', gap: 10, padding: '8px 12px', textDecoration: 'none', borderRadius: T.radius.md, marginTop: 6 }
      },
        React.createElement(SvgIcon, { d: ICONS.home, size: 14, color: 'rgba(255,255,255,0.4)' }),
        React.createElement('span', { style: { color: 'rgba(255,255,255,0.4)', fontSize: 12 } }, 'Back to main site'),
      )
    ),
  );
}

// ─── Portal header ────────────────────────────────────────────────────────────
function PortalHeader({ role, proCtx, workflowStage }) {
  const now = new Date();
  const hour = now.getHours();
  const greeting = hour < 12 ? 'Good morning' : hour < 17 ? 'Good afternoon' : 'Good evening';
  const name = proCtx.doctorName || proCtx.practiceName || (role === 'hygienist' ? 'there' : 'Doctor');
  const STAGE_LABELS = { onboarding: 'Getting started', profile_ready: 'Almost ready', first_agent: 'Agent active', active: 'Active', growth: 'Growing', power_user: 'Pro' };

  return React.createElement('div', { style: { marginBottom: 28, display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between' } },
    React.createElement('div', null,
      React.createElement('h1', { style: { margin: '0 0 4px', fontSize: 24, fontWeight: 700, color: T.navy } },
        `${greeting}, ${name}`
      ),
      React.createElement('p', { style: { margin: 0, color: T.slate, fontSize: 14 } },
        now.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' })
      ),
    ),
    React.createElement('div', {
      style: { background: T.white, border: `1px solid ${T.light}`, borderRadius: T.radius.md, padding: '6px 12px', fontSize: 12, color: T.slate, display: 'flex', alignItems: 'center', gap: 6 }
    },
      React.createElement('span', { style: { width: 6, height: 6, borderRadius: '50%', background: T.mint, display: 'inline-block' } }),
      STAGE_LABELS[workflowStage] || 'Active',
    ),
  );
}

// ─── Onboarding progress banner ───────────────────────────────────────────────
function OnboardingProgressBanner({ steps, onboarding, progress }) {
  const [expanded, setExpanded] = useState(progress < 40);
  const nextStep = steps.find(s => !onboarding?.[`step_${s.id}_complete`]);

  return React.createElement('div', { className: 'card', style: { marginBottom: 20, overflow: 'hidden', padding: 0 } },
    // Header
    React.createElement('button', {
      onClick: () => setExpanded(e => !e),
      style: { width: '100%', display: 'flex', alignItems: 'center', padding: '16px 20px', background: 'none', border: 'none', cursor: 'pointer', gap: 12 }
    },
      React.createElement('div', { style: { flex: 1, display: 'flex', alignItems: 'center', gap: 12 } },
        React.createElement('div', { style: { position: 'relative', width: 36, height: 36, flexShrink: 0 } },
          React.createElement('svg', { width: 36, height: 36, style: { transform: 'rotate(-90deg)' } },
            React.createElement('circle', { cx: 18, cy: 18, r: 14, fill: 'none', stroke: T.light, strokeWidth: 3 }),
            React.createElement('circle', { cx: 18, cy: 18, r: 14, fill: 'none', stroke: T.mint, strokeWidth: 3, strokeDasharray: `${2 * Math.PI * 14}`, strokeDashoffset: `${2 * Math.PI * 14 * (1 - progress / 100)}`, strokeLinecap: 'round' }),
          ),
          React.createElement('span', { style: { position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 9, fontWeight: 700, color: T.navy } }, `${progress}%`),
        ),
        React.createElement('div', { style: { textAlign: 'left' } },
          React.createElement('div', { style: { fontSize: 14, fontWeight: 600, color: T.navy } }, `Set up your practice — ${progress}% complete`),
          nextStep && React.createElement('div', { style: { fontSize: 12, color: T.slate, marginTop: 1 } }, `Next: ${nextStep.label}`),
        ),
      ),
      React.createElement(SvgIcon, { d: expanded ? ICONS.chevDown : ICONS.chevRight, size: 16, color: T.slate, style: { transform: expanded ? 'rotate(0deg)' : 'none', transition: 'transform 0.2s' } }),
    ),

    // Steps list
    expanded && React.createElement('div', { style: { padding: '0 20px 16px', borderTop: `1px solid ${T.light}` } },
      steps.map((step, i) => {
        const done = isOnboardingStepDone(onboarding, step.id);
        const isNext = !done && steps.slice(0, i).every(s => isOnboardingStepDone(onboarding, s.id));
        return React.createElement('div', {
          key: step.id,
          style: { display: 'flex', alignItems: 'center', gap: 12, padding: '10px 0', borderBottom: i < steps.length - 1 ? `1px solid ${T.light}` : 'none' }
        },
          React.createElement('div', {
            style: {
              width: 28, height: 28, borderRadius: '50%', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
              background: done ? T.mint : isNext ? T.navy : T.light,
            }
          },
            done
              ? React.createElement(SvgIcon, { d: ICONS.check, size: 14, color: 'white' })
              : React.createElement('span', { style: { fontSize: 11, fontWeight: 700, color: done ? 'white' : isNext ? 'white' : T.slate } }, i + 1)
          ),
          React.createElement('div', { style: { flex: 1 } },
            React.createElement('div', { style: { fontSize: 13, fontWeight: 600, color: done ? T.slate : T.navy, textDecoration: done ? 'line-through' : 'none' } }, step.label),
            React.createElement('div', { style: { fontSize: 12, color: T.slate } }, step.desc),
          ),
          isNext && React.createElement('a', {
            href: step.route,
            style: { background: T.navy, color: 'white', borderRadius: T.radius.sm, padding: '6px 12px', fontSize: 12, fontWeight: 600, textDecoration: 'none', flexShrink: 0 }
          }, step.cta),
          done && React.createElement(SvgIcon, { d: ICONS.check, size: 14, color: T.mint }),
        );
      })
    ),
  );
}

// ─── Next Move card ────────────────────────────────────────────────────────────
function NextMoveCard({ action, stage }) {
  const [dismissed, setDismissed] = useState(false);
  if (dismissed) return null;

  const priorityColors = { urgent: T.red, high: T.amber, medium: T.navy, low: T.mint };
  const priorityLabels = {
    urgent: { icon: 'dot', color: '#EF4444', text: 'Urgent' },
    high: { icon: 'dotWarn', color: '#F59E0B', text: 'High priority' },
    medium: { text: 'Recommended' },
    low: { text: 'Suggested' },
  };
  const color = priorityColors[action.priority] || T.navy;

  return React.createElement('div', {
    style: {
      background: `linear-gradient(135deg, ${color} 0%, ${color}CC 100%)`,
      borderRadius: T.radius.lg, padding: '24px 24px 20px', marginBottom: 20, color: 'white', position: 'relative',
    }
  },
    React.createElement('button', {
      onClick: () => setDismissed(true),
      style: { position: 'absolute', top: 12, right: 12, background: 'rgba(255,255,255,0.2)', border: 'none', borderRadius: '50%', width: 24, height: 24, cursor: 'pointer', color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center' }
    }, React.createElement(SvgIcon, { d: ICONS.x, size: 12, color: 'white' })),
    React.createElement('div', { style: { fontSize: 11, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase', marginBottom: 8, opacity: 0.8, display: 'flex', alignItems: 'center', gap: 6 } },
      (() => {
        const pl = priorityLabels[action.priority] || { text: 'Your Next Move' };
        return [
          pl.icon && window.FlatIcon && React.createElement(window.FlatIcon, { key: 'i', name: pl.icon, size: 10, color: pl.color || 'rgba(255,255,255,0.85)' }),
          pl.text,
        ];
      })()
    ),
    React.createElement('h3', { style: { margin: '0 0 6px', fontSize: 18, fontWeight: 700 } }, action.title),
    React.createElement('p', { style: { margin: '0 0 16px', opacity: 0.85, fontSize: 14, lineHeight: 1.5 } }, action.description),
    React.createElement('a', {
      href: action.route,
      style: { display: 'inline-flex', alignItems: 'center', gap: 6, background: 'white', color: color, borderRadius: T.radius.sm, padding: '8px 16px', fontSize: 13, fontWeight: 700, textDecoration: 'none' }
    }, action.cta_label, React.createElement(SvgIcon, { d: ICONS.arrowRight, size: 14, color })),
  );
}

// ─── HITL Queue card ───────────────────────────────────────────────────────────
function HitlQueueCard({ count, overdueCount }) {
  return React.createElement('div', {
    className: 'preview-banner',
    style: { display: 'flex', alignItems: 'center', gap: 16, marginBottom: 20 }
  },
    React.createElement('div', {
      style: { width: 40, height: 40, background: 'var(--color-warning)', borderRadius: 'var(--radius-md)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }
    }, React.createElement(SvgIcon, { d: ICONS.alert, size: 20, color: 'white' })),
    React.createElement('div', { style: { flex: 1 } },
      React.createElement('div', { style: { fontWeight: 700, color: 'var(--color-warning)', fontSize: 14, marginBottom: 2 } },
        `${count} item${count !== 1 ? 's' : ''} need${count === 1 ? 's' : ''} your review`
      ),
      React.createElement('div', { className: 'hitl-badge', style: { fontSize: 12 } },
        overdueCount > 0 ? `${overdueCount} overdue (>48h) — patients may be waiting` : 'All within 48-hour SLA'
      ),
    ),
    React.createElement('a', {
      href: '/command/',
      className: 'btn btn-primary btn-sm',
      style: { textDecoration: 'none', flexShrink: 0 }
    }, 'Review now'),
  );
}

// ─── Dentist main content ─────────────────────────────────────────────────────
function DentistContent({ onboarding, proCtx, role, can }) {
  const canFn = can || (() => true);
  const [expandedTier, setExpandedTier] = useState('basic');
  const activatedAgents = onboarding?.agents_used || [];
  const tier = proCtx.subscriptionTier || 'basic';

  const agentsByTier = {
    basic:    Object.entries(AGENTS).filter(([, a]) => a.tier === 'basic'),
    pro:      Object.entries(AGENTS).filter(([, a]) => a.tier === 'pro'),
    clinical: Object.entries(AGENTS).filter(([, a]) => a.tier === 'clinical'),
  };

  const tierLabels = { basic: 'Practice Pass Basic', pro: 'Practice Pass Pro', clinical: 'Clinical OS' };
  const tierLocked = {
    basic: !canFn('tier:basic'),
    pro: tier === 'basic' || !canFn('tier:pro'),
    clinical: tier !== 'clinical' || !canFn('tier:clinical'),
  };

  const visibleTiers = ['basic', 'pro', 'clinical'].filter((t) => canFn(`tier:${t}`));

  return React.createElement('div', null,
    // Metrics row (placeholder — would be real data in production)
    React.createElement(MetricsRow),

    // Agent grid with tier sections
    React.createElement('div', { style: { marginTop: 28 } },
      React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 } },
        React.createElement('h2', { style: { margin: 0, fontSize: 17, fontWeight: 700, color: T.navy } }, 'AI Agents'),
        React.createElement('a', { href: findSpaHash('dentist-portal'), style: { fontSize: 13, color: T.mint, textDecoration: 'none', fontWeight: 600 } }, 'Manage all →'),
      ),

      ['basic', 'pro', 'clinical'].filter((t) => visibleTiers.includes(t)).map(tierKey =>
        React.createElement('div', { key: tierKey, style: { marginBottom: 16 } },
          // Tier header
          React.createElement('button', {
            onClick: () => setExpandedTier(expandedTier === tierKey ? null : tierKey),
            style: {
              width: '100%', display: 'flex', alignItems: 'center', gap: 10,
              background: 'none', border: 'none', cursor: 'pointer', padding: '8px 0', marginBottom: expandedTier === tierKey ? 10 : 0,
            }
          },
            React.createElement('span', { style: { fontSize: 11, fontWeight: 700, letterSpacing: 1, textTransform: 'uppercase', color: TIER_COLORS[tierKey], flex: 1, textAlign: 'left' } },
              tierLabels[tierKey]
            ),
            tierLocked[tierKey] && React.createElement('span', { style: { fontSize: 11, color: T.slate, background: T.light, borderRadius: 4, padding: '2px 6px' } }, 'Upgrade'),
            React.createElement(SvgIcon, { d: expandedTier === tierKey ? ICONS.chevDown : ICONS.chevRight, size: 14, color: T.slate }),
          ),

          // Agent cards
          expandedTier === tierKey && React.createElement('div', { className: 'agent-grid' },
            agentsByTier[tierKey].map(([agentId, agent]) => {
              const isActive = activatedAgents.includes(agentId);
              const isLocked = tierLocked[tierKey];
              return React.createElement(AgentCard, { key: agentId, agentId, agent, isActive, isLocked, tier: tierKey });
            })
          ),
        )
      ),
    ),

    // Tool suggestions
    React.createElement(ToolSuggestions, { onboarding, tier }),
  );
}

// ─── Agent card ───────────────────────────────────────────────────────────────
function AgentCard({ agentId, agent, isActive, isLocked, tier }) {
  const [hover, setHover] = useState(false);
  const color = TIER_COLORS[tier];

  const handleActivate = () => {
    if (isLocked) { window.location.href = SUITE_AGENTS_HREF; return; }
    const proCtx = (() => { try { return JSON.parse(localStorage.getItem('td_pro_ctx') || '{}'); } catch { return {}; } })();
    const next = { ...proCtx, agentsActivated: [...(proCtx.agentsActivated || []), agentId] };
    localStorage.setItem('td_pro_ctx', JSON.stringify(next));
    if (typeof trackEvent !== 'undefined') trackEvent('agent_activated', { agentId });
    window.location.href = SUITE_AGENTS_HREF;
  };

  return React.createElement('div', {
    className: 'card',
    onMouseEnter: () => setHover(true),
    onMouseLeave: () => setHover(false),
    style: {
      padding: '14px 16px',
      transition: 'all 0.15s', cursor: 'pointer', opacity: isLocked ? 0.7 : 1,
      borderColor: isActive ? color : undefined,
      boxShadow: hover && !isLocked ? 'var(--shadow-sm)' : undefined,
    }
  },
    // Header
    React.createElement('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 } },
      React.createElement('div', {
        style: { width: 28, height: 28, borderRadius: 'var(--radius-sm)', background: isActive ? `${color}20` : 'var(--color-surface-raised)', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }
      }, React.createElement(SvgIcon, { d: ICONS[agent.icon] || ICONS.cpu, size: 14, color: isActive ? color : 'var(--color-text-tertiary)' })),
      React.createElement('span', { style: { fontSize: 12, fontWeight: 700, color: 'var(--color-text-primary)', flex: 1, lineHeight: 1.3 } }, agent.label),
      isActive && React.createElement('span', { className: 'badge badge-green' }, 'Active'),
      isLocked && React.createElement(SvgIcon, { d: ICONS.lock, size: 12, color: 'var(--color-text-tertiary)' }),
    ),
    React.createElement('p', { className: 'section-subtitle', style: { margin: '0 0 10px', fontSize: 11 } }, agent.desc),
    React.createElement('span', { className: 'hitl-badge' }, 'SB 1120 · pending review before patient-facing use'),
    // CTA
    React.createElement('button', {
      type: 'button',
      onClick: handleActivate,
      className: isLocked ? 'btn btn-ghost btn-sm' : isActive ? 'btn btn-secondary btn-sm' : 'btn btn-primary btn-sm',
      style: { marginTop: 8 }
    }, isLocked ? 'Upgrade' : isActive ? 'Configure →' : 'Activate'),
  );
}

// ─── Metrics row ─────────────────────────────────────────────────────────────
function MetricsRow() {
  const metrics = [
    { label: 'Patients this month', value: '—', change: null, icon: 'users' },
    { label: 'Claims submitted', value: '—', change: null, icon: 'zap' },
    { label: 'Collection rate', value: '—', change: null, icon: 'trendUp' },
    { label: 'Recall rate',     value: '—', change: null, icon: 'refresh' },
  ];
  return React.createElement('div', { className: 'metric-grid' },
    metrics.map((m, i) =>
      React.createElement('div', {
        key: i,
        className: 'card',
        style: { padding: '16px' }
      },
        React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 } },
          React.createElement('span', { className: 'section-subtitle', style: { fontSize: 11, fontWeight: 500 } }, m.label),
          React.createElement(SvgIcon, { d: ICONS[m.icon] || ICONS.barChart, size: 14, color: 'var(--color-text-tertiary)' }),
        ),
        React.createElement('div', { style: { fontSize: 22, fontWeight: 700, color: 'var(--color-text-primary)' } }, m.value),
        React.createElement('div', { className: 'section-subtitle', style: { fontSize: 11, marginTop: 2 } },
          'Connect your PMS to see live data · ',
          React.createElement('a', { href: '/methodology/', className: 'methodology-link' }, 'methodology')
        ),
      )
    )
  );
}

// ─── Tool suggestions ─────────────────────────────────────────────────────────
function ToolSuggestions({ onboarding, tier }) {
  const tools = [];
  if (!onboarding?.step_billing_configured) {
    tools.push({ label: 'Benefit Bomber', desc: 'Recover unused insurance benefits before year-end.', route: findSpaHash('benefit-bomber'), icon: 'dollar', color: T.mint });
  }
  if (tier === 'basic') {
    tools.push({ label: 'Second Opinion Engine', desc: 'Help patients validate treatment plans.', route: findSpaHash('second-opinion'), icon: 'shield', color: T.navy });
  }
  tools.push({ label: 'SmileCam Pro', desc: 'Clinical photography, case presentation.', route: '/for-dentists/suite/#scribe', icon: 'star', color: T.purple });

  if (!tools.length) return null;

  return React.createElement('div', { style: { marginTop: 28 } },
    React.createElement('h2', { style: { fontSize: 17, fontWeight: 700, color: T.navy, marginBottom: 14 } }, 'Recommended tools'),
    React.createElement('div', { style: { display: 'flex', gap: 12, overflowX: 'auto', paddingBottom: 4 } },
      tools.map((t, i) =>
        React.createElement('a', {
          key: i, href: t.route,
          style: {
            flexShrink: 0, background: T.white, border: `1px solid ${T.light}`, borderRadius: T.radius.md,
            padding: '16px 18px', textDecoration: 'none', minWidth: 180,
            display: 'flex', flexDirection: 'column', gap: 8, transition: 'all 0.15s',
          },
          onMouseEnter: e => { e.currentTarget.style.boxShadow = T.shadow.sm; e.currentTarget.style.borderColor = t.color; },
          onMouseLeave: e => { e.currentTarget.style.boxShadow = 'none'; e.currentTarget.style.borderColor = T.light; },
        },
          React.createElement('div', { style: { width: 32, height: 32, borderRadius: T.radius.sm, background: `${t.color}15`, display: 'flex', alignItems: 'center', justifyContent: 'center' } },
            React.createElement(SvgIcon, { d: ICONS[t.icon] || ICONS.zap, size: 16, color: t.color })
          ),
          React.createElement('div', { style: { fontSize: 13, fontWeight: 700, color: T.navy } }, t.label),
          React.createElement('div', { style: { fontSize: 12, color: T.slate } }, t.desc),
        )
      )
    )
  );
}

// ─── Hygienist-specific content ────────────────────────────────────────────────
function HygienistContent({ proCtx }) {
  const scheduleItems = [
    { time: '9:00 AM', patient: 'Patient #1', type: 'Adult Prophy', status: 'confirmed' },
    { time: '10:00 AM', patient: 'Patient #2', type: 'Child Prophy', status: 'confirmed' },
    { time: '11:00 AM', patient: '— Available —', type: '', status: 'open' },
    { time: '1:00 PM', patient: 'Patient #3', type: 'Perio Maintenance', status: 'pending' },
  ];

  return React.createElement('div', null,
    // Today's schedule
    React.createElement('div', { style: { background: T.white, border: `1px solid ${T.light}`, borderRadius: T.radius.lg, overflow: 'hidden', marginBottom: 16 } },
      React.createElement('div', { style: { padding: '16px 20px', borderBottom: `1px solid ${T.light}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between' } },
        React.createElement('h2', { style: { margin: 0, fontSize: 15, fontWeight: 700, color: T.navy } }, "Today's Schedule"),
        React.createElement('a', { href: findSpaHash('schedule'), style: { fontSize: 13, color: T.mint, textDecoration: 'none', fontWeight: 600 } }, 'Full view →'),
      ),
      scheduleItems.map((item, i) =>
        React.createElement('div', {
          key: i,
          style: { padding: '12px 20px', display: 'flex', alignItems: 'center', gap: 14, borderBottom: i < scheduleItems.length - 1 ? `1px solid ${T.light}` : 'none', background: item.status === 'open' ? '#F0FDF9' : 'white' }
        },
          React.createElement('span', { style: { fontSize: 12, color: T.slate, width: 64, flexShrink: 0 } }, item.time),
          React.createElement('div', { style: { flex: 1 } },
            React.createElement('div', { style: { fontSize: 13, fontWeight: item.status === 'open' ? 500 : 600, color: item.status === 'open' ? T.mint : T.navy } }, item.patient),
            item.type && React.createElement('div', { style: { fontSize: 12, color: T.slate } }, item.type),
          ),
          React.createElement('span', {
            style: {
              fontSize: 11, fontWeight: 600, padding: '2px 8px', borderRadius: 20,
              background: item.status === 'confirmed' ? '#D1FAE5' : item.status === 'open' ? '#F0FDF9' : '#FEF3C7',
              color: item.status === 'confirmed' ? T.green : item.status === 'open' ? T.mint : T.amber,
            }
          }, item.status),
        )
      ),
    ),

    // CE and job board row
    React.createElement('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 } },
      React.createElement(HygienistCECard),
      React.createElement(HygienistJobCard),
    ),
  );
}

function HygienistCECard() {
  return React.createElement('div', { style: { background: T.white, border: `1px solid ${T.light}`, borderRadius: T.radius.lg, padding: '20px' } },
    React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 } },
      React.createElement('h3', { style: { margin: 0, fontSize: 14, fontWeight: 700, color: T.navy } }, 'CE Progress'),
      React.createElement('a', { href: findSpaHash('ce-hub'), style: { fontSize: 12, color: T.mint, textDecoration: 'none', fontWeight: 600 } }, 'View all'),
    ),
    React.createElement('div', { style: { fontSize: 28, fontWeight: 700, color: T.green, marginBottom: 4 } }, '— / 24'),
    React.createElement('div', { style: { fontSize: 12, color: T.slate, marginBottom: 12 } }, 'CE hours completed this cycle'),
    React.createElement('div', { style: { height: 6, background: T.light, borderRadius: 3 } },
      React.createElement('div', { style: { width: '30%', height: '100%', background: T.greenLight, borderRadius: 3 } })
    ),
    React.createElement('p', { style: { marginTop: 10, fontSize: 12, color: T.slate } }, 'Connect your CE records to track progress.'),
  );
}

function HygienistJobCard() {
  return React.createElement('div', { style: { background: T.white, border: `1px solid ${T.light}`, borderRadius: T.radius.lg, padding: '20px' } },
    React.createElement('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 } },
      React.createElement('h3', { style: { margin: 0, fontSize: 14, fontWeight: 700, color: T.navy } }, 'PRN Opportunities'),
      React.createElement('a', { href: findSpaHash('jobs'), style: { fontSize: 12, color: T.mint, textDecoration: 'none', fontWeight: 600 } }, 'Browse all'),
    ),
    React.createElement('div', { style: { fontSize: 28, fontWeight: 700, color: T.navy, marginBottom: 4 } }, '—'),
    React.createElement('div', { style: { fontSize: 12, color: T.slate, marginBottom: 10 } }, 'Open shifts near you'),
    React.createElement('a', {
      href: findSpaHash('jobs'),
      style: { display: 'block', background: T.green, color: 'white', borderRadius: T.radius.sm, padding: '8px 14px', fontSize: 13, fontWeight: 600, textDecoration: 'none', textAlign: 'center' }
    }, 'Set my availability'),
  );
}

// ─── Loading screen ────────────────────────────────────────────────────────────
function PortalLoadingScreen({ role }) {
  return React.createElement('div', {
    className: 'pro-dashboard',
    style: { minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }
  },
    React.createElement('div', { style: { textAlign: 'center' } },
      React.createElement('div', { className: 'skeleton', style: { width: 44, height: 44, borderRadius: '50%', margin: '0 auto 16px' } }),
      React.createElement('p', { className: 'section-subtitle' }, 'Loading your portal…'),
    )
  );
}

// ─── Derive next action (mirrors API logic) ────────────────────────────────────
function deriveNextAction(onboarding, role) {
  const CG = typeof window !== 'undefined' ? window.ClaimGate : null;
  const clinician = CG ? CG.isClinicianRole(role) : ['dentist', 'hygienist', 'front_desk', 'clinician', 'pro', 'practice'].includes(role);
  if (!clinician) return null;
  const hasNpi = CG ? CG.canShowClaimCta({ role }) : false;
  if (!onboarding) {
    if (!hasNpi) {
      return {
        title: 'Find your NPI',
        description: 'Enter your 10-digit National Provider Identifier before claiming your profile.',
        route: '/for-dentists/#find-npi',
        cta_label: 'Find your NPI',
        priority: 'high',
      };
    }
    return {
      title: 'Complete your profile',
      description: 'Add your NPI and practice details to get started.',
      route: '/portal/practitioner/',
      cta_label: 'Set Up Profile',
      priority: 'high',
    };
  }
  const { step_profile_complete, step_first_agent_active, step_first_patient_processed, step_billing_configured, pending_hitl_count } = onboarding;
  if (!step_profile_complete) {
    if (!hasNpi) {
      return {
        title: 'Find your NPI',
        description: 'Add your NPI, specialty, and practice details.',
        route: '/for-dentists/#find-npi',
        cta_label: 'Find your NPI',
        priority: 'high',
      };
    }
    return {
      title: 'Complete your profile',
      description: 'Add your NPI, specialty, and practice details.',
      route: '/portal/practitioner/',
      cta_label: 'Complete Profile',
      priority: 'high',
    };
  }
  if (!step_first_agent_active) return { title: 'Activate your first AI agent', description: 'Start with the AI Receptionist — it answers calls 24/7.', route: SUITE_AGENTS_HREF, cta_label: 'Activate Receptionist', priority: 'high' };
  if (pending_hitl_count > 0) return { title: `${pending_hitl_count} item${pending_hitl_count !== 1 ? 's' : ''} need your review`, description: 'The AI flagged these before sending to patients.', route: '/command/', cta_label: 'Review Now', priority: 'urgent' };
  if (!step_first_patient_processed) return { title: 'Process your first patient', description: 'Let the AI Intake agent handle new patient paperwork.', route: findSpaHash('forms'), cta_label: 'Start Intake', priority: 'medium' };
  if (!step_billing_configured) return { title: 'Set up billing automation', description: 'Unlock claim submission and EOB auto-posting.', route: '/for-dentists/suite/#treatment-plan', cta_label: 'Configure Billing', priority: 'medium' };
  return { title: "You're all set!", description: 'Explore advanced agents or invite your team to get more done.', route: SUITE_AGENTS_HREF, cta_label: 'Explore Agents', priority: 'low' };
}

// Expose
window.ProfessionalDashboard = ProfessionalDashboard;
window.AgentCard = AgentCard;
window.NextMoveCard = NextMoveCard;
