import type { Config } from 'tailwindcss'
import plugin from 'tailwindcss/plugin'
import typography from '@tailwindcss/typography'

/**
 * @zync/config Tailwind preset — foundation-design-system token registry.
 *
 * This is an intentionally RESTRICTED theme (top-level `theme`, not `theme.extend`):
 * replacing Tailwind's defaults is the enforcement mechanism. Only the 8px-grid
 * spacing, the single `rounded` radius, the single `shadow`, and the seven-token
 * typography scale generate utilities. Off-grid sizes and a radius ladder simply
 * do not exist. The four ESLint rules (no-hardcoded-colors / -spacing /
 * -radius-ladder / no-raw-html-in-pages) back-stop the same intent in source.
 */
/**
 * RTL base layer CSS injected into consuming apps.
 *
 * Sets the default --font-sans token and overrides it to Heebo when
 * `html[lang="he"]` is set (by LocaleProvider on locale change).
 *
 * Hebrew font stack: Heebo Variable (variable-weight) → Heebo → Arial fallback.
 * Latin stack: IBM Plex Sans (product body) — display uses Fraunces separately.
 *
 * Components MUST use CSS logical properties:
 *   - ms-* / me-* (margin-inline-start / -end) instead of ml-* / mr-*
 *   - ps-* / pe-* (padding-inline-start / -end) instead of pl-* / pr-*
 *   - text-start / text-end instead of text-left / text-right
 * This ensures RTL mirrors correctly without JS layout recalculation.
 *
 * The dir-transitioning class (added by LocaleProvider during locale swap)
 * gates a brief direction animation for users who have NOT opted out of motion.
 */
/**
 * RTL logical-utility plugin — rtl-hebrew-ui spec (wave 4).
 *
 * Registers the full logical-property utility set for margin, padding, border,
 * inset, text-align, and float on the 8px grid. Authors MUST use these instead
 * of physical ml-/mr-/pl-/pr-/left-/right-/text-left/text-right utilities so
 * that RTL mirrors automatically without any [dir="rtl"] layout duplication.
 *
 * Grid-legal spacing values (0.5 → 2px, 2 → 8px, 4 → 16px, 6 → 24px,
 * 8 → 32px, 12 → 48px, 16 → 64px, 24 → 96px) match the restricted spacing
 * theme below.  No off-grid values are introduced.
 */
export const logicalUtilitiesPlugin = plugin(({ addUtilities }) => {
  addUtilities({
    // ── margin-inline-start / -end ──────────────────────────────────────────
    '.ms-auto': { 'margin-inline-start': 'auto' },
    '.me-auto': { 'margin-inline-end': 'auto' },
    '.ms-0': { 'margin-inline-start': '0' },
    '.me-0': { 'margin-inline-end': '0' },
    '.ms-0\\.5': { 'margin-inline-start': '2px' },
    '.me-0\\.5': { 'margin-inline-end': '2px' },
    '.ms-2': { 'margin-inline-start': '8px' },
    '.me-2': { 'margin-inline-end': '8px' },
    '.ms-4': { 'margin-inline-start': '16px' },
    '.me-4': { 'margin-inline-end': '16px' },
    '.ms-6': { 'margin-inline-start': '24px' },
    '.me-6': { 'margin-inline-end': '24px' },
    '.ms-8': { 'margin-inline-start': '32px' },
    '.me-8': { 'margin-inline-end': '32px' },
    '.ms-12': { 'margin-inline-start': '48px' },
    '.me-12': { 'margin-inline-end': '48px' },
    '.ms-16': { 'margin-inline-start': '64px' },
    '.me-16': { 'margin-inline-end': '64px' },
    '.ms-24': { 'margin-inline-start': '96px' },
    '.me-24': { 'margin-inline-end': '96px' },
    // ── padding-inline-start / -end ─────────────────────────────────────────
    '.ps-0': { 'padding-inline-start': '0' },
    '.pe-0': { 'padding-inline-end': '0' },
    '.ps-0\\.5': { 'padding-inline-start': '2px' },
    '.pe-0\\.5': { 'padding-inline-end': '2px' },
    '.ps-2': { 'padding-inline-start': '8px' },
    '.pe-2': { 'padding-inline-end': '8px' },
    '.ps-4': { 'padding-inline-start': '16px' },
    '.pe-4': { 'padding-inline-end': '16px' },
    '.ps-6': { 'padding-inline-start': '24px' },
    '.pe-6': { 'padding-inline-end': '24px' },
    '.ps-8': { 'padding-inline-start': '32px' },
    '.pe-8': { 'padding-inline-end': '32px' },
    '.ps-12': { 'padding-inline-start': '48px' },
    '.pe-12': { 'padding-inline-end': '48px' },
    '.ps-16': { 'padding-inline-start': '64px' },
    '.pe-16': { 'padding-inline-end': '64px' },
    '.ps-24': { 'padding-inline-start': '96px' },
    '.pe-24': { 'padding-inline-end': '96px' },
    // ── border-inline-start / -end ──────────────────────────────────────────
    '.border-s': { 'border-inline-start-width': '1px' },
    '.border-e': { 'border-inline-end-width': '1px' },
    '.border-s-0': { 'border-inline-start-width': '0' },
    '.border-e-0': { 'border-inline-end-width': '0' },
    '.border-s-2': { 'border-inline-start-width': '2px' },
    '.border-e-2': { 'border-inline-end-width': '2px' },
    // ── inset-inline-start / -end ───────────────────────────────────────────
    '.inset-s-0': { 'inset-inline-start': '0' },
    '.inset-e-0': { 'inset-inline-end': '0' },
    '.inset-s-2': { 'inset-inline-start': '8px' },
    '.inset-e-2': { 'inset-inline-end': '8px' },
    '.inset-s-4': { 'inset-inline-start': '16px' },
    '.inset-e-4': { 'inset-inline-end': '16px' },
    '.inset-s-6': { 'inset-inline-start': '24px' },
    '.inset-e-6': { 'inset-inline-end': '24px' },
    '.inset-s-8': { 'inset-inline-start': '32px' },
    '.inset-e-8': { 'inset-inline-end': '32px' },
    // ── text-align logical ──────────────────────────────────────────────────
    '.text-start': { 'text-align': 'start' },
    '.text-end': { 'text-align': 'end' },
    // ── float logical ───────────────────────────────────────────────────────
    '.float-start': { float: 'inline-start' },
    '.float-end': { float: 'inline-end' },
  })
})

const zyncPreset = {
  plugins: [
    typography,
    // Inject RTL font-stack base CSS via a plugin (avoids needing a separate
    // CSS import; the preset is self-contained for consuming apps).
    plugin(({ addBase }) => {
      addBase({
        ':root': { '--font-sans': "'IBM Plex Sans', Arial, sans-serif" },
        'html[lang="he"]': {
          '--font-sans': "'Heebo Variable', 'Heebo', Arial, sans-serif",
        },
      })
    }),
    // RTL logical-property utilities (rtl-hebrew-ui spec, wave 4)
    logicalUtilitiesPlugin,
  ],
  theme: {
    colors: {
      bg: 'var(--bg)',
      surface: 'var(--surface)',
      ink: 'var(--ink)',
      'ink-soft': 'var(--ink-soft)',
      'ink-faint': 'var(--ink-faint)',
      'ink-on-accent': 'var(--ink-on-accent)',
      'on-accent': 'var(--ink-on-accent)',
      'accent-fg': 'var(--ink-on-accent)',
      'accent-foreground': 'var(--ink-on-accent)',
      'control-border': 'var(--control-border)',
      'focus-ring': 'var(--focus-ring)',
      line: 'var(--line)',
      'line-subtle': 'var(--line-subtle)',
      hover: 'var(--hover)',
      accent: 'var(--accent)',
      'accent-soft': 'var(--accent-soft)',
      'accent-mid': 'var(--accent-mid)',
      'accent-border': 'var(--accent-border)',
      danger: 'var(--danger)',
      success: 'var(--success)',
      warning: 'var(--warning)',
      info: 'var(--info)',
    },
    borderRadius: {
      DEFAULT: 'var(--radius)', // `rounded` — the only radius class
    },
    boxShadow: {
      DEFAULT: 'var(--shadow)', // `shadow` — the only shadow class
      none: 'none',
    },
    fontFamily: {
      display: ['var(--font-display)'],
      sans: ['var(--font-sans)'],
      hebrew: ['var(--font-hebrew)'],
      mono: ['var(--font-mono)'],
    },
    fontSize: {
      'display-1': ['56px', { lineHeight: '60px', letterSpacing: '-0.01em' }],
      'display-2': ['40px', { lineHeight: '46px', letterSpacing: '-0.005em' }],
      'title-1': ['28px', { lineHeight: '34px', letterSpacing: '0' }],
      'title-2': ['20px', { lineHeight: '28px', letterSpacing: '0' }],
      'body-1': ['16px', { lineHeight: '26px', letterSpacing: '0' }],
      'body-2': ['14px', { lineHeight: '22px', letterSpacing: '0.005em' }],
      meta: ['12px', { lineHeight: '18px', letterSpacing: '0.04em' }],
    },
    spacing: {
      '0.5': '2px', // tight-primitive exception (badge px, input border) — comment required at use site
      '2': '8px',
      '4': '16px',
      '6': '24px',
      '8': '32px',
      '12': '48px',
      '16': '64px',
      '24': '96px',
    },
  },
} satisfies Partial<Config>

export default zyncPreset
