'use client';

/**
 * ContrastChecker - section 10 of /design-system.
 *
 * Computes WCAG 2.1 contrast ratios for every meaningful token pair at runtime.
 * Each row shows pass / fail for AA, AA Large, and AAA.
 */

import { useState } from 'react';
import { Pill } from '@/components/ui/primitives/Pill';
import { Stack } from '@/components/ui/layout/Stack';
import { Row } from '@/components/ui/layout/Row';
import { useT } from '@/lib/i18n/react';
import { ComponentEntry } from '../../components/ComponentEntry';
import { SectionShell } from '../../components/SectionShell';
import { checkContrast, readToken } from '../../lib/contrast';

interface Pair {
  label: string;
  fg: string;
  bg: string;
}

const PAIRS: Pair[] = [
  // Text on surface
  { label: 'text-primary on surface-base', fg: '--color-text-primary', bg: '--color-surface-base' },
  {
    label: 'text-secondary on surface-base',
    fg: '--color-text-secondary',
    bg: '--color-surface-base',
  },
  { label: 'text-muted on surface-base', fg: '--color-text-muted', bg: '--color-surface-base' },
  { label: 'text-link on surface-base', fg: '--color-text-link', bg: '--color-surface-base' },
  {
    label: 'text-primary on surface-raised',
    fg: '--color-text-primary',
    bg: '--color-surface-raised',
  },
  {
    label: 'text-primary on surface-inset',
    fg: '--color-text-primary',
    bg: '--color-surface-inset',
  },

  // Buttons - customer
  {
    label: 'white on brand-primary-600 (customer Button)',
    fg: '--color-brand-on-primary',
    bg: '--color-brand-primary-600',
  },
  {
    label: 'white on brand-primary-700 (hover)',
    fg: '--color-brand-on-primary',
    bg: '--color-brand-primary-700',
  },
  {
    label: 'white on brand-primary-800 (active)',
    fg: '--color-brand-on-primary',
    bg: '--color-brand-primary-800',
  },
  {
    label: 'brand-primary-700 on brand-primary-50 (ghost hover)',
    fg: '--color-brand-primary-700',
    bg: '--color-brand-primary-50',
  },

  // Buttons - vendor
  {
    label: 'white on mode-vendor-600',
    fg: '--color-brand-on-primary',
    bg: '--color-mode-vendor-600',
  },
  {
    label: 'white on mode-vendor-700',
    fg: '--color-brand-on-primary',
    bg: '--color-mode-vendor-700',
  },

  // Buttons - danger
  { label: 'white on danger-600', fg: '--color-brand-on-primary', bg: '--color-danger-600' },
  { label: 'white on danger-700', fg: '--color-brand-on-primary', bg: '--color-danger-700' },

  // Pills / banners - semantic
  { label: 'success-700 on success-50', fg: '--color-success-700', bg: '--color-success-50' },
  { label: 'warning-700 on warning-50', fg: '--color-warning-700', bg: '--color-warning-50' },
  { label: 'danger-700 on danger-50', fg: '--color-danger-700', bg: '--color-danger-50' },
  { label: 'info-700 on info-50', fg: '--color-info-700', bg: '--color-info-50' },
  { label: 'neutral-600 on neutral-100', fg: '--color-neutral-600', bg: '--color-neutral-100' },
  {
    label: 'brand-primary-700 on brand-primary-50',
    fg: '--color-brand-primary-700',
    bg: '--color-brand-primary-50',
  },

  // BusinessHeader
  {
    label: 'white on brand-primary-700 (BusinessHeader)',
    fg: '--color-brand-on-primary',
    bg: '--color-brand-primary-700',
  },

  // Timer stages
  {
    label: 'timer-neutral on surface-base',
    fg: '--color-timer-neutral',
    bg: '--color-surface-base',
  },
  { label: 'timer-warm on surface-base', fg: '--color-timer-warm', bg: '--color-surface-base' },
  { label: 'timer-urgent on surface-base', fg: '--color-timer-urgent', bg: '--color-surface-base' },
];

interface ResolvedPair extends Pair {
  fgHex: string;
  bgHex: string;
  ratio: number;
  passesAA: boolean;
  passesAALarge: boolean;
  passesAAA: boolean;
}

function ContrastTable() {
  const t = useT('design_system');

  // Lazy-initialize from CSS custom properties at mount. `readToken` calls
  // `getComputedStyle(document.documentElement)` which is safe here because
  // this is an Astro client:visible island - the React tree never runs under
  // SSR so the useState initializer always executes client-side.
  // Using a lazy initializer instead of useEffect+setState satisfies
  // react-hooks/set-state-in-effect.
  const [rows] = useState<ResolvedPair[]>(() => {
    if (typeof document === 'undefined') return [];
    return PAIRS.map<ResolvedPair>((p) => {
      const fgHex = readToken(p.fg);
      const bgHex = readToken(p.bg);
      const result = checkContrast(fgHex, bgHex);
      return { ...p, fgHex, bgHex, ...result };
    });
  });

  return (
    <div className="overflow-x-auto">
      <table className="w-full border-collapse text-sm">
        <thead>
          <tr className="border-border-default border-b text-start">
            <th className="text-text-secondary py-2 text-start font-medium">
              {t('contrast_pair')}
            </th>
            <th className="text-text-secondary py-2 text-start font-medium">
              {t('preview_label')}
            </th>
            <th className="text-text-secondary py-2 text-start font-medium">
              {t('contrast_ratio')}
            </th>
            <th className="text-text-secondary py-2 text-start font-medium">AA</th>
            <th className="text-text-secondary py-2 text-start font-medium">AA Large</th>
            <th className="text-text-secondary py-2 text-start font-medium">AAA</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r) => (
            <tr key={r.label} className="border-border-default border-b">
              <td className="text-text-primary py-2 pe-3">{r.label}</td>
              <td className="py-2 pe-3">
                <span
                  className="border-border-default inline-block rounded-sm border px-2 py-1"
                  style={{ background: `var(${r.bg})`, color: `var(${r.fg})` }}
                >
                  Aa גג
                </span>
              </td>
              <td className="text-text-primary py-2 pe-3 font-mono">{r.ratio.toFixed(2)}:1</td>
              <td className="py-2 pe-3">
                <Pill tone={r.passesAA ? 'success' : 'danger'} size="sm">
                  {r.passesAA ? '✓' : '✗'}
                </Pill>
              </td>
              <td className="py-2 pe-3">
                <Pill tone={r.passesAALarge ? 'success' : 'danger'} size="sm">
                  {r.passesAALarge ? '✓' : '✗'}
                </Pill>
              </td>
              <td className="py-2">
                <Pill tone={r.passesAAA ? 'success' : 'warning'} size="sm">
                  {r.passesAAA ? '✓' : '-'}
                </Pill>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

export function ContrastChecker() {
  const t = useT('design_system');
  return (
    <SectionShell id="contrast" title={t('sidebar_contrast')} description={t('section_intro')}>
      <ComponentEntry
        name="WCAG 2.1 contrast checker"
        id="contrast-checker"
        path="src/features/design-system/lib/contrast.ts"
        description="Runtime check of every meaningful token pair against AA / AA Large / AAA."
        tokens={['var(--color-*)']}
        a11yNotes={[
          'WCAG 2.1: AA = 4.5:1, AA Large = 3:1, AAA = 7:1',
          'Reads computed token values from :root',
          'Updates when prefs change (font scale / contrast)',
        ]}
        importSnippet={`import { checkContrast, readToken } from '@/features/design-system/lib/contrast';`}
      >
        <Stack gap="3">
          <Row gap="3" wrap>
            <Pill tone="success" size="sm">
              ✓ AA = 4.5:1
            </Pill>
            <Pill tone="success" size="sm">
              ✓ AA Large = 3:1
            </Pill>
            <Pill tone="success" size="sm">
              ✓ AAA = 7:1
            </Pill>
            <Pill tone="danger" size="sm">
              ✗ Fail
            </Pill>
          </Row>
          <ContrastTable />
        </Stack>
      </ComponentEntry>
    </SectionShell>
  );
}
