import { For, Show, createMemo, createSignal, onMount, Switch, Match } from 'solid-js';
import { LayoutDashboard } from 'lucide-solid';
import { BTN_GHOST, BTN_PRIMARY, CARD } from '~/components/DashboardShell';
import { normalizeRole, PROFESSIONAL_ROLE_SET, ROLE_PREFIXES, type RoleKey } from './RoleDashboardShared';
import WalletWidget from './widgets/WalletWidget';
import LeadsWidget from './widgets/LeadsWidget';
import JobsWidget from './widgets/JobsWidget';
import ApplicationsWidget from './widgets/ApplicationsWidget';
import RequirementsWidget from './widgets/RequirementsWidget';
import ShortlistedWidget from './widgets/ShortlistedWidget';
import PortfolioWidget from './widgets/PortfolioWidget';
import ProfileCompletionWidget from './widgets/ProfileCompletionWidget';
import VerificationWidget from './widgets/VerificationWidget';
import AiUsageWidget from './widgets/AiUsageWidget';
import VerificationSubmissionGuide from './VerificationSubmissionGuide';
import { fetchProfile, fetchDocuments } from '~/lib/api';
import {
  getBasicFields,
  getDocFields,
  getPortfolioSections,
  roleHasPortfolio,
} from '~/lib/profile-fields-config';

// Inline apiFetch matching ProfilePage pattern
async function apiFetch(path: string, opts?: RequestInit) {
  const API = '';
  const token = typeof window !== 'undefined'
    ? (sessionStorage.getItem('nxtgauge_access_token') || '')
    : '';
  const res = await fetch(`${API}${path}`, {
    headers: {
      'Content-Type': 'application/json',
      Accept: 'application/json',
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
    credentials: 'include',
    ...opts,
  });
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`API error ${res.status}: ${text}`);
  }
  return res.json();
}

const NAVY = '#0D0D2A';
const ORANGE = '#FF5E13';

type Props = {
  roleKey: RoleKey;
  userName?: string;
  widgetKeys?: string[];
  verificationStatus?: string;
  onNavigate?: (sidebar: string) => void;
  onVerificationStatusChange?: (status: string) => void;
};

const DEFAULT_WIDGETS: Record<string, string[]> = {
  PROFESSIONAL: ['tracecoins', 'open_leads', 'my_requests', 'ai_usage', 'portfolio', 'profile_status', 'verification_status'],
  COMPANY: ['tracecoins', 'total_jobs', 'applications_received', 'ai_usage', 'shortlisted_candidates', 'profile_status', 'verification_status'],
  CUSTOMER: ['credits', 'total_requirements', 'ai_usage', 'shortlisted_responses'],
  JOB_SEEKER: ['credits', 'available_jobs', 'ai_usage', 'my_applications', 'shortlisted', 'profile_status', 'verification_status'],
};

type Metric = {
  title: string;
  value: string;
  hint: string;
};

const WIDGET_COMPONENTS: Record<string, (props: { roleKey: RoleKey }) => any> = {
  tracecoins: WalletWidget,
  credits: WalletWidget,
  open_leads: LeadsWidget,
  my_requests: LeadsWidget,
  total_requirements: RequirementsWidget,
  open_requirements: RequirementsWidget,
  closed_requirements: RequirementsWidget,
  total_jobs: JobsWidget,
  active_jobs: JobsWidget,
  pending_jobs: JobsWidget,
  available_jobs: JobsWidget,
  applications_received: ApplicationsWidget,
  my_applications: ApplicationsWidget,
  shortlisted: ApplicationsWidget,
  shortlisted_candidates: ShortlistedWidget,
  shortlisted_responses: ShortlistedWidget,
  responses_received: ShortlistedWidget,
  portfolio: PortfolioWidget,
  profile_status: ProfileCompletionWidget,
  verification_status: VerificationWidget,
  ai_usage: AiUsageWidget,
};

export default function MyDashboardPage(props: Props) {
  const [metrics, setMetrics] = createSignal<Metric[]>([]);
  const [loading, setLoading] = createSignal(true);
  const [err, setErr] = createSignal('');
  const [customizeMode, setCustomizeMode] = createSignal(false);
  const [widgetOrder, setWidgetOrder] = createSignal<string[]>([]);
  const [draggingIdx, setDraggingIdx] = createSignal<number | null>(null);
  const [visibleWidgets, setVisibleWidgets] = createSignal<Set<string>>(new Set());
  const [profileData, setProfileData] = createSignal<Record<string, any>>({});
  const [documents, setDocuments] = createSignal<any[]>([]);
  const [submitting, setSubmitting] = createSignal(false);

  const getRoleType = (): string => {
    if (PROFESSIONAL_ROLE_SET.has(props.roleKey)) return 'PROFESSIONAL';
    if (props.roleKey === 'COMPANY') return 'COMPANY';
    if (props.roleKey === 'CUSTOMER') return 'CUSTOMER';
    if (props.roleKey === 'JOB_SEEKER') return 'JOB_SEEKER';
    return 'PROFESSIONAL';
  };

  const widgetKeys = () => {
    if (props.widgetKeys && props.widgetKeys.length > 0) return props.widgetKeys;
    return DEFAULT_WIDGETS[getRoleType()] || [];
  };

  const initWidgetOrder = () => {
    const keys = widgetKeys();
    setWidgetOrder(keys);
    setVisibleWidgets(new Set(keys));
  };

  onMount(() => {
    setTimeout(() => loadData(), 0);
    initWidgetOrder();
    loadProfileData();
  });

  const loadProfileData = async () => {
    const prefix = ROLE_PREFIXES[props.roleKey];
    if (!prefix) return;
    try {
      const data = await fetchProfile(prefix);
      if (data) setProfileData(data);
    } catch { /* ignore */ }
    if (props.roleKey === 'JOB_SEEKER') {
      try {
        setDocuments(await fetchDocuments(prefix));
      } catch { /* ignore */ }
    }
  };

  const missingBasicLabels = createMemo(() => {
    const data = profileData();
    if (!data) return [];
    const p = data.profile || data;
    return getBasicFields(props.roleKey)
      .filter((field) => field.required)
      .filter((field) => !String(p[field.key] || '').trim())
      .map((field) => field.label);
  });

  const missingDocLabels = createMemo(() => {
    const docs = documents();
    return getDocFields(props.roleKey)
      .filter((doc) => doc.required)
      .filter((doc) => !docs.some((d: any) => d?.document_type === doc.key))
      .map((doc) => doc.label);
  });

  const missingPortfolioLabels = createMemo(() => {
    if (!roleHasPortfolio(props.roleKey)) return [];
    const data = profileData();
    if (!data) return getPortfolioSections(props.roleKey);
    const p = data.portfolio || data.custom_data || {};
    return getPortfolioSections(props.roleKey).filter((section) => {
      if (section === 'About') return !String(p?.about || p?.bio || '').trim();
      if (section === 'Services & pricing') return !String(p?.services || p?.pricing || '').trim();
      if (section === 'Experience / tools') return !String(p?.experience || p?.tools || '').trim();
      if (section === 'FAQs') return !String(p?.faqs || '').trim();
      if (section === 'Showcase items') return !String(p?.showcase || p?.portfolio_items || '').trim();
      return false;
    });
  });

  const handleSubmitForVerification = async () => {
    if (missingBasicLabels().length > 0 || missingDocLabels().length > 0) {
      return;
    }
    setSubmitting(true);
    try {
      const data = profileData();
      const p = data.profile || data;
      const docUrls: Record<string, string> = {};
      for (const d of documents()) {
        if (d?.document_type && d?.file_url) docUrls[d.document_type] = d.file_url;
      }
      // apiFetch() throws on a non-2xx response, so reaching this point means the submission succeeded.
      await apiFetch("/api/profile/submit-for-verification", {
        method: "POST",
        body: JSON.stringify({ roleKey: props.roleKey, profile_data: { ...p, ...docUrls } }),
      });
      props.onVerificationStatusChange?.("PENDING");
    } catch {
      // silently fail - the profile page handles submission errors
    } finally {
      setSubmitting(false);
    }
  };

  const moveWidget = (fromIdx: number, toIdx: number) => {
    if (fromIdx === toIdx) return;
    const order = [...widgetOrder()];
    const [moved] = order.splice(fromIdx, 1);
    order.splice(toIdx, 0, moved);
    setWidgetOrder(order);
  };

  const toggleWidget = (key: string) => {
    const visible = new Set(visibleWidgets());
    if (visible.has(key)) {
      visible.delete(key);
    } else {
      visible.add(key);
    }
    setVisibleWidgets(visible);
  };

  const hasWidgets = createMemo(() => widgetKeys().length > 0);

  const roleLabel = createMemo(() => String(props.roleKey || '').replace(/_/g, ' '));
  const verificationStatus = createMemo(() => String(props.verificationStatus || 'NOT_SUBMITTED').toUpperCase());
  const verificationTone = createMemo(() => {
    const status = verificationStatus();
    if (status === 'DOCUMENTS_REQUESTED' || status === 'REVISION_REQUESTED' || status === 'REJECTED') {
      return {
        badgeBorder: '#FFD8C2',
        badgeBackground: '#FFF1EB',
        badgeColor: '#FF5E13',
        title: 'Action required: complete verification updates',
        description: 'Admin requested changes. Update profile, portfolio, or documents and resubmit verification.',
      };
    }
    if (status === 'PENDING' || status === 'UNDER_REVIEW') {
      return {
        badgeBorder: '#F6D78F',
        badgeBackground: '#FFF3D6',
        badgeColor: '#B7791F',
        title: 'Verification in progress',
        description: 'Your submission is under review. Track status updates in Verification.',
      };
    }
    return {
      badgeBorder: '#F6D78F',
      badgeBackground: '#FFF3D6',
      badgeColor: '#B7791F',
      title: 'Complete verification to unlock full access',
      description: 'Fill profile and portfolio sections, upload required documents, then submit for verification.',
    };
  });
  const showVerificationPrompt = createMemo(() => !['APPROVED', 'COMPLETED'].includes(verificationStatus()));
  const showPortfolioCta = createMemo(() => PROFESSIONAL_ROLE_SET.has(props.roleKey) || props.roleKey === 'JOB_SEEKER');

  const getEffectiveRole = (): RoleKey => {
    if (typeof window === 'undefined') return props.roleKey;
    const urlParams = new URLSearchParams(window.location.search);
    const urlRole = urlParams.get('role');
    if (urlRole) {
      const normalized = normalizeRole(urlRole);
      if (normalized) return normalized;
    }
    return props.roleKey;
  };

  const loadData = async () => {
    const effectiveRole = getEffectiveRole();

    setLoading(true);
    setErr('');
    const next: Metric[] = [];

    const roleKey = effectiveRole;

    try {
      if (roleKey === 'COMPANY') {
        const [jobsRes, appsRes] = await Promise.all([
          fetch('/api/companies/jobs?page=1&limit=100', {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
            },
          }),
          fetch('/api/companies/jobs?page=1&limit=1', {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
            },
          }),
        ]);
        const jobsJson = await jobsRes.json().catch(() => ({}));
        const appsJson = await appsRes.json().catch(() => ({}));
        const jobs = Array.isArray(jobsJson?.data) ? jobsJson.data : [];
        next.push(
          { title: 'Total Jobs', value: String(jobs.length), hint: 'All job posts created' },
          { title: 'Active Jobs', value: String(jobs.filter((j: any) => String(j.status || '').toUpperCase() === 'OPEN').length), hint: 'Open to applications' },
          { title: 'Jobs In Verification', value: String(jobs.filter((j: any) => String(j.status || '').toUpperCase().includes('PENDING')).length), hint: 'Pending verification/approval' },
          { title: 'Latest Sync', value: appsRes.ok ? 'Live' : 'Partial', hint: 'Dashboard data status' },
        );
        if (!jobsRes.ok && !appsRes.ok) setErr('Some company metrics could not be loaded.');
      } else if (roleKey === 'CUSTOMER') {
        const res = await fetch('/api/customers/requirements?page=1&limit=100', {
          credentials: 'include',
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
          },
        });
        const json = await res.json().catch(() => ({}));
        const reqs = Array.isArray(json?.data) ? json.data : [];
        next.push(
          { title: 'My Requirements', value: String(reqs.length), hint: 'Total posted requirements' },
          { title: 'Open Requirements', value: String(reqs.filter((r: any) => String(r.status || '').toUpperCase() === 'OPEN').length), hint: 'Visible to professionals' },
          { title: 'In Verification', value: String(reqs.filter((r: any) => String(r.status || '').toUpperCase().includes('PENDING')).length), hint: 'Verification/approval stage' },
          { title: 'Drafts', value: String(reqs.filter((r: any) => String(r.status || '').toUpperCase() === 'DRAFT').length), hint: 'Not yet submitted' },
        );
        if (!res.ok) setErr('Some customer metrics could not be loaded.');
      } else if (roleKey === 'JOB_SEEKER') {
        const [jobsRes, appsRes] = await Promise.all([
          fetch('/api/jobseeker/jobs?page=1&limit=100', {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
            },
          }),
          fetch('/api/jobseeker/applications?page=1&limit=100', {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
            },
          }),
        ]);
        const jobsJson = await jobsRes.json().catch(() => ({}));
        const appsJson = await appsRes.json().catch(() => ({}));
        const jobs = Array.isArray(jobsJson?.data) ? jobsJson.data : [];
        const apps = Array.isArray(appsJson?.data) ? appsJson.data : [];
        next.push(
          { title: 'Available Jobs', value: String(jobs.length), hint: 'Open approved jobs' },
          { title: 'My Applications', value: String(apps.length), hint: 'Total applications submitted' },
          { title: 'Shortlisted', value: String(apps.filter((a: any) => String(a.status || '').toUpperCase() === 'SHORTLISTED').length), hint: 'Moved ahead in process' },
          { title: 'Profile Status', value: 'Active', hint: 'Verification state' },
        );
        if (!jobsRes.ok && !appsRes.ok) setErr('Some job seeker metrics could not be loaded.');
      } else if (PROFESSIONAL_ROLE_SET.has(roleKey)) {
        const prefix = roleKey.toLowerCase().split('_')[0];
        const prefixMap: Record<string, string> = {
          photographer: 'photographers',
          tutor: 'tutors',
          makeup: 'makeup-artists',
          developer: 'developers',
          video: 'video-editors',
          graphic: 'graphic-designers',
          social: 'social-media-managers',
          fitness: 'fitness-trainers',
          catering: 'catering-services',
        };
        const p = prefixMap[prefix] || prefix;
        const [marketRes, reqRes, walletRes] = await Promise.all([
          fetch(`/api/${p}/marketplace?page=1&limit=100`, {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
            },
          }),
          fetch(`/api/${p}/leads/requests/me?page=1&limit=100`, {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
            },
          }),
          fetch(`/api/${p}/wallet/me`, {
            credentials: 'include',
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${window.sessionStorage.getItem('nxtgauge_access_token') || ''}`,
            },
          }),
        ]);
        const marketJson = await marketRes.json().catch(() => ({}));
        const reqJson = await reqRes.json().catch(() => ({}));
        const walletJson = await walletRes.json().catch(() => ({}));
        const market = Array.isArray(marketJson?.data) ? marketJson.data : [];
        const requests = Array.isArray(reqJson?.data) ? reqJson.data : [];
        next.push(
          { title: 'Open Leads', value: String(market.length), hint: 'Available opportunities' },
          { title: 'My Requests', value: String(requests.length), hint: 'Lead requests sent' },
          { title: 'Accepted Requests', value: String(requests.filter((r: any) => ['APPROVED', 'CONTACT_UNLOCKED'].includes(String(r.status || '').toUpperCase())).length), hint: 'Approved responses' },
          { title: 'Tracecoins', value: String(walletJson?.balance ?? 0), hint: 'Current wallet balance' },
        );
        if (!marketRes.ok && !reqRes.ok && !walletRes.ok) setErr('Some professional metrics could not be loaded.');
      } else {
        next.push(
          { title: 'Welcome', value: 'Ready', hint: 'Dashboard initialized' },
          { title: 'Role', value: roleLabel(), hint: 'Current active role' },
        );
      }

      setMetrics(next);
    } catch {
      setErr('Network error while loading dashboard metrics.');
      setMetrics([
        { title: 'Status', value: 'Unavailable', hint: 'Please retry' },
      ]);
    } finally {
      setLoading(false);
    }
  };

  onMount(() => {
    setTimeout(() => loadData(), 0);
  });

  const renderWidget = (key: string, idx: number) => {
    const Component = WIDGET_COMPONENTS[key];
    if (!Component) return null;
    if (customizeMode() && !visibleWidgets().has(key)) return null;
    return (
      <div
        data-widget-key={key}
        draggable={true}
        onDragStart={(e) => {
          setDraggingIdx(idx);
          if (e.dataTransfer) {
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', String(idx));
          }
        }}
        onDragOver={(e) => {
          e.preventDefault();
          if (e.dataTransfer) e.dataTransfer.dropEffect = 'move';
        }}
        onDrop={(e) => {
          e.preventDefault();
          const fromIdx = draggingIdx();
          if (fromIdx !== null && fromIdx !== idx) {
            moveWidget(fromIdx, idx);
          }
          setDraggingIdx(null);
        }}
        onDragEnd={() => setDraggingIdx(null)}
        style={{
          cursor: 'grab',
          opacity: draggingIdx() === idx ? 0.5 : 1,
          transition: 'opacity 0.2s',
        }}
      >
        <Component roleKey={getEffectiveRole()} />
      </div>
    );
  };

  const effectiveRole = () => getEffectiveRole();

  return (
    <div style={{ display: 'grid', gap: '14px', 'max-width': '980px' }}>
      <div
        style={{
          background: NAVY,
          "border-radius": "12px",
          padding: "16px 20px",
          display: "flex",
          "align-items": "center",
          gap: "12px",
        }}
      >
        <span style={{ color: ORANGE }}>
          <LayoutDashboard size={24} />
        </span>
        <div>
          <p style={{ margin: "0", "font-size": "18px", "font-weight": "800", color: "#fff" }}>
            My Dashboard
          </p>
          <p style={{ margin: "4px 0 0", "font-size": "13px", color: "rgba(255,255,255,0.65)" }}>
            Overview of your {roleLabel()} metrics and activity.
          </p>
        </div>
      </div>

      <Show when={showVerificationPrompt()}>
        <VerificationSubmissionGuide
          statusLabel={verificationStatus().replace(/_/g, ' ')}
          statusColor="#B7791F"
          locked={verificationStatus() === 'UNDER_REVIEW' || verificationStatus() === 'PENDING'}
          approved={['APPROVED', 'COMPLETED'].includes(verificationStatus())}
          missingBasicLabels={missingBasicLabels()}
          missingDocLabels={missingDocLabels()}
          missingPortfolioLabels={missingPortfolioLabels()}
          canSubmit={missingBasicLabels().length === 0 && missingDocLabels().length === 0 && missingPortfolioLabels().length === 0}
          submitting={submitting()}
          onSubmit={handleSubmitForVerification}
          onGoBasic={() => props.onNavigate?.('My Profile')}
          onGoDocuments={() => props.onNavigate?.('My Profile')}
          onGoPortfolio={() => props.onNavigate?.('My Portfolio')}
        />
      </Show>

      <div style={CARD}>
        <div style={{ display: 'flex', 'justify-content': 'space-between', 'align-items': 'center' }}>
          <div>
            <p style={{ margin: '0', 'font-size': '18px', 'font-weight': '800', color: '#111827' }}>Dashboard Overview</p>
            <p style={{ margin: '4px 0 0', 'font-size': '13px', color: '#6B7280' }}>
              Manage widget layout, visibility, sizing, and dashboard presentation
            </p>
          </div>
          <button
            type="button"
            onClick={() => setCustomizeMode(!customizeMode())}
            style={{
              ...(customizeMode() ? BTN_PRIMARY : BTN_GHOST),
              'font-size': '12px',
              height: '32px',
              padding: '0 12px',
            }}
          >
            {customizeMode() ? 'Done Customizing' : 'Customize Widgets'}
          </button>
        </div>
      </div>

      <Show when={err()}>
        <div style={{ ...CARD, border: '1px solid #FECACA', background: '#FEF2F2', padding: '12px 14px', color: '#B91C1C', 'font-size': '13px', 'font-weight': '600' }}>
          {err()}
        </div>
      </Show>

      <Show when={customizeMode()}>
        <div style={{ ...CARD, border: '1px solid #E5E7EB', background: 'white', padding: '14px 16px' }}>
          <p style={{ margin: '0 0 4px', 'font-size': '11px', 'letter-spacing': '0.04em', 'text-transform': 'uppercase', color: '#6B7280' }}>Widget Customization</p>
          <p style={{ margin: '0 0 12px', 'font-size': '12px', color: '#374151' }}>Drag and drop cards below to reorder your dashboard widgets. Click eye icon to show/hide.</p>
          <div style={{ display: 'grid', 'grid-template-columns': 'repeat(auto-fill,minmax(140px,1fr))', gap: '10px' }}>
            <For each={widgetOrder()}>
              {(w, idx) => {
                const isVisible = () => visibleWidgets().has(w);
                const isDragging = () => draggingIdx() === idx();
                return (
                  <div
                    draggable={true}
                    onDragStart={(e) => {
                      setDraggingIdx(idx());
                      if (e.dataTransfer) {
                        e.dataTransfer.effectAllowed = 'move';
                        e.dataTransfer.setData('text/plain', String(idx()));
                      }
                    }}
                    onDragOver={(e) => {
                      e.preventDefault();
                      if (e.dataTransfer) e.dataTransfer.dropEffect = 'move';
                    }}
                    onDrop={(e) => {
                      e.preventDefault();
                      const fromIdx = draggingIdx();
                      if (fromIdx !== null) {
                        moveWidget(fromIdx, idx());
                      }
                      setDraggingIdx(null);
                    }}
                    onDragEnd={() => setDraggingIdx(null)}
                    style={{
                      border: '1px solid #E5E7EB',
                      background: isDragging() ? '#FFF3EE' : isVisible() ? 'white' : '#F9FAFB',
                      'border-radius': '12px',
                      padding: '10px',
                      'min-height': '80px',
                      'box-shadow': '0 1px 3px rgba(0,0,0,0.05)',
                      cursor: 'grab',
                      opacity: isDragging() ? 0.5 : isVisible() ? 1 : 0.4,
                    }}
                  >
                    <div style={{ display: 'flex', 'justify-content': 'space-between', 'align-items': 'flex-start' }}>
                      <p style={{ margin: 0, 'font-size': '10px', 'letter-spacing': '0.04em', 'text-transform': 'uppercase', color: '#6B7280' }}>
                        {w.replace(/_/g, ' ')}
                      </p>
                      <button
                        type="button"
                        onClick={(e) => { e.stopPropagation(); toggleWidget(w); }}
                        style={{
                          background: 'none',
                          border: 'none',
                          cursor: 'pointer',
                          padding: '2px',
                          'font-size': '12px',
                          'line-height': 1,
                          color: isVisible() ? '#0D0D2A' : '#9CA3AF',
                        }}
                        title={isVisible() ? 'Hide widget' : 'Show widget'}
                      >
                        {isVisible() ? '👁' : '👁‍🗨'}
                      </button>
                    </div>
                    <p style={{ margin: '8px 0 0', 'font-size': '20px', 'font-weight': '800', color: '#111827' }}>
                      {metrics().find(m => m.title.toLowerCase().replace(/ /g, '_').includes(w))?.value || '--'}
                    </p>
                  </div>
                );
              }}
            </For>
          </div>
        </div>
      </Show>

      <Show when={hasWidgets()}>
        <div style={{ display: 'grid', 'grid-template-columns': 'repeat(3,minmax(0,1fr))', gap: '14px' }}>
          <For each={widgetOrder().filter(w => !customizeMode() || visibleWidgets().has(w))}>
            {(key) => renderWidget(key, 0)}
          </For>
        </div>
      </Show>

      <Show when={!hasWidgets()}>
        <div style={CARD}>
          <div style={{ display: 'flex', 'justify-content': 'space-between', 'align-items': 'center', 'margin-bottom': '10px' }}>
            <p style={{ margin: '0', 'font-size': '16px', 'font-weight': '700', color: '#111827' }}>Quick Summary</p>
            <button type="button" onClick={loadData} style={BTN_GHOST}>Refresh</button>
          </div>

          <Show when={loading()}>
            <p style={{ margin: '0', color: '#9CA3AF', 'font-size': '13px' }}>Loading dashboard...</p>
          </Show>

          <Show when={!loading()}>
            <div style={{ display: 'grid', 'grid-template-columns': 'repeat(4,minmax(0,1fr))', gap: '10px' }}>
              <For each={metrics()}>
                {(m) => (
                  <div style={{ border: '1px solid #E5E7EB', 'border-radius': '12px', padding: '12px', background: '#FCFCFD' }}>
                    <p style={{ margin: '0', 'font-size': '11px', 'letter-spacing': '0.05em', 'text-transform': 'uppercase', color: '#6B7280' }}>{m.title}</p>
                    <p style={{ margin: '8px 0 0', 'font-size': '28px', 'line-height': '1', 'font-weight': '800', color: '#111827' }}>{m.value}</p>
                    <p style={{ margin: '6px 0 0', 'font-size': '12px', color: '#6B7280' }}>{m.hint}</p>
                  </div>
                )}
              </For>
            </div>
          </Show>
        </div>
      </Show>
    </div>
  );
}
