import React, { useState, useEffect } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'

// ── Stack theme compatibility shim (matches old theme.ts keys, new stack values) ──
const colors = {
  primary: '#1a1a2e',
  primaryLight: '#2d2d44',
  primaryDark: '#16213e',
  accent: '#c9a84c',
  accentHover: '#b8973d',
  background: '#f4f5f7',
  surface: '#ffffff',
  surfaceHover: '#fafafa',
  text: '#1e293b',
  textSecondary: '#475569',
  textMuted: '#64748b',
  textLight: '#ffffff',
  border: '#e4e8ee',
  borderLight: '#eef1f5',
  borderFocus: '#1a1a2e',
  success: '#16a34a',
  successBg: '#dcfce7',
  warning: '#f59e0b',
  warningBg: '#fef3c7',
  error: '#dc2626',
  errorBg: '#fee2e2',
  info: '#0369a1',
  infoBg: '#e0f2fe',
}
const spacing = { xs: '0.25rem', sm: '0.5rem', md: '1rem', lg: '1.5rem', xl: '2rem', xxl: '3rem' }
const radius = { sm: '4px', md: '6px', lg: '8px', xl: '12px', full: '9999px' }
const shadows = {
  sm: '0 1px 2px rgba(16, 24, 40, 0.06)',
  md: '0 2px 8px rgba(16, 24, 40, 0.08)',
  lg: '0 4px 20px rgba(16, 24, 40, 0.12)',
  xl: '0 10px 40px rgba(16, 24, 40, 0.2)',
}
const typography = {
  fontFamily: "'Inter', system-ui, sans-serif",
  xs: '0.75rem', sm: '0.875rem', base: '1rem', lg: '1.125rem',
  xl: '1.25rem', xxl: '1.5rem', xxxl: '1.75rem', display: '2.5rem',
  normal: 400, medium: 500, semibold: 600, bold: 700,
}
const mergeStyles = (...styles: (React.CSSProperties | undefined)[]): React.CSSProperties =>
  Object.assign({}, ...styles.filter(Boolean))
const BUTTON_BASE: React.CSSProperties = {
  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
  gap: spacing.sm, padding: `${spacing.sm} ${spacing.md}`, borderRadius: radius.md,
  fontSize: typography.sm, fontWeight: typography.semibold, cursor: 'pointer',
  transition: 'background 0.2s ease, transform 0.1s ease', border: 'none', outline: 'none',
}
const buttonStyle = (
  variant: 'primary' | 'secondary' | 'outline' | 'ghost' = 'primary',
  size: 'small' | 'medium' | 'large' = 'medium'
): React.CSSProperties => {
  const variants: Record<string, React.CSSProperties> = {
    primary: { background: colors.accent, color: colors.textLight },
    secondary: { background: colors.primary, color: colors.textLight },
    outline: { background: 'transparent', color: colors.primary, border: `1px solid ${colors.border}` },
    ghost: { background: 'transparent', color: colors.text },
  }
  const sizes: Record<string, React.CSSProperties> = {
    small: { padding: `${spacing.xs} ${spacing.sm}`, fontSize: typography.xs },
    medium: {},
    large: { padding: `${spacing.md} ${spacing.lg}`, fontSize: typography.base },
  }
  return mergeStyles(BUTTON_BASE, variants[variant], sizes[size])
}
const badgeStyle = (status: 'success' | 'warning' | 'error' | 'info' = 'info'): React.CSSProperties => {
  const statuses: Record<string, React.CSSProperties> = {
    success: { background: colors.successBg, color: colors.success },
    warning: { background: colors.warningBg, color: colors.warning },
    error: { background: colors.errorBg, color: colors.error },
    info: { background: colors.infoBg, color: colors.info },
  }
  return mergeStyles({
    display: 'inline-flex', alignItems: 'center',
    padding: `${spacing.xs} ${spacing.sm}`, borderRadius: radius.full,
    fontSize: typography.xs, fontWeight: typography.medium,
  }, statuses[status])
}

type SettingsPage = 'newbook' | 'resos' | 'database' | 'special-dates' | 'budget' | 'tax-rates' | 'forecast-snapshots' | 'backup' | 'api-keys' | 'ai-insights'

const Settings: React.FC = () => {
  const [activePage, setActivePage] = useState<SettingsPage>('newbook')

  const menuItems: { id: SettingsPage; label: string }[] = [
    { id: 'newbook', label: 'Newbook' },
    { id: 'resos', label: 'Resos' },
    { id: 'special-dates', label: 'Special Dates' },
    { id: 'budget', label: 'Budget' },
    { id: 'tax-rates', label: 'Tax Rates' },
    { id: 'forecast-snapshots', label: 'Forecast Snapshots' },
    { id: 'ai-insights', label: 'AI Insights' },
    { id: 'api-keys', label: 'API Keys' },
    { id: 'backup', label: 'Backup & Restore' },
    { id: 'database', label: 'Database Browser' },
  ]

  return (
    <div style={styles.layout}>
      <div style={styles.sidebar}>
        <h3 style={styles.sidebarTitle}>Settings</h3>
        <nav style={styles.nav}>
          {menuItems.map((item) => (
            <button
              key={item.id}
              onClick={() => setActivePage(item.id)}
              style={{
                ...styles.navItem,
                ...(activePage === item.id ? styles.navItemActive : {}),
              }}
            >
              {item.label}
            </button>
          ))}
        </nav>
      </div>

      <main style={styles.content}>
        {activePage === 'newbook' && <NewbookPage />}
        {activePage === 'resos' && <ResosPage />}
        {activePage === 'special-dates' && <SpecialDatesPage />}
        {activePage === 'budget' && <BudgetPage />}
        {activePage === 'tax-rates' && <TaxRatesPage />}
        {activePage === 'forecast-snapshots' && <ForecastSnapshotsPage />}
        {activePage === 'backup' && <BackupPage />}
        {activePage === 'database' && <DatabasePage />}
        {activePage === 'ai-insights' && <AIInsightsPage />}
        {activePage === 'api-keys' && <ApiKeysPage />}
      </main>
    </div>
  )
}

// ============================================
// NEWBOOK SETTINGS PAGE
// ============================================

interface NewbookSettings {
  newbook_api_key: string | null
  newbook_api_key_set: boolean
  newbook_username: string | null
  newbook_password_set: boolean
  newbook_region: string | null
}

interface RoomCategory {
  id: number
  site_id: string
  site_name: string
  site_type: string | null
  room_count: number
  is_included: boolean
  display_order: number
}

// ============================================
// ROOM CATEGORIES SECTION
// ============================================

const RoomCategoriesSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [fetchStatus, setFetchStatus] = useState<'idle' | 'fetching' | 'success' | 'error'>('idle')
  const [fetchMessage, setFetchMessage] = useState('')

  // Fetch room categories
  const { data: roomCategories, isLoading } = useQuery<RoomCategory[]>({
    queryKey: ['room-categories'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/config/room-categories')
      if (!response.ok) return []
      return response.json()
    },
  })

  // Fetch from Newbook API
  const handleFetch = async () => {
    setFetchStatus('fetching')
    setFetchMessage('')
    try {
      const response = await fetch('/forecasting/api/config/room-categories/fetch', {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setFetchStatus('success')
        setFetchMessage(data.message || 'Room categories fetched successfully')
        queryClient.invalidateQueries({ queryKey: ['room-categories'] })
      } else {
        setFetchStatus('error')
        setFetchMessage(data.detail || 'Failed to fetch room categories')
      }
    } catch {
      setFetchStatus('error')
      setFetchMessage('Failed to fetch room categories')
    }
    setTimeout(() => {
      setFetchStatus('idle')
      setFetchMessage('')
    }, 5000)
  }

  // Update a single category (toggle included)
  const handleToggle = async (category: RoomCategory) => {
    try {
      await fetch('/forecasting/api/config/room-categories/bulk-update', {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          updates: [{ id: category.id, is_included: !category.is_included }]
        })
      })
      queryClient.invalidateQueries({ queryKey: ['room-categories'] })
    } catch (err) {
      console.error('Failed to update room category', err)
    }
  }

  // Update display order for a category
  const handleOrderChange = async (category: RoomCategory, newOrder: number) => {
    try {
      await fetch('/forecasting/api/config/room-categories/bulk-update', {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          updates: [{ id: category.id, display_order: newOrder }]
        })
      })
      queryClient.invalidateQueries({ queryKey: ['room-categories'] })
    } catch (err) {
      console.error('Failed to update display order', err)
    }
  }

  // Select/deselect all
  const handleSelectAll = async (include: boolean) => {
    if (!roomCategories?.length) return
    try {
      await fetch('/forecasting/api/config/room-categories/bulk-update', {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          updates: roomCategories.map(c => ({ id: c.id, is_included: include }))
        })
      })
      queryClient.invalidateQueries({ queryKey: ['room-categories'] })
    } catch (err) {
      console.error('Failed to update room categories', err)
    }
  }

  const includedRooms = roomCategories?.filter(c => c.is_included).reduce((sum, c) => sum + (c.room_count || 0), 0) || 0
  const includedTypes = roomCategories?.filter(c => c.is_included).length || 0

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Room Categories (for Occupancy)</h3>
      <p style={styles.hint}>
        Select which room types to include in occupancy and guest calculations. Exclude overflow rooms etc.
      </p>

      <div style={styles.buttonRow}>
        <button
          onClick={handleFetch}
          disabled={fetchStatus === 'fetching'}
          style={mergeStyles(
            buttonStyle('outline'),
            fetchStatus === 'success' ? { borderColor: colors.success, color: colors.success } : {},
            fetchStatus === 'error' ? { borderColor: colors.error, color: colors.error } : {}
          )}
        >
          {fetchStatus === 'fetching' ? 'Fetching...' : 'Fetch Room Categories'}
        </button>
        {roomCategories && roomCategories.length > 0 && (
          <>
            <button onClick={() => handleSelectAll(true)} style={buttonStyle('outline')}>
              Select All
            </button>
            <button onClick={() => handleSelectAll(false)} style={buttonStyle('outline')}>
              Deselect All
            </button>
          </>
        )}
      </div>

      {fetchMessage && (
        <div style={{
          ...styles.statusMessage,
          background: fetchStatus === 'success' ? colors.successBg : colors.errorBg,
          color: fetchStatus === 'success' ? colors.success : colors.error,
          marginTop: spacing.sm,
        }}>
          {fetchMessage}
        </div>
      )}

      {isLoading ? (
        <div style={styles.loading}>Loading room categories...</div>
      ) : roomCategories && roomCategories.length > 0 ? (
        <>
          <div style={styles.roomCategoryHeader}>
            <span style={styles.roomCategorySummary}>
              {includedRooms} rooms in {includedTypes} types selected
            </span>
          </div>
          <div style={styles.roomCategoryList}>
            {roomCategories.map((cat) => (
              <div key={cat.id} style={styles.roomCategoryItem}>
                <input
                  type="checkbox"
                  checked={cat.is_included}
                  onChange={() => handleToggle(cat)}
                  style={styles.checkbox}
                />
                <span style={styles.roomCategoryName}>{cat.site_name}</span>
                <span style={styles.roomCategoryCount}>{cat.room_count} rooms</span>
                <input
                  type="number"
                  value={cat.display_order}
                  onChange={(e) => handleOrderChange(cat, parseInt(e.target.value) || 0)}
                  style={styles.displayOrderInput}
                  min={0}
                  title="Display order (lower = first)"
                />
              </div>
            ))}
          </div>
        </>
      ) : (
        <div style={styles.emptyState}>
          No room categories loaded. Click "Fetch Room Categories" to load from Newbook.
        </div>
      )}
    </div>
  )
}

// ============================================
// GL REVENUE MAPPING SECTION
// ============================================

interface GLAccount {
  id: number
  gl_account_id: string
  gl_code: string | null
  gl_name: string | null
  gl_group_id: string | null
  gl_group_name: string | null
  department: 'accommodation' | 'dry' | 'wet' | null
  is_active: boolean
}

type Department = 'accommodation' | 'dry' | 'wet'

const DEPARTMENTS: { key: Department; label: string }[] = [
  { key: 'accommodation', label: 'Accommodation' },
  { key: 'dry', label: 'Dry (Food)' },
  { key: 'wet', label: 'Wet (Beverage)' },
]

const GLRevenueMappingSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [fetchStatus, setFetchStatus] = useState<'idle' | 'fetching' | 'success' | 'error'>('idle')
  const [fetchMessage, setFetchMessage] = useState('')
  const [modalDepartment, setModalDepartment] = useState<Department | null>(null)

  // Fetch GL accounts
  const { data: glAccounts, isLoading } = useQuery<GLAccount[]>({
    queryKey: ['gl-accounts'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/config/gl-accounts')
      if (!response.ok) return []
      return response.json()
    },
  })

  // Fetch from Newbook API
  const handleFetch = async () => {
    setFetchStatus('fetching')
    setFetchMessage('')
    try {
      const response = await fetch('/forecasting/api/config/gl-accounts/fetch', {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setFetchStatus('success')
        setFetchMessage(data.message || 'GL accounts fetched successfully')
        queryClient.invalidateQueries({ queryKey: ['gl-accounts'] })
      } else {
        setFetchStatus('error')
        setFetchMessage(data.detail || 'Failed to fetch GL accounts')
      }
    } catch {
      setFetchStatus('error')
      setFetchMessage('Failed to fetch GL accounts')
    }
    setTimeout(() => {
      setFetchStatus('idle')
      setFetchMessage('')
    }, 5000)
  }

  // Update department for accounts
  const handleUpdateDepartments = async (updates: { id: number; department: string | null }[]) => {
    try {
      await fetch('/forecasting/api/config/gl-accounts/department', {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ updates })
      })
      queryClient.invalidateQueries({ queryKey: ['gl-accounts'] })
    } catch (err) {
      console.error('Failed to update GL accounts', err)
    }
  }

  // Get accounts for a specific department
  const getAccountsForDepartment = (dept: Department) =>
    glAccounts?.filter(acc => acc.department === dept) || []

  // Remove account from department
  const handleRemoveFromDepartment = (accountId: number) => {
    handleUpdateDepartments([{ id: accountId, department: null }])
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>GL Revenue Mapping</h3>
      <p style={styles.hint}>
        Map GL accounts to revenue departments for aggregation. Fetch accounts first, then assign to each department.
      </p>

      <div style={styles.buttonRow}>
        <button
          onClick={handleFetch}
          disabled={fetchStatus === 'fetching'}
          style={mergeStyles(
            buttonStyle('outline'),
            fetchStatus === 'success' ? { borderColor: colors.success, color: colors.success } : {},
            fetchStatus === 'error' ? { borderColor: colors.error, color: colors.error } : {}
          )}
        >
          {fetchStatus === 'fetching' ? 'Fetching...' : 'Fetch GL Accounts'}
        </button>
        {glAccounts && glAccounts.length > 0 && (
          <span style={styles.glAccountCount}>{glAccounts.length} accounts loaded</span>
        )}
      </div>

      {fetchMessage && (
        <div style={{
          ...styles.statusMessage,
          background: fetchStatus === 'success' ? colors.successBg : colors.errorBg,
          color: fetchStatus === 'success' ? colors.success : colors.error,
          marginTop: spacing.sm,
        }}>
          {fetchMessage}
        </div>
      )}

      {isLoading ? (
        <div style={styles.loading}>Loading GL accounts...</div>
      ) : glAccounts && glAccounts.length > 0 ? (
        <div style={styles.departmentGrid}>
          {DEPARTMENTS.map(dept => {
            const deptAccounts = getAccountsForDepartment(dept.key)
            return (
              <div key={dept.key} style={styles.departmentColumn}>
                <div style={styles.departmentHeader}>
                  <span style={styles.departmentTitle}>{dept.label}</span>
                  <span style={styles.departmentCount}>{deptAccounts.length} accounts</span>
                </div>
                <div style={styles.departmentAccountList}>
                  {deptAccounts.length === 0 ? (
                    <div style={styles.departmentEmpty}>No accounts mapped</div>
                  ) : (
                    deptAccounts.map(acc => (
                      <div key={acc.id} style={styles.departmentAccountItem}>
                        <span style={styles.departmentAccountName}>
                          {acc.gl_name || acc.gl_code || acc.gl_account_id}
                        </span>
                        {acc.gl_code && <span style={styles.departmentAccountCode}>{acc.gl_code}</span>}
                        <button
                          onClick={() => handleRemoveFromDepartment(acc.id)}
                          style={styles.removeButton}
                          title="Remove from department"
                        >
                          ×
                        </button>
                      </div>
                    ))
                  )}
                </div>
                <button
                  onClick={() => setModalDepartment(dept.key)}
                  style={buttonStyle('outline')}
                >
                  Select Accounts
                </button>
              </div>
            )
          })}
        </div>
      ) : (
        <div style={styles.emptyState}>
          No GL accounts loaded. Click "Fetch GL Accounts" to load from Newbook.
        </div>
      )}

      {/* GL Account Selection Modal */}
      {modalDepartment && glAccounts && (
        <GLAccountModal
          department={modalDepartment}
          departmentLabel={DEPARTMENTS.find(d => d.key === modalDepartment)?.label || ''}
          glAccounts={glAccounts}
          onUpdate={handleUpdateDepartments}
          onClose={() => setModalDepartment(null)}
        />
      )}
    </div>
  )
}

// GL Account Selection Modal Component
interface GLAccountModalProps {
  department: Department
  departmentLabel: string
  glAccounts: GLAccount[]
  onUpdate: (updates: { id: number; department: string | null }[]) => void
  onClose: () => void
}

const GLAccountModal: React.FC<GLAccountModalProps> = ({
  department,
  departmentLabel,
  glAccounts,
  onUpdate,
  onClose
}) => {
  // Group accounts by gl_group_name
  const grouped: Record<string, GLAccount[]> = {}
  glAccounts.forEach(acc => {
    const groupName = acc.gl_group_name || 'Ungrouped'
    if (!grouped[groupName]) grouped[groupName] = []
    grouped[groupName].push(acc)
  })
  const sortedGroups = Object.keys(grouped).sort()

  // Check if account is selected for this department
  const isSelected = (acc: GLAccount) => acc.department === department

  // Toggle single account
  const handleToggle = (acc: GLAccount) => {
    if (isSelected(acc)) {
      onUpdate([{ id: acc.id, department: null }])
    } else {
      onUpdate([{ id: acc.id, department }])
    }
  }

  // Toggle entire group
  const handleGroupToggle = (groupAccounts: GLAccount[]) => {
    const allSelected = groupAccounts.every(acc => acc.department === department)
    if (allSelected) {
      // Deselect all in group
      onUpdate(groupAccounts.map(acc => ({ id: acc.id, department: null })))
    } else {
      // Select all in group
      onUpdate(groupAccounts.map(acc => ({ id: acc.id, department })))
    }
  }

  return (
    <div style={styles.modalOverlay} onClick={onClose}>
      <div style={styles.modalContent} onClick={e => e.stopPropagation()}>
        <div style={styles.modalHeader}>
          <h3 style={styles.modalTitle}>Select GL Accounts for {departmentLabel}</h3>
          <button onClick={onClose} style={styles.modalCloseButton}>×</button>
        </div>
        <div style={styles.modalBody}>
          {sortedGroups.map(groupName => {
            const groupAccounts = grouped[groupName]
            const selectedCount = groupAccounts.filter(acc => acc.department === department).length
            const allSelected = selectedCount === groupAccounts.length
            const someSelected = selectedCount > 0 && !allSelected

            return (
              <div key={groupName} style={styles.glGroup}>
                <label style={styles.glGroupHeader}>
                  <input
                    type="checkbox"
                    checked={allSelected}
                    ref={el => { if (el) el.indeterminate = someSelected }}
                    onChange={() => handleGroupToggle(groupAccounts)}
                    style={styles.checkbox}
                  />
                  <span style={styles.glGroupName}>{groupName}</span>
                  <span style={styles.glGroupCount}>({selectedCount}/{groupAccounts.length})</span>
                </label>
                <div style={styles.glGroupItems}>
                  {groupAccounts.map(acc => (
                    <label key={acc.id} style={styles.glItem}>
                      <input
                        type="checkbox"
                        checked={isSelected(acc)}
                        onChange={() => handleToggle(acc)}
                        style={styles.checkbox}
                      />
                      <span style={styles.glItemName}>{acc.gl_name || 'Unnamed'}</span>
                      {acc.gl_code && <span style={styles.glItemCode}>({acc.gl_code})</span>}
                      {acc.department && acc.department !== department && (
                        <span style={styles.glItemMapped}>
                          → {DEPARTMENTS.find(d => d.key === acc.department)?.label}
                        </span>
                      )}
                    </label>
                  ))}
                </div>
              </div>
            )
          })}
        </div>
        <div style={styles.modalFooter}>
          <button onClick={onClose} style={buttonStyle('primary')}>Done</button>
        </div>
      </div>
    </div>
  )
}

// ============================================
// BOOKINGS DATA SYNC SECTION
// ============================================

interface SyncStatus {
  last_successful_sync: {
    completed_at: string | null
    records_fetched: number | null
    records_created: number | null
    triggered_by: string | null
  } | null
  last_sync: {
    started_at: string | null
    completed_at: string | null
    status: string | null
    records_fetched: number | null
    error_message: string | null
    triggered_by: string | null
  } | null
  auto_sync: {
    enabled: boolean
    type: string
    time: string
  }
  total_records: number
}

interface SyncLog {
  id: number
  started_at: string
  completed_at: string | null
  status: string
  records_fetched: number | null
  records_created: number | null
  date_from: string | null
  date_to: string | null
  error_message: string | null
  triggered_by: string | null
}

const BookingsDataSyncSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [syncStatus, setSyncStatus] = useState<'idle' | 'syncing' | 'success' | 'error'>('idle')
  const [syncMessage, setSyncMessage] = useState('')
  const [fromDate, setFromDate] = useState('')
  const [toDate, setToDate] = useState('')
  const [autoEnabled, setAutoEnabled] = useState(false)
  const [autoType, setAutoType] = useState('incremental')
  const [syncTime, setSyncTime] = useState('05:00')

  // Fetch sync status
  const { data: status, isLoading: statusLoading, refetch: refetchStatus } = useQuery<SyncStatus>({
    queryKey: ['bookings-sync-status'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/bookings-data/status')
      if (!response.ok) throw new Error('Failed to fetch status')
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Fetch sync logs
  const { data: logs, isLoading: logsLoading } = useQuery<SyncLog[]>({
    queryKey: ['bookings-sync-logs'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/bookings-data/logs?limit=5')
      if (!response.ok) return []
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Update local state when status loads
  React.useEffect(() => {
    if (status?.auto_sync) {
      setAutoEnabled(status.auto_sync.enabled)
      setAutoType(status.auto_sync.type)
      setSyncTime(status.auto_sync.time || '05:00')
    }
    // Check if sync is currently running
    if (status?.last_sync?.status === 'running') {
      setSyncStatus('syncing')
    } else if (syncStatus === 'syncing' && status?.last_sync?.status !== 'running') {
      // Sync completed
      setSyncStatus(status?.last_sync?.status === 'success' ? 'success' : 'error')
      setSyncMessage(status?.last_sync?.status === 'success'
        ? `Synced ${status?.last_sync?.records_fetched || 0} bookings`
        : status?.last_sync?.error_message || 'Sync failed')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
      queryClient.invalidateQueries({ queryKey: ['bookings-sync-status'] })
      queryClient.invalidateQueries({ queryKey: ['bookings-sync-logs'] })
    }
  }, [status, syncStatus, queryClient])

  // Trigger sync
  const handleSync = async (mode: 'incremental' | 'staying_range') => {
    setSyncStatus('syncing')
    setSyncMessage('')
    try {
      let url = `/forecasting/api/sync/bookings-data/sync?sync_mode=${mode}`
      if (mode === 'staying_range' && fromDate && toDate) {
        url += `&from_date=${fromDate}&to_date=${toDate}`
      }
      const response = await fetch(url, {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setSyncMessage(data.message || 'Sync started...')
        // Keep polling via refetchInterval
      } else {
        setSyncStatus('error')
        setSyncMessage(data.detail || 'Failed to start sync')
        setTimeout(() => {
          setSyncStatus('idle')
          setSyncMessage('')
        }, 5000)
      }
    } catch {
      setSyncStatus('error')
      setSyncMessage('Failed to start sync')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
    }
  }

  // Update auto sync config
  const handleAutoConfigSave = async () => {
    try {
      const response = await fetch('/forecasting/api/sync/bookings-data/config', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          enabled: autoEnabled,
          sync_type: autoType,
          sync_time: syncTime
        })
      })
      if (response.ok) {
        refetchStatus()
      }
    } catch (err) {
      console.error('Failed to update config', err)
    }
  }

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return '-'
    return new Date(dateStr).toLocaleString()
  }

  const formatTrigger = (trigger: string | null) => {
    if (!trigger) return '-'
    if (trigger.startsWith('user:')) return trigger.replace('user:', '')
    if (trigger === 'scheduler') return 'Auto'
    return trigger
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Bookings Data Sync</h3>
      <p style={styles.hint}>
        Sync booking data from Newbook. Use date range for specific periods, or incremental for recent changes.
      </p>

      {statusLoading ? (
        <div style={styles.loading}>Loading sync status...</div>
      ) : (
        <>
          {/* Status summary */}
          <div style={styles.syncStatusRow}>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Total Records</span>
              <span style={styles.syncStatusValue}>{status?.total_records?.toLocaleString() || 0}</span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Last Sync</span>
              <span style={styles.syncStatusValue}>
                {status?.last_successful_sync?.completed_at
                  ? formatDate(status.last_successful_sync.completed_at)
                  : 'Never'}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Auto Sync</span>
              <span style={status?.auto_sync?.enabled ? styles.statusOk : styles.statusPending}>
                {status?.auto_sync?.enabled ? 'Enabled' : 'Disabled'}
              </span>
            </div>
          </div>

          {/* Sync controls */}
          <div style={styles.syncControlsSection}>
            {/* Incremental sync */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Incremental Update</h4>
              <p style={styles.syncControlHint}>
                Fetches bookings modified since last sync (or last 7 days if no history).
              </p>
              <button
                onClick={() => handleSync('incremental')}
                disabled={syncStatus === 'syncing'}
                style={mergeStyles(
                  buttonStyle('primary'),
                  syncStatus === 'syncing' ? { opacity: 0.7 } : {}
                )}
              >
                {syncStatus === 'syncing' ? 'Syncing...' : 'Run Incremental Sync'}
              </button>
            </div>

            {/* Date range sync */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Date Range Sync</h4>
              <p style={styles.syncControlHint}>
                Fetches bookings staying during the specified date range.
              </p>
              <div style={styles.syncDateRow}>
                <input
                  type="date"
                  value={fromDate}
                  onChange={(e) => setFromDate(e.target.value)}
                  style={styles.dateInput}
                />
                <span style={styles.dateTo}>to</span>
                <input
                  type="date"
                  value={toDate}
                  onChange={(e) => setToDate(e.target.value)}
                  style={styles.dateInput}
                />
              </div>
              <button
                onClick={() => handleSync('staying_range')}
                disabled={syncStatus === 'syncing' || !fromDate || !toDate}
                style={mergeStyles(
                  buttonStyle('outline'),
                  (syncStatus === 'syncing' || !fromDate || !toDate) ? { opacity: 0.7 } : {}
                )}
              >
                Sync Date Range
              </button>
            </div>

            {/* Auto sync config */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Automatic Sync</h4>
              <p style={styles.syncControlHint}>
                Enable scheduled daily sync at configured time.
              </p>
              <label style={styles.syncCheckboxLabel}>
                <input
                  type="checkbox"
                  checked={autoEnabled}
                  onChange={(e) => setAutoEnabled(e.target.checked)}
                  style={styles.checkbox}
                />
                Enable auto sync
              </label>
              <div style={styles.syncAutoRow}>
                <select
                  value={autoType}
                  onChange={(e) => setAutoType(e.target.value)}
                  style={styles.syncSelect}
                  disabled={!autoEnabled}
                >
                  <option value="incremental">Incremental</option>
                  <option value="full">Full (not recommended)</option>
                </select>
                <span style={styles.syncTimeLabel}>at</span>
                <input
                  type="time"
                  value={syncTime}
                  onChange={(e) => setSyncTime(e.target.value)}
                  style={styles.syncTimeInput}
                  disabled={!autoEnabled}
                />
              </div>
              <button
                onClick={handleAutoConfigSave}
                style={buttonStyle('outline')}
              >
                Save Settings
              </button>
            </div>
          </div>

          {/* Sync message */}
          {syncMessage && (
            <div style={{
              ...styles.statusMessage,
              background: syncStatus === 'success' ? colors.successBg :
                         syncStatus === 'error' ? colors.errorBg : colors.background,
              color: syncStatus === 'success' ? colors.success :
                     syncStatus === 'error' ? colors.error : colors.text,
              marginTop: spacing.md,
            }}>
              {syncMessage}
            </div>
          )}

          {/* Recent sync logs */}
          <div style={styles.syncLogsSection}>
            <h4 style={styles.syncLogsTitle}>Recent Syncs</h4>
            {logsLoading ? (
              <div style={styles.loading}>Loading logs...</div>
            ) : logs && logs.length > 0 ? (
              <div style={styles.syncLogsList}>
                {logs.map((log) => (
                  <div key={log.id} style={styles.syncLogItem}>
                    <div style={styles.syncLogMain}>
                      <span style={{
                        ...styles.syncLogStatus,
                        color: log.status === 'success' ? colors.success :
                               log.status === 'running' ? colors.accent :
                               colors.error
                      }}>
                        {log.status === 'running' ? '●' : log.status === 'success' ? '✓' : '✗'}
                      </span>
                      <span style={styles.syncLogDate}>{formatDate(log.started_at)}</span>
                      <span style={styles.syncLogRecords}>
                        {log.records_fetched !== null ? `${log.records_fetched} fetched` : ''}
                        {log.records_created !== null ? `, ${log.records_created} new` : ''}
                      </span>
                    </div>
                    <div style={styles.syncLogMeta}>
                      <span style={styles.syncLogTrigger}>{formatTrigger(log.triggered_by)}</span>
                      {log.date_from && log.date_to && (
                        <span style={styles.syncLogRange}>{log.date_from} → {log.date_to}</span>
                      )}
                    </div>
                    {log.error_message && (
                      <div style={styles.syncLogError}>{log.error_message}</div>
                    )}
                  </div>
                ))}
              </div>
            ) : (
              <div style={styles.emptyState}>No sync history yet.</div>
            )}
          </div>
        </>
      )}
    </div>
  )
}

// ============================================
// OCCUPANCY DATA SYNC SECTION
// ============================================

interface OccupancySyncStatus {
  last_successful_sync: {
    completed_at: string | null
    records_fetched: number | null
    records_created: number | null
    date_from: string | null
    date_to: string | null
    triggered_by: string | null
  } | null
  last_sync: {
    started_at: string | null
    completed_at: string | null
    status: string | null
    records_fetched: number | null
    date_from: string | null
    date_to: string | null
    error_message: string | null
    triggered_by: string | null
  } | null
  auto_sync: {
    enabled: boolean
    time: string
  }
  total_records: number
  data_range: {
    from: string | null
    to: string | null
  }
}

const OccupancyDataSyncSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [syncStatus, setSyncStatus] = useState<'idle' | 'syncing' | 'success' | 'error'>('idle')
  const [syncMessage, setSyncMessage] = useState('')
  const [fromDate, setFromDate] = useState('')
  const [toDate, setToDate] = useState('')
  const [autoEnabled, setAutoEnabled] = useState(false)
  const [syncTime, setSyncTime] = useState('05:00')

  // Fetch sync status
  const { data: status, isLoading: statusLoading, refetch: refetchStatus } = useQuery<OccupancySyncStatus>({
    queryKey: ['occupancy-sync-status'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/occupancy-data/status')
      if (!response.ok) throw new Error('Failed to fetch status')
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Fetch sync logs
  const { data: logs, isLoading: logsLoading } = useQuery<SyncLog[]>({
    queryKey: ['occupancy-sync-logs'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/occupancy-data/logs?limit=5')
      if (!response.ok) return []
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Update local state when status loads
  React.useEffect(() => {
    if (status?.auto_sync) {
      setAutoEnabled(status.auto_sync.enabled)
      setSyncTime(status.auto_sync.time || '05:00')
    }
    // Check if sync is currently running
    if (status?.last_sync?.status === 'running') {
      setSyncStatus('syncing')
    } else if (syncStatus === 'syncing' && status?.last_sync?.status !== 'running') {
      // Sync completed
      setSyncStatus(status?.last_sync?.status === 'success' ? 'success' : 'error')
      setSyncMessage(status?.last_sync?.status === 'success'
        ? `Synced ${status?.last_sync?.records_fetched || 0} records`
        : status?.last_sync?.error_message || 'Sync failed')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
      queryClient.invalidateQueries({ queryKey: ['occupancy-sync-status'] })
      queryClient.invalidateQueries({ queryKey: ['occupancy-sync-logs'] })
    }
  }, [status, syncStatus, queryClient])

  // Trigger sync
  const handleSync = async () => {
    setSyncStatus('syncing')
    setSyncMessage('')
    try {
      let url = '/forecasting/api/sync/occupancy-data/sync'
      if (fromDate && toDate) {
        url += `?from_date=${fromDate}&to_date=${toDate}`
      }
      const response = await fetch(url, {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setSyncMessage(data.message || 'Sync started...')
        // Keep polling via refetchInterval
      } else {
        setSyncStatus('error')
        setSyncMessage(data.detail || 'Failed to start sync')
        setTimeout(() => {
          setSyncStatus('idle')
          setSyncMessage('')
        }, 5000)
      }
    } catch {
      setSyncStatus('error')
      setSyncMessage('Failed to start sync')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
    }
  }

  // Update auto sync config
  const handleAutoConfigSave = async () => {
    try {
      const response = await fetch('/forecasting/api/sync/occupancy-data/config', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          enabled: autoEnabled,
          sync_time: syncTime
        })
      })
      if (response.ok) {
        refetchStatus()
      }
    } catch (err) {
      console.error('Failed to update config', err)
    }
  }

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return '-'
    return new Date(dateStr).toLocaleString()
  }

  const formatTrigger = (trigger: string | null) => {
    if (!trigger) return '-'
    if (trigger.startsWith('user:')) return trigger.replace('user:', '')
    if (trigger === 'scheduler') return 'Auto'
    return trigger
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Occupancy Report Data Sync</h3>
      <p style={styles.hint}>
        Sync occupancy report data from Newbook. This includes available rooms, occupied, maintenance, and revenue per category.
      </p>

      {statusLoading ? (
        <div style={styles.loading}>Loading sync status...</div>
      ) : (
        <>
          {/* Status summary */}
          <div style={styles.syncStatusRow}>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Total Records</span>
              <span style={styles.syncStatusValue}>{status?.total_records?.toLocaleString() || 0}</span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Data Range</span>
              <span style={styles.syncStatusValue}>
                {status?.data_range?.from && status?.data_range?.to
                  ? `${status.data_range.from} → ${status.data_range.to}`
                  : 'No data'}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Last Sync</span>
              <span style={styles.syncStatusValue}>
                {status?.last_successful_sync?.completed_at
                  ? formatDate(status.last_successful_sync.completed_at)
                  : 'Never'}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Auto Sync</span>
              <span style={status?.auto_sync?.enabled ? styles.statusOk : styles.statusPending}>
                {status?.auto_sync?.enabled ? 'Enabled' : 'Disabled'}
              </span>
            </div>
          </div>

          {/* Sync controls */}
          <div style={styles.syncControlsSection}>
            {/* Date range sync */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Manual Sync</h4>
              <p style={styles.syncControlHint}>
                Sync occupancy data for date range. Default: -7 to +365 days if not specified.
              </p>
              <div style={styles.syncDateRow}>
                <input
                  type="date"
                  value={fromDate}
                  onChange={(e) => setFromDate(e.target.value)}
                  style={styles.dateInput}
                  placeholder="From"
                />
                <span style={styles.dateTo}>to</span>
                <input
                  type="date"
                  value={toDate}
                  onChange={(e) => setToDate(e.target.value)}
                  style={styles.dateInput}
                  placeholder="To"
                />
              </div>
              <button
                onClick={handleSync}
                disabled={syncStatus === 'syncing'}
                style={mergeStyles(
                  buttonStyle('primary'),
                  syncStatus === 'syncing' ? { opacity: 0.7 } : {}
                )}
              >
                {syncStatus === 'syncing' ? 'Syncing...' : 'Run Sync'}
              </button>
            </div>

            {/* Auto sync config */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Automatic Sync</h4>
              <p style={styles.syncControlHint}>
                Enable scheduled daily sync at configured time (-7 to +365 days).
              </p>
              <label style={styles.syncCheckboxLabel}>
                <input
                  type="checkbox"
                  checked={autoEnabled}
                  onChange={(e) => setAutoEnabled(e.target.checked)}
                  style={styles.checkbox}
                />
                Enable auto sync
              </label>
              <div style={styles.syncAutoRow}>
                <span style={styles.syncTimeLabel}>Sync at</span>
                <input
                  type="time"
                  value={syncTime}
                  onChange={(e) => setSyncTime(e.target.value)}
                  style={styles.syncTimeInput}
                  disabled={!autoEnabled}
                />
              </div>
              <button
                onClick={handleAutoConfigSave}
                style={buttonStyle('outline')}
              >
                Save Settings
              </button>
            </div>
          </div>

          {/* Sync message */}
          {syncMessage && (
            <div style={{
              ...styles.statusMessage,
              background: syncStatus === 'success' ? colors.successBg :
                         syncStatus === 'error' ? colors.errorBg : colors.background,
              color: syncStatus === 'success' ? colors.success :
                     syncStatus === 'error' ? colors.error : colors.text,
              marginTop: spacing.md,
            }}>
              {syncMessage}
            </div>
          )}

          {/* Recent sync logs */}
          <div style={styles.syncLogsSection}>
            <h4 style={styles.syncLogsTitle}>Recent Syncs</h4>
            {logsLoading ? (
              <div style={styles.loading}>Loading logs...</div>
            ) : logs && logs.length > 0 ? (
              <div style={styles.syncLogsList}>
                {logs.map((log) => (
                  <div key={log.id} style={styles.syncLogItem}>
                    <div style={styles.syncLogMain}>
                      <span style={{
                        ...styles.syncLogStatus,
                        color: log.status === 'success' ? colors.success :
                               log.status === 'running' ? colors.accent :
                               colors.error
                      }}>
                        {log.status === 'running' ? '●' : log.status === 'success' ? '✓' : '✗'}
                      </span>
                      <span style={styles.syncLogDate}>{formatDate(log.started_at)}</span>
                      <span style={styles.syncLogRecords}>
                        {log.records_fetched !== null ? `${log.records_fetched} records` : ''}
                      </span>
                    </div>
                    <div style={styles.syncLogMeta}>
                      <span style={styles.syncLogTrigger}>{formatTrigger(log.triggered_by)}</span>
                      {log.date_from && log.date_to && (
                        <span style={styles.syncLogRange}>{log.date_from} → {log.date_to}</span>
                      )}
                    </div>
                    {log.error_message && (
                      <div style={styles.syncLogError}>{log.error_message}</div>
                    )}
                  </div>
                ))}
              </div>
            ) : (
              <div style={styles.emptyState}>No sync history yet.</div>
            )}
          </div>
        </>
      )}
    </div>
  )
}

// ============================================
// EARNED REVENUE DATA SYNC SECTION
// ============================================

interface EarnedRevenueSyncStatus {
  last_successful_sync: {
    completed_at: string | null
    records_fetched: number | null
    records_created: number | null
    date_from: string | null
    date_to: string | null
    triggered_by: string | null
  } | null
  last_sync: {
    started_at: string | null
    completed_at: string | null
    status: string | null
    records_fetched: number | null
    date_from: string | null
    date_to: string | null
    error_message: string | null
    triggered_by: string | null
  } | null
  auto_sync: {
    enabled: boolean
    time: string
  }
  total_records: number
  data_range: {
    from: string | null
    to: string | null
  }
}

const EarnedRevenueDataSyncSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [syncStatus, setSyncStatus] = useState<'idle' | 'syncing' | 'success' | 'error'>('idle')
  const [syncMessage, setSyncMessage] = useState('')
  const [fromDate, setFromDate] = useState('')
  const [toDate, setToDate] = useState('')
  const [autoEnabled, setAutoEnabled] = useState(false)
  const [syncTime, setSyncTime] = useState('05:10')

  // Fetch sync status
  const { data: status, isLoading: statusLoading, refetch: refetchStatus } = useQuery<EarnedRevenueSyncStatus>({
    queryKey: ['earned-revenue-sync-status'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/earned-revenue-data/status')
      if (!response.ok) throw new Error('Failed to fetch status')
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Fetch sync logs
  const { data: logs, isLoading: logsLoading } = useQuery<SyncLog[]>({
    queryKey: ['earned-revenue-sync-logs'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/earned-revenue-data/logs?limit=5')
      if (!response.ok) return []
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Update local state when status loads
  React.useEffect(() => {
    if (status?.auto_sync) {
      setAutoEnabled(status.auto_sync.enabled)
      setSyncTime(status.auto_sync.time || '05:10')
    }
    // Check if sync is currently running
    if (status?.last_sync?.status === 'running') {
      setSyncStatus('syncing')
    } else if (syncStatus === 'syncing' && status?.last_sync?.status !== 'running') {
      // Sync completed
      setSyncStatus(status?.last_sync?.status === 'success' ? 'success' : 'error')
      setSyncMessage(status?.last_sync?.status === 'success'
        ? `Synced ${status?.last_sync?.records_fetched || 0} records`
        : status?.last_sync?.error_message || 'Sync failed')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
      queryClient.invalidateQueries({ queryKey: ['earned-revenue-sync-status'] })
      queryClient.invalidateQueries({ queryKey: ['earned-revenue-sync-logs'] })
    }
  }, [status, syncStatus, queryClient])

  // Trigger sync
  const handleSync = async () => {
    setSyncStatus('syncing')
    setSyncMessage('')
    try {
      let url = '/forecasting/api/sync/earned-revenue-data/sync'
      if (fromDate && toDate) {
        url += `?from_date=${fromDate}&to_date=${toDate}`
      }
      const response = await fetch(url, {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setSyncMessage(data.message || 'Sync started...')
        // Keep polling via refetchInterval
      } else {
        setSyncStatus('error')
        setSyncMessage(data.detail || 'Failed to start sync')
        setTimeout(() => {
          setSyncStatus('idle')
          setSyncMessage('')
        }, 5000)
      }
    } catch {
      setSyncStatus('error')
      setSyncMessage('Failed to start sync')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
    }
  }

  // Update auto sync config
  const handleAutoConfigSave = async () => {
    try {
      const response = await fetch('/forecasting/api/sync/earned-revenue-data/config', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          enabled: autoEnabled,
          sync_time: syncTime
        })
      })
      if (response.ok) {
        refetchStatus()
      }
    } catch (err) {
      console.error('Failed to update config', err)
    }
  }

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return '-'
    return new Date(dateStr).toLocaleString()
  }

  const formatTrigger = (trigger: string | null) => {
    if (!trigger) return '-'
    if (trigger.startsWith('user:')) return trigger.replace('user:', '')
    if (trigger === 'scheduler') return 'Auto'
    return trigger
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Earned Revenue Data Sync</h3>
      <p style={styles.hint}>
        Sync earned revenue from Newbook (official GL figures). Used for revenue accuracy tracking.
      </p>

      {statusLoading ? (
        <div style={styles.loading}>Loading sync status...</div>
      ) : (
        <>
          {/* Status summary */}
          <div style={styles.syncStatusRow}>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Total Records</span>
              <span style={styles.syncStatusValue}>{status?.total_records?.toLocaleString() || 0}</span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Data Range</span>
              <span style={styles.syncStatusValue}>
                {status?.data_range?.from && status?.data_range?.to
                  ? `${status.data_range.from} → ${status.data_range.to}`
                  : 'No data'}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Last Sync</span>
              <span style={styles.syncStatusValue}>
                {status?.last_successful_sync?.completed_at
                  ? formatDate(status.last_successful_sync.completed_at)
                  : 'Never'}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Auto Sync</span>
              <span style={status?.auto_sync?.enabled ? styles.statusOk : styles.statusPending}>
                {status?.auto_sync?.enabled ? 'Enabled' : 'Disabled'}
              </span>
            </div>
          </div>

          {/* Sync controls */}
          <div style={styles.syncControlsSection}>
            {/* Date range sync */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Manual Sync</h4>
              <p style={styles.syncControlHint}>
                Sync earned revenue for date range. Default: last 7 days if not specified.
              </p>
              <div style={styles.syncDateRow}>
                <input
                  type="date"
                  value={fromDate}
                  onChange={(e) => setFromDate(e.target.value)}
                  style={styles.dateInput}
                  placeholder="From"
                />
                <span style={styles.dateTo}>to</span>
                <input
                  type="date"
                  value={toDate}
                  onChange={(e) => setToDate(e.target.value)}
                  style={styles.dateInput}
                  placeholder="To"
                />
              </div>
              <button
                onClick={handleSync}
                disabled={syncStatus === 'syncing'}
                style={mergeStyles(
                  buttonStyle('primary'),
                  syncStatus === 'syncing' ? { opacity: 0.7 } : {}
                )}
              >
                {syncStatus === 'syncing' ? 'Syncing...' : 'Run Sync'}
              </button>
            </div>

            {/* Auto sync config */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Automatic Sync</h4>
              <p style={styles.syncControlHint}>
                Enable scheduled daily sync at configured time (last 7 days).
              </p>
              <label style={styles.syncCheckboxLabel}>
                <input
                  type="checkbox"
                  checked={autoEnabled}
                  onChange={(e) => setAutoEnabled(e.target.checked)}
                  style={styles.checkbox}
                />
                Enable auto sync
              </label>
              <div style={styles.syncAutoRow}>
                <span style={styles.syncTimeLabel}>Sync at</span>
                <input
                  type="time"
                  value={syncTime}
                  onChange={(e) => setSyncTime(e.target.value)}
                  style={styles.syncTimeInput}
                  disabled={!autoEnabled}
                />
              </div>
              <button
                onClick={handleAutoConfigSave}
                style={buttonStyle('outline')}
              >
                Save Settings
              </button>
            </div>
          </div>

          {/* Sync message */}
          {syncMessage && (
            <div style={{
              ...styles.statusMessage,
              background: syncStatus === 'success' ? colors.successBg :
                         syncStatus === 'error' ? colors.errorBg : colors.background,
              color: syncStatus === 'success' ? colors.success :
                     syncStatus === 'error' ? colors.error : colors.text,
              marginTop: spacing.md,
            }}>
              {syncMessage}
            </div>
          )}

          {/* Recent sync logs */}
          <div style={styles.syncLogsSection}>
            <h4 style={styles.syncLogsTitle}>Recent Syncs</h4>
            {logsLoading ? (
              <div style={styles.loading}>Loading logs...</div>
            ) : logs && logs.length > 0 ? (
              <div style={styles.syncLogsList}>
                {logs.map((log) => (
                  <div key={log.id} style={styles.syncLogItem}>
                    <div style={styles.syncLogMain}>
                      <span style={{
                        ...styles.syncLogStatus,
                        color: log.status === 'success' ? colors.success :
                               log.status === 'running' ? colors.accent :
                               colors.error
                      }}>
                        {log.status === 'running' ? '●' : log.status === 'success' ? '✓' : '✗'}
                      </span>
                      <span style={styles.syncLogDate}>{formatDate(log.started_at)}</span>
                      <span style={styles.syncLogRecords}>
                        {log.records_fetched !== null ? `${log.records_fetched} records` : ''}
                      </span>
                    </div>
                    <div style={styles.syncLogMeta}>
                      <span style={styles.syncLogTrigger}>{formatTrigger(log.triggered_by)}</span>
                      {log.date_from && log.date_to && (
                        <span style={styles.syncLogRange}>{log.date_from} → {log.date_to}</span>
                      )}
                    </div>
                    {log.error_message && (
                      <div style={styles.syncLogError}>{log.error_message}</div>
                    )}
                  </div>
                ))}
              </div>
            ) : (
              <div style={styles.emptyState}>No sync history yet.</div>
            )}
          </div>
        </>
      )}
    </div>
  )
}

// ============================================
// CURRENT RATES DATA SYNC SECTION (Pickup-V2)
// ============================================

interface CurrentRatesSyncStatus {
  last_successful_sync: {
    completed_at: string | null
    records_fetched: number | null
    records_created: number | null
    triggered_by: string | null
  } | null
  last_sync: {
    started_at: string | null
    completed_at: string | null
    status: string | null
    records_fetched: number | null
    error_message: string | null
    triggered_by: string | null
  } | null
  auto_sync: {
    enabled: boolean
    time: string
  }
  total_records: number
  data_range: {
    from: string | null
    to: string | null
  }
  category_counts: Record<string, number>
}

const CurrentRatesDataSyncSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [syncStatus, setSyncStatus] = useState<'idle' | 'syncing' | 'success' | 'error'>('idle')
  const [syncMessage, setSyncMessage] = useState('')
  const [autoEnabled, setAutoEnabled] = useState(false)
  const [syncTime, setSyncTime] = useState('05:20')
  const [horizonDays, setHorizonDays] = useState<string>('')  // Empty = full 720-day run

  // Fetch sync status
  const { data: status, isLoading: statusLoading, refetch: refetchStatus } = useQuery<CurrentRatesSyncStatus>({
    queryKey: ['current-rates-sync-status'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/current-rates/status')
      if (!response.ok) throw new Error('Failed to fetch status')
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Fetch sync logs
  const { data: logs, isLoading: logsLoading } = useQuery<SyncLog[]>({
    queryKey: ['current-rates-sync-logs'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/current-rates/logs?limit=5')
      if (!response.ok) return []
      return response.json()
    },
    refetchInterval: syncStatus === 'syncing' ? 3000 : false,
  })

  // Update local state when status loads
  React.useEffect(() => {
    if (status?.auto_sync) {
      setAutoEnabled(status.auto_sync.enabled)
      setSyncTime(status.auto_sync.time || '05:20')
    }
    // Check if sync is currently running
    if (status?.last_sync?.status === 'running') {
      setSyncStatus('syncing')
    } else if (syncStatus === 'syncing' && status?.last_sync?.status !== 'running') {
      // Sync completed
      setSyncStatus(status?.last_sync?.status === 'success' ? 'success' : 'error')
      setSyncMessage(status?.last_sync?.status === 'success'
        ? `Synced ${status?.last_sync?.records_fetched || 0} rates`
        : status?.last_sync?.error_message || 'Sync failed')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
      queryClient.invalidateQueries({ queryKey: ['current-rates-sync-status'] })
      queryClient.invalidateQueries({ queryKey: ['current-rates-sync-logs'] })
    }
  }, [status, syncStatus, queryClient])

  // Trigger sync
  const handleSync = async () => {
    setSyncStatus('syncing')
    setSyncMessage('')
    try {
      const body: Record<string, number> = {}
      if (horizonDays && parseInt(horizonDays) > 0) {
        body.horizon_days = parseInt(horizonDays)
      }
      const response = await fetch('/forecasting/api/sync/current-rates/sync', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(body)
      })
      const data = await response.json()
      if (response.ok) {
        setSyncMessage(data.message || 'Sync started...')
      } else {
        setSyncStatus('error')
        setSyncMessage(data.detail || 'Failed to start sync')
        setTimeout(() => {
          setSyncStatus('idle')
          setSyncMessage('')
        }, 5000)
      }
    } catch {
      setSyncStatus('error')
      setSyncMessage('Failed to start sync')
      setTimeout(() => {
        setSyncStatus('idle')
        setSyncMessage('')
      }, 5000)
    }
  }

  // Update auto sync config
  const handleAutoConfigSave = async () => {
    try {
      const response = await fetch('/forecasting/api/sync/current-rates/config', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          enabled: autoEnabled,
          sync_time: syncTime
        })
      })
      if (response.ok) {
        refetchStatus()
      }
    } catch (err) {
      console.error('Failed to update config', err)
    }
  }

  // Cancel running sync
  const handleCancelSync = async () => {
    try {
      const response = await fetch('/forecasting/api/sync/current-rates/cancel', {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setSyncStatus('idle')
        setSyncMessage(data.message || 'Sync cancelled')
        queryClient.invalidateQueries({ queryKey: ['current-rates-sync-status'] })
        queryClient.invalidateQueries({ queryKey: ['current-rates-sync-logs'] })
        setTimeout(() => {
          setSyncMessage('')
        }, 3000)
      }
    } catch {
      console.error('Failed to cancel sync')
    }
  }

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return '-'
    return new Date(dateStr).toLocaleString()
  }

  const formatTrigger = (trigger: string | null) => {
    if (!trigger) return '-'
    if (trigger.startsWith('user:')) return trigger.replace('user:', '')
    if (trigger === 'scheduler') return 'Auto'
    return trigger
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Current Rates Sync (Pickup-V2)</h3>
      <p style={styles.hint}>
        Fetches current rack rates from Newbook for revenue forecast upper bounds.
        Used by Pickup-V2 model for confidence shading.
      </p>

      {statusLoading ? (
        <div style={styles.loading}>Loading sync status...</div>
      ) : (
        <>
          {/* Status summary */}
          <div style={styles.syncStatusRow}>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Total Rates</span>
              <span style={styles.syncStatusValue}>{status?.total_records?.toLocaleString() || 0}</span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Date Range</span>
              <span style={styles.syncStatusValue}>
                {status?.data_range?.from && status?.data_range?.to
                  ? `${status.data_range.from} → ${status.data_range.to}`
                  : 'No data'}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Last Sync</span>
              <span style={styles.syncStatusValue}>
                {status?.last_successful_sync?.completed_at
                  ? formatDate(status.last_successful_sync.completed_at)
                  : 'Never'}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Auto Sync</span>
              <span style={status?.auto_sync?.enabled ? styles.statusOk : styles.statusPending}>
                {status?.auto_sync?.enabled ? 'Enabled' : 'Disabled'}
              </span>
            </div>
          </div>

          {/* Category breakdown if data exists */}
          {status?.category_counts && Object.keys(status.category_counts).length > 0 && (
            <div style={{ ...styles.hint, marginTop: spacing.sm }}>
              Categories: {Object.entries(status.category_counts).map(([cat, count]) =>
                `${cat}: ${count} days`
              ).join(', ')}
            </div>
          )}

          {/* Sync controls */}
          <div style={styles.syncControlsSection}>
            {/* Manual sync */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Manual Sync</h4>
              <p style={styles.syncControlHint}>
                Fetch rates for all categories. Leave days blank for full 720-day run.
              </p>
              <div style={{ display: 'flex', alignItems: 'center', gap: spacing.sm, marginBottom: spacing.sm }}>
                <span style={{ fontSize: '0.85rem', color: colors.textSecondary }}>Days ahead:</span>
                <input
                  type="number"
                  value={horizonDays}
                  onChange={(e) => setHorizonDays(e.target.value)}
                  placeholder="720"
                  min="1"
                  max="720"
                  disabled={syncStatus === 'syncing'}
                  style={{
                    width: '80px',
                    padding: `${spacing.xs} ${spacing.sm}`,
                    border: `1px solid ${colors.border}`,
                    borderRadius: '4px',
                    fontSize: '0.85rem',
                    backgroundColor: colors.surface,
                    color: colors.text,
                  }}
                />
              </div>
              <div style={{ display: 'flex', gap: spacing.sm }}>
                <button
                  onClick={handleSync}
                  disabled={syncStatus === 'syncing'}
                  style={mergeStyles(
                    buttonStyle('primary'),
                    syncStatus === 'syncing' ? { opacity: 0.7 } : {}
                  )}
                >
                  {syncStatus === 'syncing' ? 'Syncing...' : 'Fetch Current Rates'}
                </button>
                {syncStatus === 'syncing' && (
                  <button
                    onClick={handleCancelSync}
                    style={mergeStyles(buttonStyle('outline'), { borderColor: colors.error, color: colors.error })}
                  >
                    Cancel
                  </button>
                )}
              </div>
            </div>

            {/* Auto sync config */}
            <div style={styles.syncControlBox}>
              <h4 style={styles.syncControlTitle}>Automatic Sync</h4>
              <p style={styles.syncControlHint}>
                Enable scheduled daily sync. Fetches rates for next 365 days.
              </p>
              <label style={styles.syncCheckboxLabel}>
                <input
                  type="checkbox"
                  checked={autoEnabled}
                  onChange={(e) => setAutoEnabled(e.target.checked)}
                  style={styles.checkbox}
                />
                Enable auto sync
              </label>
              <div style={styles.syncAutoRow}>
                <span style={styles.syncTimeLabel}>Sync at</span>
                <input
                  type="time"
                  value={syncTime}
                  onChange={(e) => setSyncTime(e.target.value)}
                  style={styles.syncTimeInput}
                  disabled={!autoEnabled}
                />
              </div>
              <button
                onClick={handleAutoConfigSave}
                style={buttonStyle('outline')}
              >
                Save Settings
              </button>
            </div>
          </div>

          {/* Sync message */}
          {syncMessage && (
            <div style={{
              ...styles.statusMessage,
              background: syncStatus === 'success' ? colors.successBg :
                         syncStatus === 'error' ? colors.errorBg : colors.background,
              color: syncStatus === 'success' ? colors.success :
                     syncStatus === 'error' ? colors.error : colors.text,
              marginTop: spacing.md,
            }}>
              {syncMessage}
            </div>
          )}

          {/* Recent sync logs */}
          <div style={styles.syncLogsSection}>
            <h4 style={styles.syncLogsTitle}>Recent Syncs</h4>
            {logsLoading ? (
              <div style={styles.loading}>Loading logs...</div>
            ) : logs && logs.length > 0 ? (
              <div style={styles.syncLogsList}>
                {logs.map((log) => (
                  <div key={log.id} style={styles.syncLogItem}>
                    <div style={styles.syncLogMain}>
                      <span style={{
                        ...styles.syncLogStatus,
                        color: log.status === 'success' ? colors.success :
                               log.status === 'running' ? colors.accent :
                               colors.error
                      }}>
                        {log.status === 'running' ? '●' : log.status === 'success' ? '✓' : '✗'}
                      </span>
                      <span style={styles.syncLogDate}>{formatDate(log.started_at)}</span>
                      <span style={styles.syncLogRecords}>
                        {log.records_fetched !== null ? `${log.records_fetched} rates` : ''}
                      </span>
                    </div>
                    <div style={styles.syncLogMeta}>
                      <span style={styles.syncLogTrigger}>{formatTrigger(log.triggered_by)}</span>
                      {log.status === 'running' && (
                        <button
                          onClick={handleCancelSync}
                          style={mergeStyles(buttonStyle('outline', 'small'), { marginLeft: spacing.sm, borderColor: colors.error, color: colors.error })}
                        >
                          Cancel
                        </button>
                      )}
                    </div>
                    {log.error_message && (
                      <div style={styles.syncLogError}>{log.error_message}</div>
                    )}
                  </div>
                ))}
              </div>
            ) : (
              <div style={styles.emptyState}>No sync history yet.</div>
            )}
          </div>
        </>
      )}
    </div>
  )
}

const NewbookPage: React.FC = () => {
  const [testStatus, setTestStatus] = useState<'idle' | 'testing' | 'success' | 'error'>('idle')
  const [testMessage, setTestMessage] = useState('')

  const handleTestConnection = async () => {
    setTestStatus('testing')
    setTestMessage('')
    try {
      const response = await fetch('/forecasting/api/config/settings/newbook/test', {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setTestStatus('success')
        setTestMessage(data.message || 'Connection successful!')
      } else {
        setTestStatus('error')
        setTestMessage(data.detail || 'Connection failed')
      }
    } catch {
      setTestStatus('error')
      setTestMessage('Connection failed')
    }
    setTimeout(() => {
      setTestStatus('idle')
      setTestMessage('')
    }, 5000)
  }

  return (
    <div style={styles.section}>
      <h2 style={styles.sectionTitle}>Newbook Settings</h2>
      <p style={styles.hint}>Newbook data synchronization for this app.</p>

      <div style={styles.infoBox}>
        Newbook API credentials are managed centrally in the stack <strong>Settings</strong> app
        (Integrations → NewBook) and shared by all apps. Use the button below to verify this
        app can reach Newbook with those credentials.
      </div>

      <div style={styles.buttonRow}>
        <button
          onClick={handleTestConnection}
          disabled={testStatus === 'testing'}
          style={buttonStyle('outline')}
        >
          {testStatus === 'testing' ? 'Testing...' : 'Test Connection'}
        </button>
      </div>

      {testMessage && (
        <div style={{
          ...styles.statusMessage,
          background: testStatus === 'success' ? colors.successBg : colors.errorBg,
          color: testStatus === 'success' ? colors.success : colors.error,
          marginTop: spacing.md,
        }}>
          {testMessage}
        </div>
      )}

      <div style={styles.divider} />

      <RoomCategoriesSection />

      <div style={styles.divider} />

      <GLRevenueMappingSection />

      <div style={styles.divider} />

      <BookingsDataSyncSection />

      <div style={styles.divider} />

      <OccupancyDataSyncSection />

      <div style={styles.divider} />

      <EarnedRevenueDataSyncSection />

      <div style={styles.divider} />

      <CurrentRatesDataSyncSection />
    </div>
  )
}

// ============================================
// RESOS SETTINGS PAGE
// ============================================

interface ResosSettings {
  resos_api_key: string | null
  resos_api_key_set: boolean
}

interface ResosCustomField {
  id: string
  name: string
  type: string
  values?: string[]
}

interface CustomFieldMapping {
  custom_field_id: string
  mapping_type: string
}

interface ResosOpeningHour {
  id: string
  name: string
  start_time: string
  end_time: string
}

interface OpeningHourMapping {
  opening_hour_id: string
  period_type: string
  display_name?: string
}

interface ManualBreakfastPeriod {
  day_of_week: number
  start_time: string
  end_time: string
  is_active: boolean
}

const ResosPage: React.FC = () => {
  return (
    <div style={styles.section}>
      <h2 style={styles.sectionTitle}>Resos Settings</h2>
      <p style={styles.hint}>Configure your Resos API connection and sync settings for restaurant reservation management.</p>

      <ResosAPIConfigSection />

      <div style={styles.divider} />

      <ResosCustomFieldMappingSection />

      <div style={styles.divider} />

      <ResosOpeningHoursMappingSection />

      <div style={styles.divider} />

      <ResosManualBreakfastSection />

      <div style={styles.divider} />

      <ResosAverageSpendSection />

      <div style={styles.divider} />

      <ResosSyncConfigSection />
    </div>
  )
}

// ============================================
// RESOS API CONFIGURATION SECTION
// ============================================

const ResosAPIConfigSection: React.FC = () => {
  const [apiKey, setApiKey] = useState('')
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle')
  const [testStatus, setTestStatus] = useState<'idle' | 'testing' | 'success' | 'error'>('idle')
  const [testMessage, setTestMessage] = useState('')

  const { data: settings, isLoading } = useQuery({
    queryKey: ['resos-settings'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/config/settings/resos')
      if (!response.ok) throw new Error('Failed to fetch settings')
      return response.json() as Promise<ResosSettings>
    },
    staleTime: 30000,
  })

  const handleSave = async () => {
    setSaveStatus('saving')
    try {
      const response = await fetch('/forecasting/api/config/settings/resos', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          resos_api_key: apiKey || undefined,
        })
      })
      if (!response.ok) throw new Error('Failed to save')
      setSaveStatus('success')
      setApiKey('')
      setTimeout(() => setSaveStatus('idle'), 3000)
    } catch {
      setSaveStatus('error')
      setTimeout(() => setSaveStatus('idle'), 3000)
    }
  }

  const handleTestConnection = async () => {
    setTestStatus('testing')
    setTestMessage('')
    try {
      const response = await fetch('/forecasting/api/config/settings/resos/test', {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setTestStatus('success')
        setTestMessage(data.message || 'Connection successful!')
      } else {
        setTestStatus('error')
        setTestMessage(data.detail || 'Connection failed')
      }
    } catch {
      setTestStatus('error')
      setTestMessage('Connection failed')
    }
    setTimeout(() => {
      setTestStatus('idle')
      setTestMessage('')
    }, 5000)
  }

  if (isLoading) {
    return <div style={styles.loading}>Loading settings...</div>
  }

  return (
    <div style={styles.apiConfigRow}>
      <div style={styles.apiConfigLeft}>
        <h3 style={styles.subsectionTitle}>API Configuration</h3>

        <div style={styles.form}>
          <label style={styles.label}>
            <span>API Key</span>
            <div style={styles.inputWithStatus}>
              <input
                type="password"
                value={apiKey}
                onChange={(e) => setApiKey(e.target.value)}
                placeholder={settings?.resos_api_key_set ? '••••••••' : 'Enter API key'}
                style={styles.input}
              />
              {settings?.resos_api_key_set && (
                <span style={styles.keyStatus}>Key configured</span>
              )}
            </div>
          </label>

          <div style={styles.buttonRow}>
            <button
              onClick={handleSave}
              disabled={saveStatus === 'saving'}
              style={mergeStyles(
                buttonStyle('primary'),
                saveStatus === 'success' ? { background: colors.success } : {},
                saveStatus === 'error' ? { background: colors.error } : {}
              )}
            >
              {saveStatus === 'saving' ? 'Saving...' :
               saveStatus === 'success' ? 'Saved!' :
               saveStatus === 'error' ? 'Error' : 'Save Settings'}
            </button>
            <button
              onClick={handleTestConnection}
              disabled={testStatus === 'testing'}
              style={buttonStyle('outline')}
            >
              {testStatus === 'testing' ? 'Testing...' : 'Test Connection'}
            </button>
          </div>

          {testMessage && (
            <div style={{
              ...styles.statusMessage,
              background: testStatus === 'success' ? colors.successBg : colors.errorBg,
              color: testStatus === 'success' ? colors.success : colors.error,
            }}>
              {testMessage}
            </div>
          )}
        </div>
      </div>

      <div style={styles.apiConfigRight}>
        <h3 style={styles.subsectionTitle}>Connection Status</h3>
        <div style={styles.statusGridVertical}>
          <div style={styles.statusItem}>
            <span style={styles.statusLabel}>API Key</span>
            <span style={settings?.resos_api_key_set ? styles.statusOk : styles.statusPending}>
              {settings?.resos_api_key_set ? 'Configured' : 'Not set'}
            </span>
          </div>
        </div>
      </div>
    </div>
  )
}

// ============================================
// RESOS CUSTOM FIELD MAPPING SECTION
// ============================================

const ResosCustomFieldMappingSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [fetchStatus, setFetchStatus] = useState<'idle' | 'fetching' | 'success' | 'error'>('idle')
  const [fetchMessage, setFetchMessage] = useState('')
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle')
  const [saveMessage, setSaveMessage] = useState('')
  const [customFieldMapping, setCustomFieldMapping] = useState<Record<string, string>>({})

  const { data: customFields, isLoading } = useQuery<ResosCustomField[]>({
    queryKey: ['resos-custom-fields-list'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/resos/custom-fields')
      if (!response.ok) return []
      return response.json()
    },
  })

  const { data: existingMappings } = useQuery<CustomFieldMapping[]>({
    queryKey: ['resos-custom-field-mapping'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/resos/custom-field-mapping')
      if (!response.ok) return []
      return response.json()
    },
  })

  React.useEffect(() => {
    if (existingMappings) {
      // Convert from array to simple mapping object: {mapping_type: field_id}
      const mappingObj: Record<string, string> = {}
      existingMappings.forEach(m => {
        mappingObj[m.mapping_type] = m.custom_field_id
      })
      setCustomFieldMapping(mappingObj)
    }
  }, [existingMappings])

  const handleFetch = async () => {
    setFetchStatus('fetching')
    setFetchMessage('')
    try {
      const response = await fetch('/forecasting/api/resos/custom-fields', {
        method: 'GET',
      })
      const data = await response.json()
      if (response.ok) {
        setFetchStatus('success')
        setFetchMessage('Custom fields fetched successfully')
        queryClient.invalidateQueries({ queryKey: ['resos-custom-fields-list'] })
      } else {
        setFetchStatus('error')
        setFetchMessage(data.detail || 'Failed to fetch custom fields')
      }
    } catch {
      setFetchStatus('error')
      setFetchMessage('Failed to fetch custom fields')
    }
    setTimeout(() => {
      setFetchStatus('idle')
      setFetchMessage('')
    }, 5000)
  }

  const handleSaveMappings = async () => {
    setSaveStatus('saving')
    setSaveMessage('')
    try {
      // Convert mapping object back to array format for API
      const mappingsArray = Object.entries(customFieldMapping)
        .filter(([_, fieldId]) => fieldId) // Only include non-empty mappings
        .map(([mappingType, fieldId]) => ({
          custom_field_id: fieldId,
          mapping_type: mappingType
        }))

      const response = await fetch('/forecasting/api/resos/custom-field-mapping', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ mappings: mappingsArray })
      })
      if (response.ok) {
        setSaveStatus('success')
        setSaveMessage('Mappings saved successfully')
        queryClient.invalidateQueries({ queryKey: ['resos-custom-field-mapping'] })
      } else {
        const data = await response.json()
        setSaveStatus('error')
        setSaveMessage(data.detail || 'Failed to save mappings')
      }
    } catch {
      setSaveStatus('error')
      setSaveMessage('Failed to save mappings')
    }
    setTimeout(() => {
      setSaveStatus('idle')
      setSaveMessage('')
    }, 5000)
  }

  // Define predefined mapping targets (like kitchen app)
  const mappingTargets = [
    { key: 'booking_number', label: 'Hotel Booking #', hint: 'Hotel booking reference number from Resos custom field' },
    { key: 'hotel_guest', label: 'Hotel Guest', hint: 'Yes/No field indicating if diner is a hotel guest' },
    { key: 'dbb', label: 'DBB (Dinner B&B)', hint: 'Yes/No field indicating Dinner Bed & Breakfast package guests' },
    { key: 'package', label: 'Package', hint: 'Yes/No field indicating package deal bookings' },
    { key: 'group_exclude', label: 'Group/Exclude', hint: 'Free-text field for group codes and exclusions (e.g., "#12345,NOT-#56789")' },
    { key: 'allergies', label: 'Allergies', hint: 'Multi-select or text field with allergy information' },
  ]

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Custom Field Mapping</h3>
      <p style={styles.hint}>
        Map Resos custom fields to booking data fields. Fetch custom fields first, then select which Resos field maps to each target.
      </p>

      <div style={styles.buttonRow}>
        <button
          onClick={handleFetch}
          disabled={fetchStatus === 'fetching'}
          style={mergeStyles(
            buttonStyle('outline'),
            fetchStatus === 'success' ? { borderColor: colors.success, color: colors.success } : {},
            fetchStatus === 'error' ? { borderColor: colors.error, color: colors.error } : {}
          )}
        >
          {fetchStatus === 'fetching' ? 'Fetching...' : 'Fetch Custom Fields'}
        </button>
        {customFields && customFields.length > 0 && (
          <span style={styles.glAccountCount}>{customFields.length} fields loaded</span>
        )}
      </div>

      {fetchMessage && (
        <div style={{
          ...styles.statusMessage,
          background: fetchStatus === 'success' ? colors.successBg : colors.errorBg,
          color: fetchStatus === 'success' ? colors.success : colors.error,
          marginTop: spacing.sm,
        }}>
          {fetchMessage}
        </div>
      )}

      {isLoading ? (
        <div style={styles.loading}>Loading custom fields...</div>
      ) : customFields && customFields.length > 0 ? (
        <>
          <div style={{ marginTop: spacing.lg, display: 'flex', flexDirection: 'column', gap: spacing.md }}>
            {mappingTargets.map((target) => (
              <div key={target.key} style={{
                display: 'flex',
                flexDirection: 'column',
                gap: spacing.xs,
              }}>
                <label style={{
                  fontWeight: typography.medium,
                  color: colors.text,
                  fontSize: typography.sm
                }}>
                  {target.label}
                </label>
                <select
                  value={customFieldMapping[target.key] || ''}
                  onChange={(e) => setCustomFieldMapping({
                    ...customFieldMapping,
                    [target.key]: e.target.value
                  })}
                  style={styles.select}
                >
                  <option value="">-- Select Field --</option>
                  {customFields.map((field) => (
                    <option key={field.id} value={field.id}>
                      {field.name} ({field.type})
                    </option>
                  ))}
                </select>
                <small style={{
                  ...styles.hint,
                  marginTop: 0,
                  fontSize: typography.xs
                }}>
                  {target.hint}
                </small>
              </div>
            ))}
          </div>

          <div style={{ ...styles.buttonRow, marginTop: spacing.lg }}>
            <button
              onClick={handleSaveMappings}
              disabled={saveStatus === 'saving'}
              style={mergeStyles(
                buttonStyle('primary'),
                saveStatus === 'success' ? { background: colors.success } : {},
                saveStatus === 'error' ? { background: colors.error } : {}
              )}
            >
              {saveStatus === 'saving' ? 'Saving...' :
               saveStatus === 'success' ? 'Saved!' :
               saveStatus === 'error' ? 'Error' : 'Save Mappings'}
            </button>
          </div>

          {saveMessage && (
            <div style={{
              ...styles.statusMessage,
              background: saveStatus === 'success' ? colors.successBg : colors.errorBg,
              color: saveStatus === 'success' ? colors.success : colors.error,
              marginTop: spacing.sm,
            }}>
              {saveMessage}
            </div>
          )}
        </>
      ) : (
        <div style={styles.emptyState}>
          No custom fields loaded. Click "Fetch Custom Fields" to load from Resos.
        </div>
      )}
    </div>
  )
}

// ============================================
// RESOS OPENING HOURS MAPPING SECTION
// ============================================

const ResosOpeningHoursMappingSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [fetchStatus, setFetchStatus] = useState<'idle' | 'fetching' | 'success' | 'error'>('idle')
  const [fetchMessage, setFetchMessage] = useState('')
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle')
  const [saveMessage, setSaveMessage] = useState('')
  const [mappings, setMappings] = useState<Record<string, OpeningHourMapping>>({})

  const { data: openingHours, isLoading } = useQuery<ResosOpeningHour[]>({
    queryKey: ['resos-opening-hours-list'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/resos/opening-hours')
      if (!response.ok) return []
      return response.json()
    },
  })

  const { data: existingMappings } = useQuery<OpeningHourMapping[]>({
    queryKey: ['resos-opening-hours-mapping'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/resos/opening-hours-mapping')
      if (!response.ok) return []
      return response.json()
    },
  })

  React.useEffect(() => {
    if (existingMappings) {
      const mappingObj: Record<string, OpeningHourMapping> = {}
      existingMappings.forEach(m => {
        mappingObj[m.opening_hour_id] = m
      })
      setMappings(mappingObj)
    }
  }, [existingMappings])

  const handleFetch = async () => {
    setFetchStatus('fetching')
    setFetchMessage('')
    try {
      const response = await fetch('/forecasting/api/resos/opening-hours', {
        method: 'GET',
      })
      const data = await response.json()
      if (response.ok) {
        setFetchStatus('success')
        setFetchMessage('Opening hours fetched successfully')
        queryClient.invalidateQueries({ queryKey: ['resos-opening-hours-list'] })
      } else {
        setFetchStatus('error')
        setFetchMessage(data.detail || 'Failed to fetch opening hours')
      }
    } catch {
      setFetchStatus('error')
      setFetchMessage('Failed to fetch opening hours')
    }
    setTimeout(() => {
      setFetchStatus('idle')
      setFetchMessage('')
    }, 5000)
  }

  const handleMappingChange = (hourId: string, periodType: string) => {
    setMappings(prev => ({
      ...prev,
      [hourId]: {
        opening_hour_id: hourId,
        period_type: periodType,
        display_name: prev[hourId]?.display_name
      }
    }))
  }

  const handleDisplayNameChange = (hourId: string, displayName: string) => {
    setMappings(prev => ({
      ...prev,
      [hourId]: {
        ...prev[hourId],
        opening_hour_id: hourId,
        period_type: prev[hourId]?.period_type || 'ignore',
        display_name: displayName || undefined
      }
    }))
  }

  const handleSaveMappings = async () => {
    setSaveStatus('saving')
    setSaveMessage('')
    try {
      const mappingsArray = Object.values(mappings).filter(m => m.period_type !== 'ignore')
      const response = await fetch('/forecasting/api/resos/opening-hours-mapping', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ mappings: mappingsArray })
      })
      if (response.ok) {
        setSaveStatus('success')
        setSaveMessage('Mappings saved successfully')
        queryClient.invalidateQueries({ queryKey: ['resos-opening-hours-mapping'] })
      } else {
        const data = await response.json()
        setSaveStatus('error')
        setSaveMessage(data.detail || 'Failed to save mappings')
      }
    } catch {
      setSaveStatus('error')
      setSaveMessage('Failed to save mappings')
    }
    setTimeout(() => {
      setSaveStatus('idle')
      setSaveMessage('')
    }, 5000)
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Opening Hours Mapping</h3>
      <p style={styles.hint}>
        Map Resos opening hours to meal periods. Fetch opening hours first, then assign period types.
      </p>

      <div style={styles.buttonRow}>
        <button
          onClick={handleFetch}
          disabled={fetchStatus === 'fetching'}
          style={mergeStyles(
            buttonStyle('outline'),
            fetchStatus === 'success' ? { borderColor: colors.success, color: colors.success } : {},
            fetchStatus === 'error' ? { borderColor: colors.error, color: colors.error } : {}
          )}
        >
          {fetchStatus === 'fetching' ? 'Fetching...' : 'Fetch Opening Hours'}
        </button>
        {openingHours && openingHours.length > 0 && (
          <span style={styles.glAccountCount}>{openingHours.length} hours loaded</span>
        )}
      </div>

      {fetchMessage && (
        <div style={{
          ...styles.statusMessage,
          background: fetchStatus === 'success' ? colors.successBg : colors.errorBg,
          color: fetchStatus === 'success' ? colors.success : colors.error,
          marginTop: spacing.sm,
        }}>
          {fetchMessage}
        </div>
      )}

      {isLoading ? (
        <div style={styles.loading}>Loading opening hours...</div>
      ) : openingHours && openingHours.length > 0 ? (
        <>
          <div style={{ marginTop: spacing.lg }}>
            {openingHours.map((hour) => {
              const mapping = mappings[hour.id]
              const periodType = mapping?.period_type || 'ignore'

              return (
                <div key={hour.id} style={{
                  display: 'grid',
                  gridTemplateColumns: '2fr 2fr 2fr',
                  gap: spacing.md,
                  marginBottom: spacing.md,
                  alignItems: 'center',
                  padding: spacing.sm,
                  background: colors.background,
                  borderRadius: radius.md,
                  border: `1px solid ${colors.borderLight}`,
                }}>
                  <div>
                    <div style={{ fontWeight: typography.medium, color: colors.text }}>
                      {hour.name}
                    </div>
                    <div style={{ fontSize: typography.xs, color: colors.textMuted }}>
                      {hour.start_time} - {hour.end_time}
                    </div>
                  </div>
                  <select
                    value={periodType}
                    onChange={(e) => handleMappingChange(hour.id, e.target.value)}
                    style={styles.select}
                  >
                    <option value="ignore">Ignore</option>
                    <option value="breakfast">Breakfast</option>
                    <option value="lunch">Lunch</option>
                    <option value="afternoon">Afternoon</option>
                    <option value="dinner">Dinner</option>
                    <option value="other">Other</option>
                  </select>
                  <input
                    type="text"
                    value={mapping?.display_name || ''}
                    onChange={(e) => handleDisplayNameChange(hour.id, e.target.value)}
                    placeholder="Display name (optional)"
                    style={styles.input}
                    disabled={periodType === 'ignore'}
                  />
                </div>
              )
            })}
          </div>

          <div style={styles.buttonRow}>
            <button
              onClick={handleSaveMappings}
              disabled={saveStatus === 'saving'}
              style={mergeStyles(
                buttonStyle('primary'),
                saveStatus === 'success' ? { background: colors.success } : {},
                saveStatus === 'error' ? { background: colors.error } : {}
              )}
            >
              {saveStatus === 'saving' ? 'Saving...' :
               saveStatus === 'success' ? 'Saved!' :
               saveStatus === 'error' ? 'Error' : 'Save Mappings'}
            </button>
          </div>

          {saveMessage && (
            <div style={{
              ...styles.statusMessage,
              background: saveStatus === 'success' ? colors.successBg : colors.errorBg,
              color: saveStatus === 'success' ? colors.success : colors.error,
              marginTop: spacing.sm,
            }}>
              {saveMessage}
            </div>
          )}
        </>
      ) : (
        <div style={styles.emptyState}>
          No opening hours loaded. Click "Fetch Opening Hours" to load from Resos.
        </div>
      )}
    </div>
  )
}

// ============================================
// RESOS MANUAL BREAKFAST CONFIGURATION SECTION
// ============================================

const ResosManualBreakfastSection: React.FC = () => {
  const [enabled, setEnabled] = useState(false)
  const [periods, setPeriods] = useState<ManualBreakfastPeriod[]>([
    { day_of_week: 1, start_time: '07:00', end_time: '10:00', is_active: true },
    { day_of_week: 2, start_time: '07:00', end_time: '10:00', is_active: true },
    { day_of_week: 3, start_time: '07:00', end_time: '10:00', is_active: true },
    { day_of_week: 4, start_time: '07:00', end_time: '10:00', is_active: true },
    { day_of_week: 5, start_time: '07:00', end_time: '10:00', is_active: true },
    { day_of_week: 6, start_time: '08:00', end_time: '11:00', is_active: true },
    { day_of_week: 0, start_time: '08:00', end_time: '11:00', is_active: true },
  ])
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle')
  const [saveMessage, setSaveMessage] = useState('')

  const { data: existingPeriods, isLoading } = useQuery<{ enabled: boolean; periods: ManualBreakfastPeriod[] }>({
    queryKey: ['resos-manual-breakfast'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/resos/manual-breakfast-periods')
      if (!response.ok) return { enabled: false, periods: [] }
      return response.json()
    },
  })

  React.useEffect(() => {
    if (existingPeriods && existingPeriods.periods.length > 0) {
      setEnabled(existingPeriods.enabled)
      setPeriods(existingPeriods.periods)
    }
  }, [existingPeriods])

  const dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']

  const handlePeriodChange = (index: number, field: keyof ManualBreakfastPeriod, value: string | boolean) => {
    const newPeriods = [...periods]
    newPeriods[index] = { ...newPeriods[index], [field]: value }
    setPeriods(newPeriods)
  }

  const handleSave = async () => {
    setSaveStatus('saving')
    setSaveMessage('')
    try {
      const response = await fetch('/forecasting/api/resos/manual-breakfast-periods', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ enabled, periods })
      })
      if (response.ok) {
        setSaveStatus('success')
        setSaveMessage('Manual breakfast configuration saved successfully')
      } else {
        const data = await response.json()
        setSaveStatus('error')
        setSaveMessage(data.detail || 'Failed to save configuration')
      }
    } catch {
      setSaveStatus('error')
      setSaveMessage('Failed to save configuration')
    }
    setTimeout(() => {
      setSaveStatus('idle')
      setSaveMessage('')
    }, 5000)
  }

  if (isLoading) {
    return <div style={styles.loading}>Loading manual breakfast configuration...</div>
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Manual Breakfast Configuration</h3>
      <p style={styles.hint}>
        Configure breakfast periods manually instead of using Resos opening hours. Useful for custom scheduling.
      </p>

      <label style={{
        display: 'flex',
        alignItems: 'center',
        gap: spacing.sm,
        marginBottom: spacing.lg,
        cursor: 'pointer',
      }}>
        <input
          type="checkbox"
          checked={enabled}
          onChange={(e) => setEnabled(e.target.checked)}
          style={styles.checkbox}
        />
        <span style={{ fontWeight: typography.medium, color: colors.text }}>
          Enable manual breakfast configuration
        </span>
      </label>

      {enabled && (
        <>
          <div style={{ marginBottom: spacing.lg }}>
            {periods.map((period, index) => (
              <div key={period.day_of_week} style={{
                display: 'grid',
                gridTemplateColumns: '150px 120px 120px 100px',
                gap: spacing.md,
                marginBottom: spacing.sm,
                alignItems: 'center',
                padding: spacing.sm,
                background: colors.background,
                borderRadius: radius.md,
                border: `1px solid ${colors.borderLight}`,
              }}>
                <div style={{ fontWeight: typography.medium, color: colors.text }}>
                  {dayNames[period.day_of_week]}
                </div>
                <input
                  type="time"
                  value={period.start_time}
                  onChange={(e) => handlePeriodChange(index, 'start_time', e.target.value)}
                  style={styles.input}
                  disabled={!period.is_active}
                />
                <input
                  type="time"
                  value={period.end_time}
                  onChange={(e) => handlePeriodChange(index, 'end_time', e.target.value)}
                  style={styles.input}
                  disabled={!period.is_active}
                />
                <label style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: spacing.xs,
                  cursor: 'pointer',
                }}>
                  <input
                    type="checkbox"
                    checked={period.is_active}
                    onChange={(e) => handlePeriodChange(index, 'is_active', e.target.checked)}
                    style={styles.checkbox}
                  />
                  <span style={{ fontSize: typography.sm, color: colors.text }}>Active</span>
                </label>
              </div>
            ))}
          </div>

          <div style={styles.buttonRow}>
            <button
              onClick={handleSave}
              disabled={saveStatus === 'saving'}
              style={mergeStyles(
                buttonStyle('primary'),
                saveStatus === 'success' ? { background: colors.success } : {},
                saveStatus === 'error' ? { background: colors.error } : {}
              )}
            >
              {saveStatus === 'saving' ? 'Saving...' :
               saveStatus === 'success' ? 'Saved!' :
               saveStatus === 'error' ? 'Error' : 'Save Configuration'}
            </button>
          </div>

          {saveMessage && (
            <div style={{
              ...styles.statusMessage,
              background: saveStatus === 'success' ? colors.successBg : colors.errorBg,
              color: saveStatus === 'success' ? colors.success : colors.error,
              marginTop: spacing.sm,
            }}>
              {saveMessage}
            </div>
          )}
        </>
      )}
    </div>
  )
}

// ============================================
// RESOS AVERAGE SPEND CONFIGURATION SECTION
// ============================================

const ResosAverageSpendSection: React.FC = () => {
  const queryClient = useQueryClient()
  const [breakfastFoodSpend, setBreakfastFoodSpend] = useState('')
  const [breakfastDrinksSpend, setBreakfastDrinksSpend] = useState('')
  const [lunchFoodSpend, setLunchFoodSpend] = useState('')
  const [lunchDrinksSpend, setLunchDrinksSpend] = useState('')
  const [dinnerFoodSpend, setDinnerFoodSpend] = useState('')
  const [dinnerDrinksSpend, setDinnerDrinksSpend] = useState('')
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle')
  const [saveMessage, setSaveMessage] = useState('')

  const { data: spendSettings, isLoading } = useQuery({
    queryKey: ['resos-average-spend'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/resos/average-spend')
      if (!response.ok) return null
      return response.json()
    },
  })

  // Update local state when settings load
  React.useEffect(() => {
    if (spendSettings) {
      setBreakfastFoodSpend(spendSettings.breakfast_food_spend?.toString() || '')
      setBreakfastDrinksSpend(spendSettings.breakfast_drinks_spend?.toString() || '')
      setLunchFoodSpend(spendSettings.lunch_food_spend?.toString() || '')
      setLunchDrinksSpend(spendSettings.lunch_drinks_spend?.toString() || '')
      setDinnerFoodSpend(spendSettings.dinner_food_spend?.toString() || '')
      setDinnerDrinksSpend(spendSettings.dinner_drinks_spend?.toString() || '')
    }
  }, [spendSettings])

  const handleSave = async () => {
    setSaveStatus('saving')
    setSaveMessage('')
    try {
      const response = await fetch('/forecasting/api/resos/average-spend', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          breakfast_food_spend: parseFloat(breakfastFoodSpend) || 0,
          breakfast_drinks_spend: parseFloat(breakfastDrinksSpend) || 0,
          lunch_food_spend: parseFloat(lunchFoodSpend) || 0,
          lunch_drinks_spend: parseFloat(lunchDrinksSpend) || 0,
          dinner_food_spend: parseFloat(dinnerFoodSpend) || 0,
          dinner_drinks_spend: parseFloat(dinnerDrinksSpend) || 0
        })
      })
      if (response.ok) {
        setSaveStatus('success')
        setSaveMessage('Average spend settings saved successfully')
        queryClient.invalidateQueries({ queryKey: ['resos-average-spend'] })
      } else {
        const data = await response.json()
        setSaveStatus('error')
        setSaveMessage(data.detail || 'Failed to save settings')
      }
    } catch {
      setSaveStatus('error')
      setSaveMessage('Failed to save settings')
    }
    setTimeout(() => {
      setSaveStatus('idle')
      setSaveMessage('')
    }, 3000)
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Average Spend per Cover (Gross inc VAT)</h3>
      <p style={styles.hint}>
        Configure average spend values per cover for revenue forecasting. Enter gross amounts (including VAT) - the system will calculate net revenue at 20% VAT automatically. These are interim values until till integration provides live data.
      </p>

      {isLoading ? (
        <div style={styles.loading}>Loading settings...</div>
      ) : (
        <>
          <div style={{
            display: 'grid',
            gridTemplateColumns: 'repeat(3, 1fr)',
            gap: spacing.lg,
            marginBottom: spacing.lg,
          }}>
            {/* Breakfast Section */}
            <div style={{
              padding: spacing.md,
              background: colors.background,
              borderRadius: radius.md,
              border: `1px solid ${colors.borderLight}`,
            }}>
              <h4 style={{ margin: 0, marginBottom: spacing.md, fontSize: typography.base, fontWeight: typography.medium }}>
                Breakfast
              </h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: spacing.sm }}>
                <label style={styles.label}>
                  <span>Food Spend (£)</span>
                  <input
                    type="number"
                    step="0.01"
                    min="0"
                    value={breakfastFoodSpend}
                    onChange={(e) => setBreakfastFoodSpend(e.target.value)}
                    placeholder="e.g. 15.00"
                    style={styles.input}
                  />
                </label>
                <label style={styles.label}>
                  <span>Drinks Spend (£)</span>
                  <input
                    type="number"
                    step="0.01"
                    min="0"
                    value={breakfastDrinksSpend}
                    onChange={(e) => setBreakfastDrinksSpend(e.target.value)}
                    placeholder="e.g. 5.00"
                    style={styles.input}
                  />
                </label>
              </div>
            </div>

            {/* Lunch Section */}
            <div style={{
              padding: spacing.md,
              background: colors.background,
              borderRadius: radius.md,
              border: `1px solid ${colors.borderLight}`,
            }}>
              <h4 style={{ margin: 0, marginBottom: spacing.md, fontSize: typography.base, fontWeight: typography.medium }}>
                Lunch
              </h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: spacing.sm }}>
                <label style={styles.label}>
                  <span>Food Spend (£)</span>
                  <input
                    type="number"
                    step="0.01"
                    min="0"
                    value={lunchFoodSpend}
                    onChange={(e) => setLunchFoodSpend(e.target.value)}
                    placeholder="e.g. 25.00"
                    style={styles.input}
                  />
                </label>
                <label style={styles.label}>
                  <span>Drinks Spend (£)</span>
                  <input
                    type="number"
                    step="0.01"
                    min="0"
                    value={lunchDrinksSpend}
                    onChange={(e) => setLunchDrinksSpend(e.target.value)}
                    placeholder="e.g. 12.00"
                    style={styles.input}
                  />
                </label>
              </div>
            </div>

            {/* Dinner Section */}
            <div style={{
              padding: spacing.md,
              background: colors.background,
              borderRadius: radius.md,
              border: `1px solid ${colors.borderLight}`,
            }}>
              <h4 style={{ margin: 0, marginBottom: spacing.md, fontSize: typography.base, fontWeight: typography.medium }}>
                Dinner
              </h4>
              <div style={{ display: 'flex', flexDirection: 'column', gap: spacing.sm }}>
                <label style={styles.label}>
                  <span>Food Spend (£)</span>
                  <input
                    type="number"
                    step="0.01"
                    min="0"
                    value={dinnerFoodSpend}
                    onChange={(e) => setDinnerFoodSpend(e.target.value)}
                    placeholder="e.g. 45.00"
                    style={styles.input}
                  />
                </label>
                <label style={styles.label}>
                  <span>Drinks Spend (£)</span>
                  <input
                    type="number"
                    step="0.01"
                    min="0"
                    value={dinnerDrinksSpend}
                    onChange={(e) => setDinnerDrinksSpend(e.target.value)}
                    placeholder="e.g. 20.00"
                    style={styles.input}
                  />
                </label>
              </div>
            </div>
          </div>

          <div style={styles.buttonRow}>
            <button
              onClick={handleSave}
              disabled={saveStatus === 'saving'}
              style={mergeStyles(
                buttonStyle('primary'),
                saveStatus === 'success' ? { background: colors.success } : {},
                saveStatus === 'error' ? { background: colors.error } : {}
              )}
            >
              {saveStatus === 'saving' ? 'Saving...' :
               saveStatus === 'success' ? 'Saved!' :
               saveStatus === 'error' ? 'Error' : 'Save Settings'}
            </button>
          </div>

          {saveMessage && (
            <div style={{
              ...styles.statusMessage,
              background: saveStatus === 'success' ? colors.successBg : colors.errorBg,
              color: saveStatus === 'success' ? colors.success : colors.error,
              marginTop: spacing.sm,
            }}>
              {saveMessage}
            </div>
          )}
        </>
      )}
    </div>
  )
}

// ============================================
// RESOS SYNC CONFIGURATION SECTION
// ============================================

const ResosSyncConfigSection: React.FC = () => {
  const [autoSyncEnabled, setAutoSyncEnabled] = useState(false)
  const [syncTime, setSyncTime] = useState('03:00')
  const [fromDate, setFromDate] = useState('')
  const [toDate, setToDate] = useState('')
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle')
  const [saveMessage, setSaveMessage] = useState('')
  const [syncStatus, setSyncStatus] = useState<'idle' | 'syncing' | 'success' | 'error'>('idle')
  const [syncMessage, setSyncMessage] = useState('')

  const { data: syncConfig, isLoading: configLoading } = useQuery({
    queryKey: ['resos-sync-config'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/resos-bookings/config')
      if (!response.ok) return null
      return response.json()
    },
  })

  const { data: lastSyncStatus, refetch: refetchStatus } = useQuery<SyncStatus>({
    queryKey: ['resos-sync-status'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/sync/resos-bookings/status')
      if (!response.ok) return {}
      return response.json()
    },
    refetchInterval: 30000,
  })

  React.useEffect(() => {
    if (syncConfig) {
      setAutoSyncEnabled(syncConfig.auto_sync_enabled || false)
      setSyncTime(syncConfig.sync_time || '03:00')
    }
  }, [syncConfig])

  React.useEffect(() => {
    const today = new Date()
    const sevenDaysAgo = new Date(today)
    sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7)

    setFromDate(sevenDaysAgo.toISOString().split('T')[0])
    setToDate(today.toISOString().split('T')[0])
  }, [])

  const handleSaveConfig = async () => {
    setSaveStatus('saving')
    setSaveMessage('')
    try {
      const response = await fetch('/forecasting/api/sync/resos-bookings/config', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          auto_sync_enabled: autoSyncEnabled,
          sync_time: syncTime
        })
      })
      if (response.ok) {
        setSaveStatus('success')
        setSaveMessage('Sync configuration saved successfully')
      } else {
        const data = await response.json()
        setSaveStatus('error')
        setSaveMessage(data.detail || 'Failed to save configuration')
      }
    } catch {
      setSaveStatus('error')
      setSaveMessage('Failed to save configuration')
    }
    setTimeout(() => {
      setSaveStatus('idle')
      setSaveMessage('')
    }, 5000)
  }

  const handleTriggerSync = async () => {
    setSyncStatus('syncing')
    setSyncMessage('')
    try {
      // Build query params with from_date and to_date
      const params = new URLSearchParams()
      if (fromDate) params.append('from_date', fromDate)
      if (toDate) params.append('to_date', toDate)

      const response = await fetch(`/forecasting/api/sync/resos-bookings/sync?${params.toString()}`, {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setSyncStatus('success')
        setSyncMessage(data.message || 'Sync triggered successfully')
        refetchStatus()
      } else {
        setSyncStatus('error')
        setSyncMessage(data.detail || 'Failed to trigger sync')
      }
    } catch {
      setSyncStatus('error')
      setSyncMessage('Failed to trigger sync')
    }
    setTimeout(() => {
      setSyncStatus('idle')
      setSyncMessage('')
    }, 5000)
  }

  if (configLoading) {
    return <div style={styles.loading}>Loading sync configuration...</div>
  }

  return (
    <div style={styles.subsection}>
      <h3 style={styles.subsectionTitle}>Sync Configuration</h3>
      <p style={styles.hint}>
        Configure automatic synchronization or trigger manual syncs of booking data from Resos.
      </p>

      <div style={{ marginBottom: spacing.lg }}>
        <h4 style={{ ...styles.subsectionTitle, fontSize: typography.base, marginBottom: spacing.md }}>
          Automatic Sync
        </h4>

        <label style={{
          display: 'flex',
          alignItems: 'center',
          gap: spacing.sm,
          marginBottom: spacing.md,
          cursor: 'pointer',
        }}>
          <input
            type="checkbox"
            checked={autoSyncEnabled}
            onChange={(e) => setAutoSyncEnabled(e.target.checked)}
            style={styles.checkbox}
          />
          <span style={{ fontWeight: typography.medium, color: colors.text }}>
            Enable automatic sync
          </span>
        </label>

        {autoSyncEnabled && (
          <label style={styles.label}>
            <span>Sync Time (HH:MM)</span>
            <input
              type="time"
              value={syncTime}
              onChange={(e) => setSyncTime(e.target.value)}
              style={{ ...styles.input, maxWidth: '200px' }}
            />
          </label>
        )}

        <div style={styles.buttonRow}>
          <button
            onClick={handleSaveConfig}
            disabled={saveStatus === 'saving'}
            style={mergeStyles(
              buttonStyle('primary'),
              saveStatus === 'success' ? { background: colors.success } : {},
              saveStatus === 'error' ? { background: colors.error } : {}
            )}
          >
            {saveStatus === 'saving' ? 'Saving...' :
             saveStatus === 'success' ? 'Saved!' :
             saveStatus === 'error' ? 'Error' : 'Save Configuration'}
          </button>
        </div>

        {saveMessage && (
          <div style={{
            ...styles.statusMessage,
            background: saveStatus === 'success' ? colors.successBg : colors.errorBg,
            color: saveStatus === 'success' ? colors.success : colors.error,
            marginTop: spacing.sm,
          }}>
            {saveMessage}
          </div>
        )}
      </div>

      <div style={styles.divider} />

      <div style={{ marginTop: spacing.lg }}>
        <h4 style={{ ...styles.subsectionTitle, fontSize: typography.base, marginBottom: spacing.md }}>
          Manual Sync
        </h4>

        <div style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
          gap: spacing.md,
          marginBottom: spacing.md,
        }}>
          <label style={styles.label}>
            <span>From Date</span>
            <input
              type="date"
              value={fromDate}
              onChange={(e) => setFromDate(e.target.value)}
              style={styles.input}
            />
          </label>
          <label style={styles.label}>
            <span>To Date</span>
            <input
              type="date"
              value={toDate}
              onChange={(e) => setToDate(e.target.value)}
              style={styles.input}
            />
          </label>
        </div>

        <div style={styles.buttonRow}>
          <button
            onClick={handleTriggerSync}
            disabled={syncStatus === 'syncing'}
            style={mergeStyles(
              buttonStyle('outline'),
              syncStatus === 'success' ? { borderColor: colors.success, color: colors.success } : {},
              syncStatus === 'error' ? { borderColor: colors.error, color: colors.error } : {}
            )}
          >
            {syncStatus === 'syncing' ? 'Syncing...' : 'Trigger Sync'}
          </button>
        </div>

        {syncMessage && (
          <div style={{
            ...styles.statusMessage,
            background: syncStatus === 'success' ? colors.successBg : colors.errorBg,
            color: syncStatus === 'success' ? colors.success : colors.error,
            marginTop: spacing.sm,
          }}>
            {syncMessage}
          </div>
        )}

        {lastSyncStatus && lastSyncStatus.last_sync && (
          <div style={{
            marginTop: spacing.lg,
            padding: spacing.md,
            background: colors.background,
            borderRadius: radius.md,
            border: `1px solid ${colors.borderLight}`,
          }}>
            <h4 style={{ fontSize: typography.sm, fontWeight: typography.medium, marginBottom: spacing.sm, color: colors.text }}>
              Last Sync Status
            </h4>
            <div style={{ fontSize: typography.sm, color: colors.textSecondary }}>
              <div style={{ marginBottom: spacing.xs }}>
                <strong>Time:</strong> {lastSyncStatus.last_sync.completed_at
                  ? new Date(lastSyncStatus.last_sync.completed_at).toLocaleString()
                  : lastSyncStatus.last_sync.started_at
                    ? new Date(lastSyncStatus.last_sync.started_at).toLocaleString()
                    : 'N/A'}
              </div>
              {lastSyncStatus.last_sync.status && (
                <div style={{ marginBottom: spacing.xs }}>
                  <strong>Status:</strong>{' '}
                  <span style={{
                    color: lastSyncStatus.last_sync.status === 'success' ? colors.success : colors.error
                  }}>
                    {lastSyncStatus.last_sync.status}
                  </span>
                </div>
              )}
              {lastSyncStatus.last_sync.error_message && (
                <div>
                  <strong>Message:</strong> {lastSyncStatus.last_sync.error_message}
                </div>
              )}
            </div>
          </div>
        )}
      </div>
    </div>
  )
}

// ============================================
// SPECIAL DATES PAGE
// ============================================

interface SpecialDate {
  id: number
  name: string
  pattern_type: 'fixed' | 'nth_weekday' | 'relative_to_date'
  fixed_month: number | null
  fixed_day: number | null
  nth_week: number | null
  weekday: number | null
  month: number | null
  relative_to_month: number | null
  relative_to_day: number | null
  relative_weekday: number | null
  relative_direction: string | null
  duration_days: number
  is_recurring: boolean
  one_off_year: number | null
  is_active: boolean
  created_at: string
}

interface ResolvedDate {
  name: string
  date: string
  day_of_week: string
}

const WEEKDAYS = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
const MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
const NTH_OPTIONS = [
  { value: 1, label: 'First' },
  { value: 2, label: 'Second' },
  { value: 3, label: 'Third' },
  { value: 4, label: 'Fourth' },
  { value: -1, label: 'Last' },
]

const SpecialDatesPage: React.FC = () => {
  const queryClient = useQueryClient()
  const [showForm, setShowForm] = useState(false)
  const [editingDate, setEditingDate] = useState<SpecialDate | null>(null)
  const [previewYear, setPreviewYear] = useState(new Date().getFullYear())

  // Form state
  const [formData, setFormData] = useState({
    name: '',
    pattern_type: 'fixed' as 'fixed' | 'nth_weekday' | 'relative_to_date',
    fixed_month: 1,
    fixed_day: 1,
    nth_week: 1,
    weekday: 0,
    month: 1,
    relative_to_month: 12,
    relative_to_day: 25,
    relative_weekday: 4,
    relative_direction: 'before',
    duration_days: 1,
    is_recurring: true,
    one_off_year: new Date().getFullYear(),
    is_active: true,
  })

  // Fetch special dates
  const { data: specialDates, isLoading } = useQuery<SpecialDate[]>({
    queryKey: ['special-dates'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/settings/special-dates')
      if (!response.ok) return []
      return response.json()
    },
  })

  // Fetch preview for year
  const { data: previewDates } = useQuery<ResolvedDate[]>({
    queryKey: ['special-dates-preview', previewYear],
    queryFn: async () => {
      const response = await fetch(`/forecasting/api/settings/special-dates/preview?year=${previewYear}`)
      if (!response.ok) return []
      return response.json()
    },
  })

  // Create mutation
  const createMutation = useMutation({
    mutationFn: async (data: typeof formData) => {
      const response = await fetch('/forecasting/api/settings/special-dates', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data)
      })
      if (!response.ok) throw new Error('Failed to create')
      return response.json()
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['special-dates'] })
      queryClient.invalidateQueries({ queryKey: ['special-dates-preview'] })
      setShowForm(false)
      resetForm()
    }
  })

  // Update mutation
  const updateMutation = useMutation({
    mutationFn: async ({ id, data }: { id: number, data: typeof formData }) => {
      const response = await fetch(`/forecasting/api/settings/special-dates/${id}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data)
      })
      if (!response.ok) throw new Error('Failed to update')
      return response.json()
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['special-dates'] })
      queryClient.invalidateQueries({ queryKey: ['special-dates-preview'] })
      setShowForm(false)
      setEditingDate(null)
      resetForm()
    }
  })

  // Delete mutation
  const deleteMutation = useMutation({
    mutationFn: async (id: number) => {
      const response = await fetch(`/forecasting/api/settings/special-dates/${id}`, {
        method: 'DELETE',
      })
      if (!response.ok) throw new Error('Failed to delete')
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['special-dates'] })
      queryClient.invalidateQueries({ queryKey: ['special-dates-preview'] })
    }
  })

  // Seed defaults mutation
  const seedMutation = useMutation({
    mutationFn: async () => {
      const response = await fetch('/forecasting/api/settings/special-dates/seed-defaults', {
        method: 'POST',
      })
      if (!response.ok) throw new Error('Failed to seed')
      return response.json()
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['special-dates'] })
      queryClient.invalidateQueries({ queryKey: ['special-dates-preview'] })
    }
  })

  const resetForm = () => {
    setFormData({
      name: '',
      pattern_type: 'fixed',
      fixed_month: 1,
      fixed_day: 1,
      nth_week: 1,
      weekday: 0,
      month: 1,
      relative_to_month: 12,
      relative_to_day: 25,
      relative_weekday: 4,
      relative_direction: 'before',
      duration_days: 1,
      is_recurring: true,
      one_off_year: new Date().getFullYear(),
      is_active: true,
    })
  }

  const handleEdit = (sd: SpecialDate) => {
    setEditingDate(sd)
    setFormData({
      name: sd.name,
      pattern_type: sd.pattern_type,
      fixed_month: sd.fixed_month || 1,
      fixed_day: sd.fixed_day || 1,
      nth_week: sd.nth_week || 1,
      weekday: sd.weekday || 0,
      month: sd.month || 1,
      relative_to_month: sd.relative_to_month || 12,
      relative_to_day: sd.relative_to_day || 25,
      relative_weekday: sd.relative_weekday || 4,
      relative_direction: sd.relative_direction || 'before',
      duration_days: sd.duration_days || 1,
      is_recurring: sd.is_recurring,
      one_off_year: sd.one_off_year || new Date().getFullYear(),
      is_active: sd.is_active,
    })
    setShowForm(true)
  }

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault()
    if (editingDate) {
      updateMutation.mutate({ id: editingDate.id, data: formData })
    } else {
      createMutation.mutate(formData)
    }
  }

  const getPatternDescription = (sd: SpecialDate): string => {
    if (sd.pattern_type === 'fixed') {
      return `${MONTHS[(sd.fixed_month || 1) - 1]} ${sd.fixed_day}`
    } else if (sd.pattern_type === 'nth_weekday') {
      const nth = NTH_OPTIONS.find(o => o.value === sd.nth_week)?.label || ''
      return `${nth} ${WEEKDAYS[sd.weekday || 0]} of ${MONTHS[(sd.month || 1) - 1]}`
    } else {
      return `${WEEKDAYS[sd.relative_weekday || 0]} ${sd.relative_direction} ${MONTHS[(sd.relative_to_month || 1) - 1]} ${sd.relative_to_day}`
    }
  }

  return (
    <div style={styles.section}>
      <div style={styles.sectionHeader}>
        <div>
          <h2 style={styles.sectionTitle}>Special Dates</h2>
          <p style={styles.hint}>
            Configure custom holidays and events for Prophet forecasting
          </p>
        </div>
        <div style={{ display: 'flex', gap: spacing.sm }}>
          {(!specialDates || specialDates.length === 0) && (
            <button
              onClick={() => seedMutation.mutate()}
              disabled={seedMutation.isPending}
              style={mergeStyles(buttonStyle('secondary'), { background: colors.textSecondary })}
            >
              {seedMutation.isPending ? 'Seeding...' : 'Seed Defaults'}
            </button>
          )}
          <button
            onClick={() => { resetForm(); setEditingDate(null); setShowForm(true) }}
            style={buttonStyle()}
          >
            Add Special Date
          </button>
        </div>
      </div>

      {/* Form Modal */}
      {showForm && (
        <div style={styles.formContainer}>
          <h3 style={{ margin: 0, marginBottom: spacing.md, color: colors.text }}>
            {editingDate ? 'Edit Special Date' : 'Add Special Date'}
          </h3>
          <form onSubmit={handleSubmit}>
            <div style={styles.formGrid}>
              <div style={styles.formGroup}>
                <label style={styles.label}>Name</label>
                <input
                  type="text"
                  value={formData.name}
                  onChange={(e) => setFormData({ ...formData, name: e.target.value })}
                  style={styles.input}
                  placeholder="e.g., Valentine's Day"
                  required
                />
              </div>

              <div style={styles.formGroup}>
                <label style={styles.label}>Pattern Type</label>
                <select
                  value={formData.pattern_type}
                  onChange={(e) => setFormData({ ...formData, pattern_type: e.target.value as typeof formData.pattern_type })}
                  style={styles.select}
                >
                  <option value="fixed">Fixed Date (e.g., Feb 14)</option>
                  <option value="nth_weekday">Nth Weekday (e.g., 2nd Monday of May)</option>
                  <option value="relative_to_date">Relative to Date (e.g., Friday before Dec 25)</option>
                </select>
              </div>

              {/* Fixed Date Fields */}
              {formData.pattern_type === 'fixed' && (
                <>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Month</label>
                    <select
                      value={formData.fixed_month}
                      onChange={(e) => setFormData({ ...formData, fixed_month: parseInt(e.target.value) })}
                      style={styles.select}
                    >
                      {MONTHS.map((m, i) => (
                        <option key={i} value={i + 1}>{m}</option>
                      ))}
                    </select>
                  </div>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Day</label>
                    <input
                      type="number"
                      min={1}
                      max={31}
                      value={formData.fixed_day}
                      onChange={(e) => setFormData({ ...formData, fixed_day: parseInt(e.target.value) })}
                      style={styles.input}
                    />
                  </div>
                </>
              )}

              {/* Nth Weekday Fields */}
              {formData.pattern_type === 'nth_weekday' && (
                <>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Which</label>
                    <select
                      value={formData.nth_week}
                      onChange={(e) => setFormData({ ...formData, nth_week: parseInt(e.target.value) })}
                      style={styles.select}
                    >
                      {NTH_OPTIONS.map((o) => (
                        <option key={o.value} value={o.value}>{o.label}</option>
                      ))}
                    </select>
                  </div>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Weekday</label>
                    <select
                      value={formData.weekday}
                      onChange={(e) => setFormData({ ...formData, weekday: parseInt(e.target.value) })}
                      style={styles.select}
                    >
                      {WEEKDAYS.map((w, i) => (
                        <option key={i} value={i}>{w}</option>
                      ))}
                    </select>
                  </div>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Month</label>
                    <select
                      value={formData.month}
                      onChange={(e) => setFormData({ ...formData, month: parseInt(e.target.value) })}
                      style={styles.select}
                    >
                      {MONTHS.map((m, i) => (
                        <option key={i} value={i + 1}>{m}</option>
                      ))}
                    </select>
                  </div>
                </>
              )}

              {/* Relative to Date Fields */}
              {formData.pattern_type === 'relative_to_date' && (
                <>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Find</label>
                    <select
                      value={formData.relative_weekday}
                      onChange={(e) => setFormData({ ...formData, relative_weekday: parseInt(e.target.value) })}
                      style={styles.select}
                    >
                      {WEEKDAYS.map((w, i) => (
                        <option key={i} value={i}>{w}</option>
                      ))}
                    </select>
                  </div>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Direction</label>
                    <select
                      value={formData.relative_direction}
                      onChange={(e) => setFormData({ ...formData, relative_direction: e.target.value })}
                      style={styles.select}
                    >
                      <option value="before">Before</option>
                      <option value="after">After</option>
                    </select>
                  </div>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Reference Month</label>
                    <select
                      value={formData.relative_to_month}
                      onChange={(e) => setFormData({ ...formData, relative_to_month: parseInt(e.target.value) })}
                      style={styles.select}
                    >
                      {MONTHS.map((m, i) => (
                        <option key={i} value={i + 1}>{m}</option>
                      ))}
                    </select>
                  </div>
                  <div style={styles.formGroup}>
                    <label style={styles.label}>Reference Day</label>
                    <input
                      type="number"
                      min={1}
                      max={31}
                      value={formData.relative_to_day}
                      onChange={(e) => setFormData({ ...formData, relative_to_day: parseInt(e.target.value) })}
                      style={styles.input}
                    />
                  </div>
                </>
              )}

              {/* Common Fields */}
              <div style={styles.formGroup}>
                <label style={styles.label}>Duration (days)</label>
                <input
                  type="number"
                  min={1}
                  max={30}
                  value={formData.duration_days}
                  onChange={(e) => setFormData({ ...formData, duration_days: parseInt(e.target.value) })}
                  style={styles.input}
                />
              </div>

              <div style={styles.formGroup}>
                <label style={styles.label}>Recurrence</label>
                <select
                  value={formData.is_recurring ? 'recurring' : 'one-off'}
                  onChange={(e) => setFormData({ ...formData, is_recurring: e.target.value === 'recurring' })}
                  style={styles.select}
                >
                  <option value="recurring">Every Year</option>
                  <option value="one-off">One-off</option>
                </select>
              </div>

              {!formData.is_recurring && (
                <div style={styles.formGroup}>
                  <label style={styles.label}>Year</label>
                  <input
                    type="number"
                    min={2020}
                    max={2030}
                    value={formData.one_off_year}
                    onChange={(e) => setFormData({ ...formData, one_off_year: parseInt(e.target.value) })}
                    style={styles.input}
                  />
                </div>
              )}

              <div style={styles.formGroup}>
                <label style={{ ...styles.label, display: 'flex', alignItems: 'center', gap: spacing.sm }}>
                  <input
                    type="checkbox"
                    checked={formData.is_active}
                    onChange={(e) => setFormData({ ...formData, is_active: e.target.checked })}
                  />
                  Active
                </label>
              </div>
            </div>

            <div style={{ display: 'flex', gap: spacing.sm, marginTop: spacing.md }}>
              <button type="submit" style={buttonStyle()} disabled={createMutation.isPending || updateMutation.isPending}>
                {editingDate ? 'Update' : 'Create'}
              </button>
              <button
                type="button"
                onClick={() => { setShowForm(false); setEditingDate(null); resetForm() }}
                style={mergeStyles(buttonStyle('secondary'), { background: colors.textSecondary })}
              >
                Cancel
              </button>
            </div>
          </form>
        </div>
      )}

      {/* Existing Special Dates List */}
      <div style={styles.tableContainer}>
        <table style={styles.table}>
          <thead>
            <tr>
              <th style={styles.th}>Name</th>
              <th style={styles.th}>Pattern</th>
              <th style={styles.th}>Duration</th>
              <th style={styles.th}>Recurrence</th>
              <th style={styles.th}>Status</th>
              <th style={styles.th}>Actions</th>
            </tr>
          </thead>
          <tbody>
            {isLoading ? (
              <tr><td colSpan={6} style={{ ...styles.td, textAlign: 'center' }}>Loading...</td></tr>
            ) : specialDates && specialDates.length > 0 ? (
              specialDates.map((sd) => (
                <tr key={sd.id}>
                  <td style={styles.td}>{sd.name}</td>
                  <td style={{ ...styles.td, color: colors.textSecondary }}>{getPatternDescription(sd)}</td>
                  <td style={styles.td}>{sd.duration_days} day{sd.duration_days > 1 ? 's' : ''}</td>
                  <td style={styles.td}>{sd.is_recurring ? 'Every Year' : `${sd.one_off_year} only`}</td>
                  <td style={styles.td}>
                    <span style={mergeStyles(badgeStyle(sd.is_active ? 'success' : 'info'), {
                      background: sd.is_active ? colors.success : colors.textMuted
                    })}>
                      {sd.is_active ? 'Active' : 'Inactive'}
                    </span>
                  </td>
                  <td style={styles.td}>
                    <div style={{ display: 'flex', gap: spacing.xs }}>
                      <button
                        onClick={() => handleEdit(sd)}
                        style={{ ...styles.actionButton, color: colors.accent }}
                      >
                        Edit
                      </button>
                      <button
                        onClick={() => {
                          if (confirm(`Delete "${sd.name}"?`)) {
                            deleteMutation.mutate(sd.id)
                          }
                        }}
                        style={{ ...styles.actionButton, color: colors.error }}
                      >
                        Delete
                      </button>
                    </div>
                  </td>
                </tr>
              ))
            ) : (
              <tr><td colSpan={6} style={{ ...styles.td, textAlign: 'center', color: colors.textMuted }}>
                No special dates configured. Click "Seed Defaults" to add common dates.
              </td></tr>
            )}
          </tbody>
        </table>
      </div>

      {/* Preview Section */}
      <div style={{ marginTop: spacing.xl }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: spacing.md, marginBottom: spacing.md }}>
          <h3 style={{ margin: 0, color: colors.text }}>Preview</h3>
          <select
            value={previewYear}
            onChange={(e) => setPreviewYear(parseInt(e.target.value))}
            style={styles.select}
          >
            {[2024, 2025, 2026, 2027].map((y) => (
              <option key={y} value={y}>{y}</option>
            ))}
          </select>
        </div>

        <div style={{ display: 'flex', flexWrap: 'wrap', gap: spacing.sm }}>
          {previewDates && previewDates.length > 0 ? (
            previewDates.map((pd, i) => (
              <div key={i} style={styles.previewCard}>
                <div style={{ fontWeight: typography.semibold }}>{pd.name}</div>
                <div style={{ fontSize: typography.sm, color: colors.textSecondary }}>
                  {pd.day_of_week} {pd.date}
                </div>
              </div>
            ))
          ) : (
            <p style={{ color: colors.textMuted }}>No dates to preview</p>
          )}
        </div>
      </div>
    </div>
  )
}

// ============================================
// DATABASE PAGE
// ============================================

const DatabasePage: React.FC = () => {
  return (
    <div style={styles.section}>
      <h2 style={styles.sectionTitle}>Database Browser</h2>
      <p style={styles.hint}>
        Browse and manage the database using Adminer. Login with: Server: <strong>db</strong>, Username: <strong>forecast</strong>, Password: <strong>forecast_secret</strong>, Database: <strong>forecast_data</strong>
      </p>

      <div style={styles.iframeContainer}>
        <iframe
          src="/adminer/?pgsql=db&username=forecast&db=forecast_data"
          style={styles.iframe}
          title="Database Browser"
        />
      </div>
    </div>
  )
}

// ============================================
// BUDGET PAGE
// ============================================

interface MonthlyBudget {
  id: number
  year: number
  month: number
  budget_type: string
  budget_value: number
  notes: string | null
  created_at: string
  updated_at: string
}

interface DailyBudget {
  date: string
  budget_type: string
  budget_value: number
  distribution_method: string
  prior_year_pct: number | null
}

interface UploadResult {
  status: string
  filename: string
  records_created: number
  records_updated: number
  total_records: number
  errors: string[] | null
}

const MONTH_NAMES = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

const BudgetPage: React.FC = () => {
  const queryClient = useQueryClient()
  const [selectedYear, setSelectedYear] = useState(new Date().getFullYear())
  const [selectedMonth, setSelectedMonth] = useState<number | null>(null)
  const [uploading, setUploading] = useState(false)
  const [uploadResult, setUploadResult] = useState<UploadResult | null>(null)
  const [distributing, setDistributing] = useState(false)
  const [distributeStatus, setDistributeStatus] = useState<string | null>(null)
  const [dragOver, setDragOver] = useState(false)

  // Fetch monthly budgets for selected year
  const { data: monthlyBudgets, isLoading: loadingMonthly } = useQuery<MonthlyBudget[]>({
    queryKey: ['monthly-budgets', selectedYear],
    queryFn: async () => {
      const response = await fetch(`/forecasting/api/budget/monthly?year=${selectedYear}`)
      if (!response.ok) return []
      return response.json()
    },
  })

  // Fetch daily budgets for selected month
  const { data: dailyBudgets, isLoading: loadingDaily } = useQuery<DailyBudget[]>({
    queryKey: ['daily-budgets', selectedYear, selectedMonth],
    queryFn: async () => {
      if (selectedMonth === null) return []
      const startDate = `${selectedYear}-${String(selectedMonth).padStart(2, '0')}-01`
      const lastDay = new Date(selectedYear, selectedMonth, 0).getDate()
      const endDate = `${selectedYear}-${String(selectedMonth).padStart(2, '0')}-${lastDay}`
      const response = await fetch(`/forecasting/api/budget/daily?from_date=${startDate}&to_date=${endDate}`)
      if (!response.ok) return []
      return response.json()
    },
    enabled: selectedMonth !== null,
  })

  // Handle file upload
  const handleFileUpload = async (file: File) => {
    const validTypes = ['.csv', '.xlsx', '.xls']
    const ext = file.name.toLowerCase().substring(file.name.lastIndexOf('.'))
    if (!validTypes.includes(ext)) {
      setUploadResult({
        status: 'error',
        filename: file.name,
        records_created: 0,
        records_updated: 0,
        total_records: 0,
        errors: ['Invalid file type. Please upload a CSV or Excel file.']
      })
      return
    }

    setUploading(true)
    setUploadResult(null)

    const formData = new FormData()
    formData.append('file', file)

    try {
      const response = await fetch('/forecasting/api/budget/upload', {
        method: 'POST',
        body: formData
      })
      const result = await response.json()
      if (response.ok) {
        setUploadResult(result)
        queryClient.invalidateQueries({ queryKey: ['monthly-budgets'] })
      } else {
        setUploadResult({
          status: 'error',
          filename: file.name,
          records_created: 0,
          records_updated: 0,
          total_records: 0,
          errors: [result.detail || 'Upload failed']
        })
      }
    } catch (err) {
      setUploadResult({
        status: 'error',
        filename: file.name,
        records_created: 0,
        records_updated: 0,
        total_records: 0,
        errors: ['Failed to upload file']
      })
    } finally {
      setUploading(false)
    }
  }

  // Handle drag and drop
  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault()
    setDragOver(false)
    const file = e.dataTransfer.files[0]
    if (file) handleFileUpload(file)
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
    setDragOver(true)
  }

  const handleDragLeave = () => {
    setDragOver(false)
  }

  // Handle file input
  const handleFileInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file) handleFileUpload(file)
    e.target.value = '' // Reset input
  }

  // Download template
  const handleDownloadTemplate = async () => {
    try {
      const response = await fetch('/forecasting/api/budget/template')
      if (response.ok) {
        const blob = await response.blob()
        const url = window.URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = `budget_template_${selectedYear}.xlsx`
        a.click()
        window.URL.revokeObjectURL(url)
      }
    } catch (err) {
      console.error('Failed to download template', err)
    }
  }

  // Distribute all budgets
  const handleDistributeAll = async () => {
    setDistributing(true)
    setDistributeStatus(null)
    let totalDays = 0

    try {
      for (let month = 1; month <= 12; month++) {
        const response = await fetch(`/forecasting/api/budget/distribute?year=${selectedYear}&month=${month}`, {
          method: 'POST',
        })
        if (response.ok) {
          const result = await response.json()
          totalDays += result.days_distributed || 0
        }
      }
      setDistributeStatus(`Distributed ${totalDays} days successfully`)
      queryClient.invalidateQueries({ queryKey: ['daily-budgets'] })
    } catch (err) {
      setDistributeStatus('Failed to distribute budgets')
    } finally {
      setDistributing(false)
      setTimeout(() => setDistributeStatus(null), 5000)
    }
  }

  // Distribute single month
  const handleDistributeMonth = async (month: number) => {
    setDistributing(true)
    try {
      const response = await fetch(`/forecasting/api/budget/distribute?year=${selectedYear}&month=${month}`, {
        method: 'POST',
      })
      if (response.ok) {
        queryClient.invalidateQueries({ queryKey: ['daily-budgets'] })
        setSelectedMonth(month)
      }
    } catch (err) {
      console.error('Failed to distribute budget', err)
    } finally {
      setDistributing(false)
    }
  }

  // Organize monthly budgets by month
  const budgetsByMonth: Record<number, Record<string, number>> = {}
  monthlyBudgets?.forEach(b => {
    if (!budgetsByMonth[b.month]) budgetsByMonth[b.month] = {}
    budgetsByMonth[b.month][b.budget_type] = b.budget_value
  })

  // Organize daily budgets by date
  const dailyByDate: Record<string, Record<string, number>> = {}
  let dailyTotals = { net_accom: 0, net_dry: 0, net_wet: 0 }
  dailyBudgets?.forEach(d => {
    if (!dailyByDate[d.date]) dailyByDate[d.date] = {}
    dailyByDate[d.date][d.budget_type] = d.budget_value
    if (d.budget_type in dailyTotals) {
      dailyTotals[d.budget_type as keyof typeof dailyTotals] += d.budget_value
    }
  })

  // Generate year options
  const currentYear = new Date().getFullYear()
  const yearOptions = [currentYear - 1, currentYear, currentYear + 1, currentYear + 2]

  // Format currency
  const formatCurrency = (value: number | undefined) => {
    if (value === undefined || value === null) return '-'
    return `£${value.toLocaleString('en-GB', { minimumFractionDigits: 0, maximumFractionDigits: 0 })}`
  }

  return (
    <div style={styles.section}>
      <h2 style={styles.sectionTitle}>Budget Management</h2>
      <p style={styles.hint}>
        Upload budget spreadsheets from FD and distribute to daily values for forecast comparison.
      </p>

      {/* Upload Section */}
      <div style={styles.subsection}>
        <h3 style={styles.subsectionTitle}>Upload Budget Spreadsheet</h3>
        <p style={styles.hint}>
          Upload a CSV or Excel file with format: Row labels (accom, dry, wet) in first column, month headers (mm/yy) across top.
        </p>

        <div
          style={{
            ...budgetStyles.dropZone,
            ...(dragOver ? budgetStyles.dropZoneActive : {})
          }}
          onDrop={handleDrop}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
        >
          <input
            type="file"
            accept=".csv,.xlsx,.xls"
            onChange={handleFileInput}
            style={budgetStyles.fileInput}
            id="budget-file-input"
          />
          <label htmlFor="budget-file-input" style={budgetStyles.dropZoneLabel}>
            {uploading ? 'Uploading...' : 'Drag & drop CSV or Excel file here, or click to browse'}
          </label>
        </div>

        <div style={styles.buttonRow}>
          <button onClick={handleDownloadTemplate} style={buttonStyle('outline')}>
            Download Template
          </button>
        </div>

        {uploadResult && (
          <div style={{
            ...styles.statusMessage,
            background: uploadResult.status === 'success' ? colors.successBg : colors.errorBg,
            color: uploadResult.status === 'success' ? colors.success : colors.error,
            marginTop: spacing.md
          }}>
            {uploadResult.status === 'success' ? (
              <>
                <strong>Upload successful!</strong> {uploadResult.records_created} created, {uploadResult.records_updated} updated
              </>
            ) : (
              <>
                <strong>Upload failed:</strong> {uploadResult.errors?.join(', ')}
              </>
            )}
          </div>
        )}
      </div>

      <div style={styles.divider} />

      {/* Monthly Budgets Table */}
      <div style={styles.subsection}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: spacing.md }}>
          <h3 style={{ ...styles.subsectionTitle, margin: 0 }}>Monthly Budgets</h3>
          <select
            value={selectedYear}
            onChange={(e) => setSelectedYear(Number(e.target.value))}
            style={budgetStyles.yearSelect}
          >
            {yearOptions.map(y => (
              <option key={y} value={y}>{y}</option>
            ))}
          </select>
        </div>

        {loadingMonthly ? (
          <div style={styles.loading}>Loading budgets...</div>
        ) : (
          <>
            <div style={budgetStyles.tableContainer}>
              <table style={budgetStyles.table}>
                <thead>
                  <tr>
                    <th style={budgetStyles.th}>Month</th>
                    <th style={budgetStyles.thRight}>Accommodation</th>
                    <th style={budgetStyles.thRight}>Dry</th>
                    <th style={budgetStyles.thRight}>Wet</th>
                    <th style={budgetStyles.thCenter}>Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {MONTH_NAMES.map((name, idx) => {
                    const month = idx + 1
                    const data = budgetsByMonth[month] || {}
                    const hasData = Object.keys(data).length > 0
                    return (
                      <tr key={month} style={budgetStyles.tr}>
                        <td style={budgetStyles.td}>{name}</td>
                        <td style={budgetStyles.tdRight}>{formatCurrency(data.net_accom)}</td>
                        <td style={budgetStyles.tdRight}>{formatCurrency(data.net_dry)}</td>
                        <td style={budgetStyles.tdRight}>{formatCurrency(data.net_wet)}</td>
                        <td style={budgetStyles.tdCenter}>
                          {hasData && (
                            <button
                              onClick={() => {
                                handleDistributeMonth(month)
                              }}
                              style={buttonStyle('ghost')}
                              disabled={distributing}
                            >
                              View Daily
                            </button>
                          )}
                        </td>
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </div>

            <div style={{ ...styles.buttonRow, marginTop: spacing.md }}>
              <button
                onClick={handleDistributeAll}
                disabled={distributing || !monthlyBudgets?.length}
                style={buttonStyle('primary')}
              >
                {distributing ? 'Distributing...' : 'Distribute All to Daily'}
              </button>
              {distributeStatus && (
                <span style={{
                  color: distributeStatus.includes('Failed') ? colors.error : colors.success,
                  fontSize: typography.sm,
                  marginLeft: spacing.md
                }}>
                  {distributeStatus}
                </span>
              )}
            </div>
          </>
        )}
      </div>

      {/* Daily Distribution View */}
      {selectedMonth !== null && (
        <>
          <div style={styles.divider} />

          <div style={styles.subsection}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: spacing.md }}>
              <h3 style={{ ...styles.subsectionTitle, margin: 0 }}>
                Daily Distribution - {MONTH_NAMES[selectedMonth - 1]} {selectedYear}
              </h3>
              <button
                onClick={() => setSelectedMonth(null)}
                style={buttonStyle('ghost')}
              >
                Close
              </button>
            </div>

            {loadingDaily ? (
              <div style={styles.loading}>Loading daily budgets...</div>
            ) : dailyBudgets && dailyBudgets.length > 0 ? (
              <div style={budgetStyles.tableContainer}>
                <table style={budgetStyles.table}>
                  <thead>
                    <tr>
                      <th style={budgetStyles.th}>Date</th>
                      <th style={budgetStyles.thRight}>Accommodation</th>
                      <th style={budgetStyles.thRight}>Dry</th>
                      <th style={budgetStyles.thRight}>Wet</th>
                    </tr>
                  </thead>
                  <tbody>
                    {Object.keys(dailyByDate).sort().map(dateStr => {
                      const data = dailyByDate[dateStr]
                      const date = new Date(dateStr)
                      const dayName = date.toLocaleDateString('en-GB', { weekday: 'short' })
                      const dayNum = date.getDate()
                      return (
                        <tr key={dateStr} style={budgetStyles.tr}>
                          <td style={budgetStyles.td}>{dayName} {dayNum}</td>
                          <td style={budgetStyles.tdRight}>{formatCurrency(data.net_accom)}</td>
                          <td style={budgetStyles.tdRight}>{formatCurrency(data.net_dry)}</td>
                          <td style={budgetStyles.tdRight}>{formatCurrency(data.net_wet)}</td>
                        </tr>
                      )
                    })}
                    <tr style={budgetStyles.trTotal}>
                      <td style={{ ...budgetStyles.td, fontWeight: typography.semibold }}>Total</td>
                      <td style={{ ...budgetStyles.tdRight, fontWeight: typography.semibold }}>{formatCurrency(dailyTotals.net_accom)}</td>
                      <td style={{ ...budgetStyles.tdRight, fontWeight: typography.semibold }}>{formatCurrency(dailyTotals.net_dry)}</td>
                      <td style={{ ...budgetStyles.tdRight, fontWeight: typography.semibold }}>{formatCurrency(dailyTotals.net_wet)}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            ) : (
              <p style={styles.hint}>No daily budgets found. Click "Distribute All to Daily" to generate.</p>
            )}
          </div>
        </>
      )}
    </div>
  )
}

// ============================================
// TAX RATES PAGE
// ============================================

interface TaxRate {
  id: number
  tax_type: string
  rate: number
  effective_from: string
  created_at: string | null
}

const TaxRatesPage: React.FC = () => {
  const queryClient = useQueryClient()
  const [newRate, setNewRate] = useState('')
  const [newEffectiveFrom, setNewEffectiveFrom] = useState('')
  const [addingRate, setAddingRate] = useState(false)
  const [error, setError] = useState<string | null>(null)

  // Fetch all tax rates
  const { data: taxRates, isLoading } = useQuery<TaxRate[]>({
    queryKey: ['tax-rates'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/config/tax-rates')
      if (!response.ok) return []
      return response.json()
    },
  })

  // Group rates by type
  const ratesByType = (taxRates || []).reduce((acc, rate) => {
    if (!acc[rate.tax_type]) acc[rate.tax_type] = []
    acc[rate.tax_type].push(rate)
    return acc
  }, {} as Record<string, TaxRate[]>)

  const handleAddRate = async () => {
    if (!newRate || !newEffectiveFrom) {
      setError('Please enter both rate and effective date')
      return
    }

    const rateValue = parseFloat(newRate) / 100 // Convert percentage to decimal
    if (isNaN(rateValue) || rateValue < 0 || rateValue > 1) {
      setError('Rate must be a valid percentage between 0 and 100')
      return
    }

    setAddingRate(true)
    setError(null)

    try {
      const response = await fetch('/forecasting/api/config/tax-rates', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          tax_type: 'accommodation_vat',
          rate: rateValue,
          effective_from: newEffectiveFrom
        })
      })

      if (response.ok) {
        queryClient.invalidateQueries({ queryKey: ['tax-rates'] })
        setNewRate('')
        setNewEffectiveFrom('')
      } else {
        const data = await response.json()
        setError(data.detail || 'Failed to add tax rate')
      }
    } catch {
      setError('Failed to add tax rate')
    } finally {
      setAddingRate(false)
    }
  }

  const handleDeleteRate = async (id: number) => {
    if (!confirm('Are you sure you want to delete this tax rate?')) return

    try {
      const response = await fetch(`/forecasting/api/config/tax-rates/${id}`, {
        method: 'DELETE',
      })

      if (response.ok) {
        queryClient.invalidateQueries({ queryKey: ['tax-rates'] })
      }
    } catch {
      // Silent fail
    }
  }

  const formatDate = (dateStr: string) => {
    const date = new Date(dateStr)
    return date.toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })
  }

  return (
    <div>
      <h2 style={styles.pageTitle}>Tax Rates</h2>
      <p style={styles.hint}>
        Configure tax rates with effective dates. The most recent rate before a given date will be used for calculations.
        For example, if VAT changes from 20% to 22% on 1st April 2026, add a new entry with that date.
      </p>

      {/* Add New Rate Form */}
      <div style={taxRateStyles.addForm}>
        <h3 style={styles.sectionTitle}>Add Accommodation VAT Rate</h3>
        <div style={taxRateStyles.formRow}>
          <div style={taxRateStyles.inputGroup}>
            <label style={taxRateStyles.label}>Rate (%)</label>
            <input
              type="number"
              step="0.1"
              min="0"
              max="100"
              value={newRate}
              onChange={(e) => setNewRate(e.target.value)}
              placeholder="e.g. 20"
              style={taxRateStyles.input}
            />
          </div>
          <div style={taxRateStyles.inputGroup}>
            <label style={taxRateStyles.label}>Effective From</label>
            <input
              type="date"
              value={newEffectiveFrom}
              onChange={(e) => setNewEffectiveFrom(e.target.value)}
              style={taxRateStyles.input}
            />
          </div>
          <button
            onClick={handleAddRate}
            disabled={addingRate}
            style={mergeStyles(buttonStyle('primary'), { alignSelf: 'flex-end' })}
          >
            {addingRate ? 'Adding...' : 'Add Rate'}
          </button>
        </div>
        {error && <p style={taxRateStyles.error}>{error}</p>}
      </div>

      {/* Existing Rates */}
      <div style={taxRateStyles.ratesSection}>
        <h3 style={styles.sectionTitle}>Current Tax Rates</h3>

        {isLoading ? (
          <div style={styles.loading}>Loading tax rates...</div>
        ) : Object.keys(ratesByType).length === 0 ? (
          <p style={styles.hint}>No tax rates configured. Add your first rate above.</p>
        ) : (
          Object.entries(ratesByType).map(([taxType, rates]) => (
            <div key={taxType} style={taxRateStyles.rateGroup}>
              <h4 style={taxRateStyles.rateGroupTitle}>
                {taxType === 'accommodation_vat' ? 'Accommodation VAT' : taxType}
              </h4>
              <table style={budgetStyles.table}>
                <thead>
                  <tr>
                    <th style={budgetStyles.th}>Effective From</th>
                    <th style={budgetStyles.thRight}>Rate</th>
                    <th style={budgetStyles.thCenter}>Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {rates.map((rate, idx) => (
                    <tr key={rate.id} style={budgetStyles.tr}>
                      <td style={budgetStyles.td}>
                        {formatDate(rate.effective_from)}
                        {idx === 0 && (
                          <span style={taxRateStyles.currentBadge}>Current</span>
                        )}
                      </td>
                      <td style={budgetStyles.tdRight}>{(rate.rate * 100).toFixed(1)}%</td>
                      <td style={budgetStyles.tdCenter}>
                        <button
                          onClick={() => handleDeleteRate(rate.id)}
                          style={mergeStyles(buttonStyle('outline'), taxRateStyles.deleteBtn)}
                        >
                          Delete
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          ))
        )}
      </div>
    </div>
  )
}

const taxRateStyles: Record<string, React.CSSProperties> = {
  addForm: {
    background: colors.surface,
    padding: spacing.lg,
    borderRadius: radius.lg,
    marginBottom: spacing.xl,
    border: `1px solid ${colors.border}`,
  },
  formRow: {
    display: 'flex',
    gap: spacing.md,
    alignItems: 'flex-end',
    flexWrap: 'wrap',
  },
  inputGroup: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
  },
  label: {
    fontSize: typography.sm,
    color: colors.textSecondary,
    fontWeight: typography.medium,
  },
  input: {
    padding: `${spacing.sm} ${spacing.md}`,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.base,
    background: colors.background,
    minWidth: '150px',
  },
  error: {
    color: colors.error,
    fontSize: typography.sm,
    marginTop: spacing.sm,
  },
  ratesSection: {
    marginTop: spacing.xl,
  },
  rateGroup: {
    marginBottom: spacing.lg,
  },
  rateGroupTitle: {
    fontSize: typography.base,
    fontWeight: typography.semibold,
    color: colors.text,
    marginBottom: spacing.sm,
  },
  currentBadge: {
    display: 'inline-block',
    marginLeft: spacing.sm,
    padding: `2px ${spacing.xs}`,
    fontSize: typography.xs,
    background: colors.success,
    color: 'white',
    borderRadius: radius.sm,
  },
  deleteBtn: {
    padding: `${spacing.xs} ${spacing.sm}`,
    fontSize: typography.xs,
  },
}

const budgetStyles: Record<string, React.CSSProperties> = {
  dropZone: {
    border: `2px dashed ${colors.border}`,
    borderRadius: radius.lg,
    padding: spacing.xl,
    textAlign: 'center',
    cursor: 'pointer',
    transition: 'all 0.2s ease',
    background: colors.background,
  },
  dropZoneActive: {
    borderColor: colors.accent,
    background: `${colors.accent}15`,
  },
  dropZoneLabel: {
    display: 'block',
    color: colors.textSecondary,
    fontSize: typography.sm,
    cursor: 'pointer',
  },
  fileInput: {
    display: 'none',
  },
  yearSelect: {
    padding: `${spacing.xs} ${spacing.sm}`,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.base,
    background: colors.surface,
    cursor: 'pointer',
  },
  tableContainer: {
    overflowX: 'auto',
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
  },
  table: {
    width: '100%',
    borderCollapse: 'collapse',
    fontSize: typography.sm,
  },
  th: {
    padding: spacing.sm,
    textAlign: 'left',
    background: colors.background,
    borderBottom: `1px solid ${colors.border}`,
    fontWeight: typography.medium,
    color: colors.textSecondary,
  },
  thRight: {
    padding: spacing.sm,
    textAlign: 'right',
    background: colors.background,
    borderBottom: `1px solid ${colors.border}`,
    fontWeight: typography.medium,
    color: colors.textSecondary,
  },
  thCenter: {
    padding: spacing.sm,
    textAlign: 'center',
    background: colors.background,
    borderBottom: `1px solid ${colors.border}`,
    fontWeight: typography.medium,
    color: colors.textSecondary,
  },
  tr: {
    borderBottom: `1px solid ${colors.borderLight}`,
  },
  trTotal: {
    background: colors.background,
    borderTop: `2px solid ${colors.border}`,
  },
  td: {
    padding: spacing.sm,
    color: colors.text,
  },
  tdRight: {
    padding: spacing.sm,
    textAlign: 'right',
    color: colors.text,
    fontFamily: 'monospace',
  },
  tdCenter: {
    padding: spacing.sm,
    textAlign: 'center',
  },
}

// ============================================
// BACKUP & RESTORE PAGE
// ============================================

interface BackupSettings {
  backup_frequency: string
  backup_retention_count: number
  backup_destination: string
  backup_time: string | null
  backup_last_run_at: string | null
  backup_last_status: string | null
}

interface BackupHistoryEntry {
  id: number
  backup_type: string
  status: string
  filename: string
  file_path: string
  file_size_bytes: number | null
  snapshot_count: number | null
  file_count: number | null
  started_at: string
  completed_at: string | null
  error_message: string | null
  created_by: string | null
}

const BackupPage: React.FC = () => {
  const queryClient = useQueryClient()
  const [backupMessage, setBackupMessage] = useState<string | null>(null)
  const [uploadDragActive, setUploadDragActive] = useState(false)
  const [restoreConfirmOpen, setRestoreConfirmOpen] = useState(false)
  const [restoreTarget, setRestoreTarget] = useState<File | number | null>(null)

  // State for settings form
  const [frequency, setFrequency] = useState('manual')
  const [retentionCount, setRetentionCount] = useState(7)
  const [backupTime, setBackupTime] = useState('02:00')

  // Fetch backup settings
  const { data: backupSettings } = useQuery<BackupSettings>({
    queryKey: ['backup-settings'],
    queryFn: async () => {
      const res = await fetch('/forecasting/api/backup/settings')
      if (!res.ok) throw new Error('Failed to fetch backup settings')
      return res.json()
    }
  })

  // Sync form state when backup settings load
  useEffect(() => {
    if (backupSettings) {
      setFrequency(backupSettings.backup_frequency)
      setRetentionCount(backupSettings.backup_retention_count)
      if (backupSettings.backup_time) setBackupTime(backupSettings.backup_time)
    }
  }, [backupSettings])

  // Fetch backup history
  const { data: backupHistory, refetch: refetchHistory } = useQuery({
    queryKey: ['backup-history'],
    queryFn: async () => {
      const res = await fetch('/forecasting/api/backup/history')
      if (!res.ok) throw new Error('Failed to fetch backup history')
      return res.json() as Promise<BackupHistoryEntry[]>
    }
  })

  // Save settings mutation
  const saveSettingsMutation = useMutation({
    mutationFn: async (updates: any) => {
      const res = await fetch('/forecasting/api/backup/settings', {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(updates)
      })
      if (!res.ok) throw new Error('Failed to save settings')
      return res.json()
    },
    onSuccess: () => {
      setBackupMessage('Settings saved successfully')
      queryClient.invalidateQueries({ queryKey: ['backup-settings'] })
      setTimeout(() => setBackupMessage(null), 3000)
    },
    onError: (error: any) => {
      setBackupMessage(`Error: ${error.message}`)
      setTimeout(() => setBackupMessage(null), 5000)
    }
  })

  // Create backup mutation
  const createBackupMutation = useMutation({
    mutationFn: async () => {
      const res = await fetch('/forecasting/api/backup/create', {
        method: 'POST',
      })
      if (!res.ok) throw new Error('Failed to create backup')
      return res.json()
    },
    onSuccess: (data) => {
      setBackupMessage(`Backup created: ${data.message}`)
      refetchHistory()
      setTimeout(() => setBackupMessage(null), 5000)
    },
    onError: (error: any) => {
      setBackupMessage(`Error: ${error.message}`)
      setTimeout(() => setBackupMessage(null), 5000)
    }
  })

  // Upload and restore mutation
  const uploadRestoreMutation = useMutation({
    mutationFn: async (file: File) => {
      const formData = new FormData()
      formData.append('file', file)
      const res = await fetch('/forecasting/api/backup/upload-restore', {
        method: 'POST',
        body: formData
      })
      if (!res.ok) throw new Error('Failed to restore backup')
      return res.json()
    },
    onSuccess: () => {
      setBackupMessage('Restore successful! Reloading...')
      setTimeout(() => {
        window.location.reload()
      }, 2000)
    },
    onError: (error: any) => {
      setBackupMessage(`Error: ${error.message}`)
      setTimeout(() => setBackupMessage(null), 5000)
    }
  })

  // Restore from history mutation
  const restoreBackupMutation = useMutation({
    mutationFn: async (backupId: number) => {
      const res = await fetch(`/forecasting/api/backup/${backupId}/restore`, {
        method: 'POST',
      })
      if (!res.ok) throw new Error('Failed to restore backup')
      return res.json()
    },
    onSuccess: () => {
      setBackupMessage('Restore successful! Reloading...')
      setTimeout(() => {
        window.location.reload()
      }, 2000)
    },
    onError: (error: any) => {
      setBackupMessage(`Error: ${error.message}`)
      setTimeout(() => setBackupMessage(null), 5000)
    }
  })

  // Delete backup mutation
  const deleteBackupMutation = useMutation({
    mutationFn: async (backupId: number) => {
      const res = await fetch(`/forecasting/api/backup/${backupId}`, {
        method: 'DELETE',
      })
      if (!res.ok) throw new Error('Failed to delete backup')
      return res.json()
    },
    onSuccess: () => {
      setBackupMessage('Backup deleted successfully')
      refetchHistory()
      setTimeout(() => setBackupMessage(null), 3000)
    },
    onError: (error: any) => {
      setBackupMessage(`Error: ${error.message}`)
      setTimeout(() => setBackupMessage(null), 5000)
    }
  })

  const handleSaveSettings = () => {
    saveSettingsMutation.mutate({
      frequency,
      retention_count: retentionCount,
      time: backupTime
    })
  }

  const handleCreateBackup = () => {
    createBackupMutation.mutate()
  }

  const handleFileUpload = (file: File) => {
    if (!file.name.endsWith('.zip')) {
      setBackupMessage('Error: Only ZIP files are accepted')
      setTimeout(() => setBackupMessage(null), 3000)
      return
    }
    setRestoreTarget(file)
    setRestoreConfirmOpen(true)
  }

  const handleDragEnter = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setUploadDragActive(true)
  }

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setUploadDragActive(false)
  }

  const handleDragOver = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
  }

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setUploadDragActive(false)

    const files = e.dataTransfer.files
    if (files && files[0]) {
      handleFileUpload(files[0])
    }
  }

  const handleDownload = async (backup: BackupHistoryEntry) => {
    try {
      const res = await fetch(`/forecasting/api/backup/${backup.id}/download`)
      if (!res.ok) throw new Error('Download failed')
      const blob = await res.blob()
      const url = window.URL.createObjectURL(blob)
      const a = document.createElement('a')
      a.href = url
      a.download = backup.filename
      document.body.appendChild(a)
      a.click()
      window.URL.revokeObjectURL(url)
      document.body.removeChild(a)
    } catch (err) {
      setBackupMessage('Error: Download failed')
      setTimeout(() => setBackupMessage(null), 3000)
    }
  }

  const formatFileSize = (bytes: number | null): string => {
    if (!bytes) return '-'
    const mb = bytes / 1024 / 1024
    if (mb < 1) return `${(bytes / 1024).toFixed(1)} KB`
    if (mb < 1024) return `${mb.toFixed(1)} MB`
    return `${(mb / 1024).toFixed(1)} GB`
  }

  const formatDate = (dateStr: string | null): string => {
    if (!dateStr) return '-'
    return new Date(dateStr).toLocaleString()
  }

  const getStatusBadge = (status: string) => {
    const colors = {
      success: { bg: '#d4edda', color: '#155724', border: '#c3e6cb' },
      running: { bg: '#fff3cd', color: '#856404', border: '#ffeaa7' },
      failed: { bg: '#f8d7da', color: '#721c24', border: '#f5c6cb' }
    }
    const style = colors[status as keyof typeof colors] || colors.failed
    return (
      <span
        style={{
          padding: '0.25rem 0.5rem',
          borderRadius: radius.sm,
          fontSize: typography.xs,
          fontWeight: typography.semibold,
          background: style.bg,
          color: style.color,
          border: `1px solid ${style.border}`,
          textTransform: 'uppercase'
        }}
      >
        {status}
      </span>
    )
  }

  const getTypeBadge = (type: string) => {
    const isManual = type === 'manual'
    return (
      <span
        style={{
          padding: '0.25rem 0.5rem',
          borderRadius: radius.sm,
          fontSize: typography.xs,
          fontWeight: typography.medium,
          background: isManual ? '#e7f5ff' : '#f3f4f6',
          color: isManual ? '#1971c2' : '#4b5563',
          border: `1px solid ${isManual ? '#a5d8ff' : '#d1d5db'}`
        }}
      >
        {type}
      </span>
    )
  }

  const isOperationInProgress =
    createBackupMutation.isPending ||
    uploadRestoreMutation.isPending ||
    restoreBackupMutation.isPending ||
    deleteBackupMutation.isPending

  return (
    <div style={styles.section}>
      <div style={styles.sectionHeader}>
        <div>
          <h2 style={styles.sectionTitle}>Backup & Restore</h2>
          <p style={styles.hint}>
            Create and manage database backups for disaster recovery
          </p>
        </div>
      </div>

      {backupMessage && (
        <div
          style={{
            padding: spacing.md,
            marginBottom: spacing.lg,
            borderRadius: radius.md,
            background: backupMessage.startsWith('Error')
              ? colors.errorBg
              : '#d4edda',
            color: backupMessage.startsWith('Error') ? colors.error : '#155724',
            border: `1px solid ${backupMessage.startsWith('Error') ? colors.error : '#c3e6cb'}`,
            fontSize: typography.sm
          }}
        >
          {backupMessage}
        </div>
      )}

      {/* Backup Settings */}
      <div style={styles.subsection}>
        <h3 style={styles.subsectionTitle}>Backup Settings</h3>

        <div style={styles.formGroup}>
          <label style={styles.label}>Frequency</label>
          <select
            value={frequency}
            onChange={(e) => setFrequency(e.target.value)}
            style={styles.select}
            disabled={isOperationInProgress}
          >
            <option value="manual">Manual Only</option>
            <option value="daily">Daily</option>
            <option value="weekly">Weekly</option>
            <option value="monthly">Monthly</option>
          </select>
        </div>

        {frequency !== 'manual' && (
          <div style={styles.formGroup}>
            <label style={styles.label}>Backup Time</label>
            <input
              type="time"
              value={backupTime}
              onChange={(e) => setBackupTime(e.target.value)}
              style={styles.input}
              disabled={isOperationInProgress}
            />
          </div>
        )}

        <div style={styles.formGroup}>
          <label style={styles.label}>Retention Count</label>
          <input
            type="number"
            min="1"
            max="30"
            value={retentionCount}
            onChange={(e) => setRetentionCount(parseInt(e.target.value))}
            style={styles.input}
            disabled={isOperationInProgress}
          />
          <p style={styles.hint}>Number of backups to keep (older ones will be deleted)</p>
        </div>

        {backupSettings?.backup_last_run_at && (
          <div style={{ marginTop: spacing.md }}>
            <p style={{ ...styles.label, marginBottom: spacing.xs }}>Last Backup:</p>
            <p style={styles.hint}>
              {formatDate(backupSettings.backup_last_run_at)} -{' '}
              {getStatusBadge(backupSettings.backup_last_status || 'unknown')}
            </p>
          </div>
        )}

        <button
          onClick={handleSaveSettings}
          style={mergeStyles(
            buttonStyle(),
            isOperationInProgress ? { opacity: 0.6, cursor: 'not-allowed' } : {}
          )}
          disabled={isOperationInProgress}
        >
          {saveSettingsMutation.isPending ? 'Saving...' : 'Save Settings'}
        </button>
      </div>

      <div style={styles.divider} />

      {/* Manual Backup */}
      <div style={styles.subsection}>
        <h3 style={styles.subsectionTitle}>Create Backup</h3>
        <p style={styles.hint}>
          Create a full backup of your database and files. This may take several minutes.
        </p>
        <button
          onClick={handleCreateBackup}
          style={mergeStyles(
            buttonStyle(),
            { background: colors.success },
            isOperationInProgress ? { opacity: 0.6, cursor: 'not-allowed' } : {}
          )}
          disabled={isOperationInProgress}
        >
          {createBackupMutation.isPending ? 'Creating Backup...' : 'Create Backup Now'}
        </button>
      </div>

      <div style={styles.divider} />

      {/* Restore from File */}
      <div style={styles.subsection}>
        <h3 style={styles.subsectionTitle}>Restore from File</h3>
        <p style={styles.hint}>Upload a backup ZIP file to restore your data.</p>

        <div
          onDragEnter={handleDragEnter}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          onDrop={handleDrop}
          style={{
            border: `2px dashed ${uploadDragActive ? colors.primary : colors.border}`,
            borderRadius: radius.md,
            padding: spacing.xl,
            textAlign: 'center',
            background: uploadDragActive ? '#fff5f7' : colors.surfaceHover,
            cursor: 'pointer',
            transition: 'all 0.2s'
          }}
          onClick={() => document.getElementById('backup-upload-input')?.click()}
        >
          <div style={{ fontSize: '3rem', marginBottom: spacing.sm }}>📦</div>
          <p style={{ margin: `${spacing.sm} 0`, fontWeight: typography.medium }}>
            {uploadDragActive ? 'Drop backup file here' : 'Drag and drop backup file here'}
          </p>
          <p style={{ margin: `${spacing.sm} 0`, fontSize: typography.sm, color: colors.textMuted }}>
            or{' '}
            <span style={{ color: colors.primary, textDecoration: 'underline' }}>
              click to browse
            </span>
          </p>
          <p style={{ margin: `${spacing.sm} 0`, fontSize: typography.xs, color: colors.textMuted }}>
            Only .zip backup files are accepted
          </p>
          <input
            type="file"
            accept=".zip"
            onChange={(e) => {
              const file = e.target.files?.[0]
              if (file) {
                handleFileUpload(file)
                e.target.value = ''
              }
            }}
            style={{ display: 'none' }}
            id="backup-upload-input"
          />
        </div>
      </div>

      <div style={styles.divider} />

      {/* Backup History */}
      <div style={styles.subsection}>
        <h3 style={styles.subsectionTitle}>Backup History</h3>

        {backupHistory && backupHistory.length > 0 ? (
          <div style={{ overflowX: 'auto' }}>
            <table style={styles.table}>
              <thead>
                <tr>
                  <th style={styles.th}>Started</th>
                  <th style={styles.th}>Type</th>
                  <th style={styles.th}>Status</th>
                  <th style={styles.th}>Size</th>
                  <th style={styles.th}>Snapshots</th>
                  <th style={styles.th}>Files</th>
                  <th style={styles.th}>Created By</th>
                  <th style={styles.th}>Actions</th>
                </tr>
              </thead>
              <tbody>
                {backupHistory.map((backup) => (
                  <tr key={backup.id}>
                    <td style={styles.td}>{formatDate(backup.started_at)}</td>
                    <td style={styles.td}>{getTypeBadge(backup.backup_type)}</td>
                    <td style={styles.td}>{getStatusBadge(backup.status)}</td>
                    <td style={styles.td}>{formatFileSize(backup.file_size_bytes)}</td>
                    <td style={styles.td}>
                      {backup.snapshot_count !== null ? backup.snapshot_count.toLocaleString() : '-'}
                    </td>
                    <td style={styles.td}>
                      {backup.file_count !== null ? backup.file_count.toLocaleString() : '-'}
                    </td>
                    <td style={styles.td}>
                      {backup.created_by || (
                        <span style={{ fontStyle: 'italic', color: colors.textMuted }}>scheduled</span>
                      )}
                    </td>
                    <td style={styles.td}>
                      <div style={{ display: 'flex', gap: spacing.xs }}>
                        <button
                          onClick={() => handleDownload(backup)}
                          disabled={backup.status !== 'success'}
                          style={mergeStyles(
                            buttonStyle('secondary'),
                            {
                              padding: `${spacing.xs} ${spacing.sm}`,
                              fontSize: typography.sm
                            },
                            backup.status !== 'success' ? { opacity: 0.5, cursor: 'not-allowed' } : {}
                          )}
                        >
                          Download
                        </button>
                        <button
                          onClick={() => {
                            setRestoreTarget(backup.id)
                            setRestoreConfirmOpen(true)
                          }}
                          disabled={backup.status !== 'success' || isOperationInProgress}
                          style={mergeStyles(
                            buttonStyle('secondary'),
                            {
                              padding: `${spacing.xs} ${spacing.sm}`,
                              fontSize: typography.sm,
                              background: '#f59e0b',
                              color: colors.textLight
                            },
                            (backup.status !== 'success' || isOperationInProgress) ? {
                              opacity: 0.5,
                              cursor: 'not-allowed'
                            } : {}
                          )}
                        >
                          Restore
                        </button>
                        <button
                          onClick={() => {
                            if (confirm(`Delete backup "${backup.filename}"? This cannot be undone.`)) {
                              deleteBackupMutation.mutate(backup.id)
                            }
                          }}
                          disabled={isOperationInProgress}
                          style={mergeStyles(
                            buttonStyle('secondary'),
                            {
                              padding: `${spacing.xs} ${spacing.sm}`,
                              fontSize: typography.sm,
                              background: colors.error,
                              color: colors.textLight
                            },
                            isOperationInProgress ? { opacity: 0.5, cursor: 'not-allowed' } : {}
                          )}
                        >
                          Delete
                        </button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        ) : (
          <p style={styles.hint}>No backups yet. Create your first backup above.</p>
        )}
      </div>

      {/* Restore Confirmation Modal */}
      {restoreConfirmOpen && (
        <div
          style={styles.modal}
          onClick={(e) => {
            if (e.target === e.currentTarget) {
              setRestoreConfirmOpen(false)
              setRestoreTarget(null)
            }
          }}
        >
          <div style={{ ...styles.modalContent, maxWidth: '600px' }}>
            <h3 style={{ marginTop: 0, display: 'flex', alignItems: 'center', gap: spacing.sm }}>
              <span style={{ fontSize: '1.5rem' }}>⚠️</span>
              Confirm Backup Restore
            </h3>

            <div
              style={{
                padding: spacing.md,
                background: '#fff3cd',
                border: '1px solid #ffc107',
                borderRadius: radius.md,
                marginBottom: spacing.md
              }}
            >
              <strong style={{ color: '#856404' }}>Warning: Data Restore Operation</strong>
              <p style={{ margin: `${spacing.sm} 0 0 0`, fontSize: typography.sm, color: '#856404' }}>
                This operation will restore data from the backup file. Please review:
              </p>
            </div>

            <ul style={{ marginLeft: spacing.lg, marginBottom: spacing.lg, lineHeight: 1.8 }}>
              <li>
                <strong>Database:</strong> Full database restore (all current data will be replaced)
              </li>
              <li>
                <strong>Files:</strong> Missing files will be restored
              </li>
              <li>
                <strong>Existing files:</strong> Will NOT be overwritten
              </li>
              <li>
                <strong>After restore:</strong> You will need to log in again
              </li>
            </ul>

            <div style={{ display: 'flex', gap: spacing.md, justifyContent: 'flex-end' }}>
              <button
                onClick={() => {
                  setRestoreConfirmOpen(false)
                  setRestoreTarget(null)
                }}
                style={{ ...buttonStyle, background: colors.textMuted }}
              >
                Cancel
              </button>
              <button
                onClick={() => {
                  if (typeof restoreTarget === 'number') {
                    restoreBackupMutation.mutate(restoreTarget)
                  } else if (restoreTarget instanceof File) {
                    uploadRestoreMutation.mutate(restoreTarget)
                  }
                  setRestoreConfirmOpen(false)
                  setRestoreTarget(null)
                }}
                style={{ ...buttonStyle, background: colors.error }}
                disabled={isOperationInProgress}
              >
                {isOperationInProgress ? 'Restoring...' : 'Confirm Restore'}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

// ============================================
// FORECAST SNAPSHOTS PAGE
// ============================================

interface ForecastSnapshotSettings {
  enabled: boolean
  time: string
  models: string
  days_ahead: number
}

const ForecastSnapshotsPage: React.FC = () => {
  const queryClient = useQueryClient()
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle')
  const [testStatus, setTestStatus] = useState<'idle' | 'running' | 'success' | 'error'>('idle')
  const [testMessage, setTestMessage] = useState('')

  // Fetch settings
  const { data: settings, isLoading } = useQuery<ForecastSnapshotSettings>({
    queryKey: ['forecast-snapshot-settings'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/config/settings/forecast-snapshot')
      if (!response.ok) throw new Error('Failed to fetch settings')
      return response.json()
    },
  })

  const [formData, setFormData] = useState<ForecastSnapshotSettings>({
    enabled: false,
    time: '06:00',
    models: 'prophet,xgboost,catboost,blended',
    days_ahead: 90
  })

  // Update form when settings load
  React.useEffect(() => {
    if (settings) {
      setFormData(settings)
    }
  }, [settings])

  const handleSave = async () => {
    setSaveStatus('saving')
    try {
      const response = await fetch('/forecasting/api/config/settings/forecast-snapshot', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(formData)
      })

      if (response.ok) {
        setSaveStatus('success')
        queryClient.invalidateQueries({ queryKey: ['forecast-snapshot-settings'] })
      } else {
        setSaveStatus('error')
      }
    } catch {
      setSaveStatus('error')
    }

    setTimeout(() => setSaveStatus('idle'), 3000)
  }

  const handleTest = async () => {
    setTestStatus('running')
    setTestMessage('Running forecast snapshot...')

    try {
      const response = await fetch('/forecasting/api/config/settings/forecast-snapshot/test', {
        method: 'POST',
      })

      const data = await response.json()

      if (response.ok) {
        setTestStatus('success')
        setTestMessage(data.message || 'Forecast snapshot completed successfully')
      } else {
        setTestStatus('error')
        setTestMessage(data.detail || 'Forecast snapshot failed')
      }
    } catch (err) {
      setTestStatus('error')
      setTestMessage('Failed to run forecast snapshot')
    }

    setTimeout(() => {
      setTestStatus('idle')
      setTestMessage('')
    }, 8000)
  }

  if (isLoading) {
    return <div style={styles.loading}>Loading settings...</div>
  }

  return (
    <div>
      <div style={styles.header}>
        <h1 style={styles.title}>Forecast Snapshot Automation</h1>
        <p style={styles.hint}>
          Automatically create weekly forecast snapshots for all non-COVID metrics
        </p>
      </div>

      <div style={styles.section}>
        <h3 style={styles.sectionTitle}>Automation Settings</h3>

        {/* Enabled Toggle */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>
              <input
                type="checkbox"
                checked={formData.enabled}
                onChange={(e) => setFormData({ ...formData, enabled: e.target.checked })}
              />
              <span style={{ marginLeft: spacing.sm }}>Enable weekly forecast snapshots</span>
            </label>
            <p style={styles.hint}>
              When enabled, forecast snapshots will be created automatically every Monday
            </p>
          </div>
        </div>

        {/* Time */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>Snapshot Time</label>
            <input
              type="time"
              value={formData.time}
              onChange={(e) => setFormData({ ...formData, time: e.target.value })}
              style={styles.input}
              disabled={!formData.enabled}
            />
            <p style={styles.hint}>
              Time to run the snapshot (default: 06:00)
            </p>
          </div>
        </div>

        {/* Models */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>Models</label>
            <input
              type="text"
              value={formData.models}
              onChange={(e) => setFormData({ ...formData, models: e.target.value })}
              style={styles.input}
              disabled={!formData.enabled}
              placeholder="prophet,xgboost,catboost,blended"
            />
            <p style={styles.hint}>
              Comma-separated list of models to run (prophet, xgboost, catboost, pickup, blended). Blended averages the other models.
            </p>
          </div>
        </div>

        {/* Days Ahead */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>Forecast Horizon (days)</label>
            <input
              type="number"
              value={formData.days_ahead}
              onChange={(e) => setFormData({ ...formData, days_ahead: parseInt(e.target.value) || 90 })}
              style={styles.input}
              disabled={!formData.enabled}
              min="1"
              max="365"
            />
            <p style={styles.hint}>
              Number of days ahead to forecast (default: 90)
            </p>
          </div>
        </div>

        {/* Save Button */}
        <div style={styles.actions}>
          <button
            onClick={handleSave}
            style={{
              ...buttonStyle(),
              ...(saveStatus === 'saving' ? { opacity: 0.6, cursor: 'wait' } : {})
            }}
            disabled={saveStatus === 'saving'}
          >
            {saveStatus === 'saving' ? 'Saving...' : saveStatus === 'success' ? '✓ Saved' : 'Save Settings'}
          </button>

          <button
            onClick={handleTest}
            style={{
              ...buttonStyle('secondary'),
              ...(testStatus === 'running' || !formData.enabled ? { opacity: 0.6 } : {})
            }}
            disabled={testStatus === 'running' || !formData.enabled}
          >
            {testStatus === 'running' ? 'Running...' : 'Test Now'}
          </button>
        </div>

        {testMessage && (
          <div style={{
            padding: spacing.md,
            borderRadius: radius.md,
            marginTop: spacing.md,
            background: testStatus === 'error' ? colors.errorBg : colors.successBg,
            color: testStatus === 'error' ? colors.error : colors.success,
          }}>
            {testMessage}
          </div>
        )}
      </div>

      <div style={styles.infoBox}>
        <h4 style={{ margin: `0 0 ${spacing.sm} 0`, fontSize: typography.base }}>How it works</h4>
        <ul style={{ margin: 0, paddingLeft: spacing.lg, fontSize: typography.sm, lineHeight: 1.6 }}>
          <li>Forecast snapshots are created every Monday at the specified time</li>
          <li>Snapshots capture forecasts for all active metrics using the configured models</li>
          <li>The forecast horizon determines how many days ahead to predict</li>
          <li>Snapshots use standard models (without "_postcovid" suffix) that include all historical data</li>
          <li>Forecasts are stored in the database for historical comparison and trend analysis</li>
        </ul>
      </div>
    </div>
  )
}

// ============================================
// API KEYS PAGE
// ============================================

interface ApiKey {
  id: number
  key_prefix: string
  name: string
  is_active: boolean
  created_at: string
  last_used_at: string | null
  created_by: string | null
}

interface CreateApiKeyResponse {
  id: number
  key: string
  key_prefix: string
  name: string
}

const ApiKeysPage: React.FC = () => {
  const queryClient = useQueryClient()
  const [showCreateForm, setShowCreateForm] = useState(false)
  const [newKeyName, setNewKeyName] = useState('')
  const [createdKey, setCreatedKey] = useState<CreateApiKeyResponse | null>(null)
  const [showKeyModal, setShowKeyModal] = useState(false)
  const [error, setError] = useState('')
  const [copied, setCopied] = useState(false)

  const { data: apiKeys, isLoading } = useQuery<ApiKey[]>({
    queryKey: ['api-keys'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/config/api-keys')
      if (!response.ok) throw new Error('Failed to fetch API keys')
      return response.json()
    },
  })

  const createMutation = useMutation({
    mutationFn: async (name: string) => {
      const response = await fetch('/forecasting/api/config/api-keys', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ name })
      })
      if (!response.ok) {
        const errData = await response.json()
        throw new Error(errData.detail || 'Failed to create API key')
      }
      return response.json()
    },
    onSuccess: (data: CreateApiKeyResponse) => {
      queryClient.invalidateQueries({ queryKey: ['api-keys'] })
      setCreatedKey(data)
      setShowKeyModal(true)
      setShowCreateForm(false)
      setNewKeyName('')
      setError('')
    },
    onError: (err: Error) => {
      setError(err.message)
    },
  })

  const revokeMutation = useMutation({
    mutationFn: async (keyId: number) => {
      const response = await fetch(`/forecasting/api/config/api-keys/${keyId}/revoke`, {
        method: 'POST',
      })
      if (!response.ok) throw new Error('Failed to revoke API key')
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['api-keys'] })
    },
  })

  const deleteMutation = useMutation({
    mutationFn: async (keyId: number) => {
      const response = await fetch(`/forecasting/api/config/api-keys/${keyId}`, {
        method: 'DELETE',
      })
      if (!response.ok) throw new Error('Failed to delete API key')
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['api-keys'] })
    },
  })

  const handleCreate = (e: React.FormEvent) => {
    e.preventDefault()
    if (!newKeyName.trim()) {
      setError('Please enter a name for the API key')
      return
    }
    createMutation.mutate(newKeyName.trim())
  }

  const handleRevoke = (key: ApiKey) => {
    if (confirm(`Revoke API key "${key.name}"? It will no longer work for API requests.`)) {
      revokeMutation.mutate(key.id)
    }
  }

  const handleDelete = (key: ApiKey) => {
    if (confirm(`Permanently delete API key "${key.name}"? This cannot be undone.`)) {
      deleteMutation.mutate(key.id)
    }
  }

  const handleCopyKey = async () => {
    if (createdKey) {
      await navigator.clipboard.writeText(createdKey.key)
      setCopied(true)
      setTimeout(() => setCopied(false), 2000)
    }
  }

  const closeKeyModal = () => {
    setShowKeyModal(false)
    setCreatedKey(null)
    setCopied(false)
  }

  const formatDate = (dateStr: string | null) => {
    if (!dateStr) return 'Never'
    return new Date(dateStr).toLocaleString()
  }

  return (
    <div style={styles.section}>
      <div style={styles.sectionHeader}>
        <div>
          <h2 style={styles.sectionTitle}>API Keys</h2>
          <p style={styles.hint}>Generate API keys for external applications to access forecast data.</p>
        </div>
        <button
          onClick={() => setShowCreateForm(!showCreateForm)}
          style={buttonStyle('primary')}
        >
          {showCreateForm ? 'Cancel' : 'Generate New Key'}
        </button>
      </div>

      {showCreateForm && (
        <div style={styles.addForm}>
          <form onSubmit={handleCreate}>
            {error && <div style={styles.error}>{error}</div>}
            <div style={styles.formRow}>
              <div style={styles.formField}>
                <label style={styles.label}>Key Name</label>
                <input
                  type="text"
                  value={newKeyName}
                  onChange={(e) => setNewKeyName(e.target.value)}
                  style={styles.input}
                  placeholder="e.g., Kitchen Flash App"
                  required
                />
              </div>
              <button
                type="submit"
                style={mergeStyles(buttonStyle('secondary'), { alignSelf: 'flex-end' })}
                disabled={createMutation.isPending}
              >
                {createMutation.isPending ? 'Generating...' : 'Generate'}
              </button>
            </div>
          </form>
        </div>
      )}

      {isLoading ? (
        <div style={styles.loading}>Loading API keys...</div>
      ) : apiKeys && apiKeys.length > 0 ? (
        <div style={styles.userList}>
          {apiKeys.map((key) => (
            <div key={key.id} style={styles.userCard}>
              <div style={styles.userInfo}>
                <div style={styles.userName}>
                  {key.name}
                  <span style={{
                    marginLeft: spacing.sm,
                    fontFamily: 'monospace',
                    fontSize: typography.sm,
                    color: colors.textSecondary,
                  }}>
                    {key.key_prefix}...
                  </span>
                </div>
                <div style={styles.userMeta}>
                  Created: {formatDate(key.created_at)}
                  <span style={styles.userDate}>
                    {' • '}Last used: {formatDate(key.last_used_at)}
                  </span>
                </div>
              </div>
              <div style={styles.userActions}>
                <span style={key.is_active ? badgeStyle('success') : badgeStyle('error')}>
                  {key.is_active ? 'Active' : 'Revoked'}
                </span>
                {key.is_active && (
                  <button
                    onClick={() => handleRevoke(key)}
                    style={mergeStyles(buttonStyle('secondary'), { padding: `${spacing.xs} ${spacing.sm}` })}
                    disabled={revokeMutation.isPending}
                    title="Revoke key"
                  >
                    Revoke
                  </button>
                )}
                <button
                  onClick={() => handleDelete(key)}
                  style={styles.deleteButton}
                  disabled={deleteMutation.isPending}
                  title="Delete key"
                >
                  ×
                </button>
              </div>
            </div>
          ))}
        </div>
      ) : (
        <div style={styles.emptyState}>
          <p>No API keys created yet.</p>
          <p style={{ fontSize: typography.sm, color: colors.textSecondary }}>
            Generate an API key to allow external applications like Kitchen Flash to access forecast data.
          </p>
        </div>
      )}

      <div style={styles.infoBox}>
        <h4 style={{ margin: `0 0 ${spacing.sm} 0`, fontSize: typography.base }}>Using API Keys</h4>
        <ul style={{ margin: 0, paddingLeft: spacing.lg, fontSize: typography.sm, lineHeight: 1.6 }}>
          <li>Include the API key in requests using the <code>X-API-Key</code> header</li>
          <li>Example: <code>curl -H "X-API-Key: fk_..." /api/public/forecast/rooms</code></li>
          <li>Available endpoints: <code>/public/forecast/rooms</code>, <code>/public/forecast/covers</code>, <code>/public/forecast/revenue</code></li>
          <li>API keys provide read-only access to forecast data</li>
          <li>Revoked keys will no longer work for API requests</li>
        </ul>
      </div>

      {/* Key Created Modal */}
      {showKeyModal && createdKey && (
        <div style={{
          position: 'fixed',
          top: 0,
          left: 0,
          right: 0,
          bottom: 0,
          background: 'rgba(0, 0, 0, 0.5)',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
          zIndex: 1000,
        }}>
          <div style={{
            background: colors.surface,
            borderRadius: radius.xl,
            padding: spacing.xl,
            maxWidth: '500px',
            width: '90%',
            boxShadow: shadows.lg,
          }}>
            <h3 style={{ margin: `0 0 ${spacing.md} 0`, color: colors.success }}>
              API Key Created
            </h3>
            <p style={{ margin: `0 0 ${spacing.md} 0`, color: colors.textSecondary }}>
              Copy this key now. You won't be able to see it again!
            </p>
            <div style={{
              background: colors.background,
              border: `1px solid ${colors.border}`,
              borderRadius: radius.lg,
              padding: spacing.md,
              fontFamily: 'monospace',
              fontSize: typography.sm,
              wordBreak: 'break-all',
              marginBottom: spacing.md,
            }}>
              {createdKey.key}
            </div>
            <div style={{ display: 'flex', gap: spacing.sm, justifyContent: 'flex-end' }}>
              <button
                onClick={handleCopyKey}
                style={mergeStyles(
                  buttonStyle('secondary'),
                  copied ? { background: colors.success, color: '#fff' } : {}
                )}
              >
                {copied ? 'Copied!' : 'Copy to Clipboard'}
              </button>
              <button
                onClick={closeKeyModal}
                style={buttonStyle('primary')}
              >
                Done
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

// ============================================
// AI INSIGHTS SETTINGS PAGE
// ============================================

interface AIInsightsSettings {
  enabled: boolean
  api_key_set: boolean
  model: string
  schedule_time: string
  daily_token_budget: number
}

const AIInsightsPage: React.FC = () => {
  const queryClient = useQueryClient()
  const [apiKey, setApiKey] = useState('')
  const [model, setModel] = useState('claude-haiku-4-5-20251001')
  const [scheduleTime, setScheduleTime] = useState('07:15')
  const [enabled, setEnabled] = useState(false)
  const [tokenBudget, setTokenBudget] = useState(5000)
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle')
  const [testStatus, setTestStatus] = useState<'idle' | 'testing' | 'connected' | 'error'>('idle')
  const [testMessage, setTestMessage] = useState('')
  const [generateStatus, setGenerateStatus] = useState<'idle' | 'generating' | 'done' | 'error'>('idle')
  const [generateMessage, setGenerateMessage] = useState('')

  const { data: settings, isLoading } = useQuery<AIInsightsSettings>({
    queryKey: ['ai-insights-settings'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/config/settings/ai-insights')
      if (!response.ok) throw new Error('Failed to fetch AI Insights settings')
      return response.json()
    },
  })

  const { data: usage } = useQuery({
    queryKey: ['ai-insights-usage'],
    queryFn: async () => {
      const response = await fetch('/forecasting/api/ai-insights/usage')
      if (!response.ok) return null
      return response.json()
    },
  })

  useEffect(() => {
    if (settings) {
      setModel(settings.model)
      setScheduleTime(settings.schedule_time)
      setEnabled(settings.enabled)
      setTokenBudget(settings.daily_token_budget)
    }
  }, [settings])

  const handleSave = async () => {
    setSaveStatus('saving')
    try {
      const body: any = {
        enabled,
        model,
        schedule_time: scheduleTime,
        daily_token_budget: tokenBudget,
      }
      if (apiKey.trim()) {
        body.api_key = apiKey.trim()
      }
      const response = await fetch('/forecasting/api/config/settings/ai-insights', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(body)
      })
      if (response.ok) {
        setSaveStatus('saved')
        setApiKey('')
        queryClient.invalidateQueries({ queryKey: ['ai-insights-settings'] })
        setTimeout(() => setSaveStatus('idle'), 3000)
      } else {
        setSaveStatus('error')
        setTimeout(() => setSaveStatus('idle'), 3000)
      }
    } catch {
      setSaveStatus('error')
      setTimeout(() => setSaveStatus('idle'), 3000)
    }
  }

  const handleTest = async () => {
    setTestStatus('testing')
    setTestMessage('')
    try {
      const response = await fetch('/forecasting/api/config/settings/ai-insights/test', {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setTestStatus('connected')
        setTestMessage(data.message || 'Connected')
      } else {
        setTestStatus('error')
        setTestMessage(data.detail || 'Connection failed')
      }
    } catch {
      setTestStatus('error')
      setTestMessage('Connection failed')
    }
    setTimeout(() => { setTestStatus('idle'); setTestMessage('') }, 5000)
  }

  const handleGenerate = async () => {
    setGenerateStatus('generating')
    setGenerateMessage('')
    try {
      const response = await fetch('/forecasting/api/ai-insights/generate', {
        method: 'POST',
      })
      const data = await response.json()
      if (response.ok) {
        setGenerateStatus('done')
        setGenerateMessage(`Generated! ${data.input_tokens} in / ${data.output_tokens} out tokens`)
        queryClient.invalidateQueries({ queryKey: ['ai-insights-usage'] })
        queryClient.invalidateQueries({ queryKey: ['ai-insights-latest'] })
      } else {
        setGenerateStatus('error')
        setGenerateMessage(data.detail || 'Generation failed')
      }
    } catch {
      setGenerateStatus('error')
      setGenerateMessage('Generation failed')
    }
    setTimeout(() => { setGenerateStatus('idle'); setGenerateMessage('') }, 8000)
  }

  if (isLoading) return <div style={styles.loading}>Loading AI Insights settings...</div>

  return (
    <div>
      <h2 style={styles.pageTitle}>AI Insights</h2>
      <p style={styles.pageDescription}>
        Daily AI-generated briefings using your forecast, pace, and competitor rate data.
        Powered by Anthropic's Claude — approximately $0.05/month.
      </p>

      <div style={styles.section}>
        <h3 style={styles.sectionTitle}>Configuration</h3>

        {/* Enable toggle */}
        <div style={styles.formRow}>
          <label style={styles.label}>
            <input
              type="checkbox"
              checked={enabled}
              onChange={(e) => setEnabled(e.target.checked)}
              style={{ marginRight: spacing.sm }}
            />
            Enable daily AI insights generation
          </label>
        </div>

        {/* API Key */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>Anthropic API Key</label>
            <input
              type="password"
              value={apiKey}
              onChange={(e) => setApiKey(e.target.value)}
              placeholder={settings?.api_key_set ? '••••••••  (key saved)' : 'sk-ant-...'}
              style={styles.input}
            />
            {settings?.api_key_set && (
              <span style={{ fontSize: typography.xs, color: colors.success, marginTop: spacing.xs, display: 'block' }}>
                API key is configured
              </span>
            )}
          </div>
        </div>

        {/* Model selector */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>Model</label>
            <select
              value={model}
              onChange={(e) => setModel(e.target.value)}
              style={styles.input}
            >
              <option value="claude-haiku-4-5-20251001">Claude Haiku 4.5 (cheapest)</option>
              <option value="claude-sonnet-4-6">Claude Sonnet 4.6</option>
            </select>
          </div>
        </div>

        {/* Schedule time */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>Schedule Time</label>
            <input
              type="time"
              value={scheduleTime}
              onChange={(e) => setScheduleTime(e.target.value)}
              style={mergeStyles(styles.input, { width: '140px' })}
            />
            <span style={{ fontSize: typography.xs, color: colors.textMuted, marginTop: spacing.xs, display: 'block' }}>
              Runs daily after all forecasts complete
            </span>
          </div>
        </div>

        {/* Daily token budget */}
        <div style={styles.formRow}>
          <div style={styles.formField}>
            <label style={styles.label}>Daily Token Budget</label>
            <input
              type="number"
              value={tokenBudget}
              onChange={(e) => setTokenBudget(parseInt(e.target.value) || 5000)}
              style={mergeStyles(styles.input, { width: '140px' })}
              min={1000}
              max={50000}
              step={1000}
            />
            <span style={{ fontSize: typography.xs, color: colors.textMuted, marginTop: spacing.xs, display: 'block' }}>
              ~1,100 tokens per insight. Budget prevents runaway costs.
            </span>
          </div>
        </div>

        {/* Save button */}
        <div style={{ display: 'flex', gap: spacing.sm, alignItems: 'center', marginTop: spacing.md }}>
          <button
            onClick={handleSave}
            style={buttonStyle('primary')}
            disabled={saveStatus === 'saving'}
          >
            {saveStatus === 'saving' ? 'Saving...' : 'Save Settings'}
          </button>
          {saveStatus === 'saved' && (
            <span style={{ color: colors.success, fontSize: typography.sm }}>Saved</span>
          )}
          {saveStatus === 'error' && (
            <span style={{ color: colors.error, fontSize: typography.sm }}>Save failed</span>
          )}
        </div>
      </div>

      {/* Test & Generate */}
      <div style={styles.section}>
        <h3 style={styles.sectionTitle}>Actions</h3>

        <div style={{ display: 'flex', gap: spacing.md, flexWrap: 'wrap', alignItems: 'flex-start' }}>
          <div>
            <button
              onClick={handleTest}
              style={buttonStyle('secondary')}
              disabled={testStatus === 'testing' || !settings?.api_key_set}
            >
              {testStatus === 'testing' ? 'Testing...' : 'Test Connection'}
            </button>
            {testMessage && (
              <div style={{
                marginTop: spacing.xs,
                fontSize: typography.xs,
                color: testStatus === 'connected' ? colors.success : colors.error
              }}>
                {testMessage}
              </div>
            )}
          </div>

          <div>
            <button
              onClick={handleGenerate}
              style={buttonStyle('primary')}
              disabled={generateStatus === 'generating' || !settings?.api_key_set || !settings?.enabled}
            >
              {generateStatus === 'generating' ? 'Generating...' : 'Generate Now'}
            </button>
            {generateMessage && (
              <div style={{
                marginTop: spacing.xs,
                fontSize: typography.xs,
                color: generateStatus === 'done' ? colors.success : colors.error
              }}>
                {generateMessage}
              </div>
            )}
          </div>
        </div>
      </div>

      {/* Usage stats */}
      {usage && (
        <div style={styles.section}>
          <h3 style={styles.sectionTitle}>Usage</h3>
          <div style={styles.syncStatusRow}>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>This Month</span>
              <span style={styles.syncStatusValue}>
                {usage.month.generations} generations
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Monthly Tokens</span>
              <span style={styles.syncStatusValue}>
                {usage.month.total_tokens.toLocaleString()}
              </span>
            </div>
            <div style={styles.syncStatusItem}>
              <span style={styles.syncStatusLabel}>Today</span>
              <span style={styles.syncStatusValue}>
                {usage.today_tokens.toLocaleString()} / {tokenBudget.toLocaleString()} tokens
              </span>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}


// ============================================
// STYLES
// ============================================

const styles: Record<string, React.CSSProperties> = {
  layout: {
    display: 'flex',
    gap: spacing.xl,
    padding: spacing.xl,
  },
  header: { marginBottom: spacing.lg },
  title: { fontSize: typography.xxl, fontWeight: typography.semibold, color: colors.text, margin: 0 },
  pageTitle: { fontSize: typography.xxl, fontWeight: typography.semibold, color: colors.text, margin: `0 0 ${spacing.xs} 0` },
  pageDescription: { fontSize: typography.sm, color: colors.textSecondary, margin: `0 0 ${spacing.lg} 0` },
  actions: { display: 'flex', gap: spacing.sm, alignItems: 'center', flexWrap: 'wrap' },
  infoBox: { padding: spacing.md, background: colors.infoBg, color: colors.info, borderRadius: radius.md, fontSize: typography.sm, marginBottom: spacing.lg },
  modal: { background: colors.surface, borderRadius: radius.xl, padding: spacing.xl, boxShadow: shadows.xl, maxWidth: '480px', width: '90%' },
  sidebar: {
    width: '200px',
    flexShrink: 0,
    background: colors.surface,
    borderRadius: radius.xl,
    padding: spacing.md,
    boxShadow: shadows.md,
    height: 'fit-content',
    position: 'sticky',
    top: spacing.md,
  },
  sidebarTitle: {
    margin: `0 0 ${spacing.md} 0`,
    fontSize: typography.lg,
    color: colors.text,
    fontWeight: typography.semibold,
  },
  nav: {
    display: 'flex',
    flexDirection: 'column',
    gap: '4px',
  },
  navItem: {
    padding: `${spacing.sm} ${spacing.md}`,
    border: 'none',
    background: 'transparent',
    textAlign: 'left',
    cursor: 'pointer',
    borderRadius: radius.md,
    fontSize: typography.sm,
    color: colors.textSecondary,
    fontWeight: typography.normal,
    transition: 'all 0.15s ease',
  },
  navItemActive: {
    background: colors.accent,
    color: colors.textLight,
    fontWeight: typography.medium,
  },
  content: {
    flex: 1,
    minWidth: 0,
  },
  section: {
    background: colors.surface,
    padding: spacing.lg,
    borderRadius: radius.xl,
    boxShadow: shadows.md,
  },
  sectionHeader: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'flex-start',
    marginBottom: spacing.lg,
  },
  sectionTitle: {
    color: colors.text,
    margin: 0,
    marginBottom: spacing.xs,
    fontSize: typography.xxl,
    fontWeight: typography.semibold,
  },
  subsection: {
    marginTop: spacing.lg,
  },
  subsectionTitle: {
    color: colors.text,
    margin: `0 0 ${spacing.md} 0`,
    fontSize: typography.lg,
    fontWeight: typography.medium,
  },
  hint: {
    color: colors.textSecondary,
    margin: 0,
    marginBottom: spacing.md,
    fontSize: typography.sm,
  },
  divider: {
    height: '1px',
    background: colors.borderLight,
    margin: `${spacing.xl} 0`,
  },
  apiConfigRow: {
    display: 'flex',
    gap: spacing.xl,
    marginTop: spacing.lg,
  },
  apiConfigLeft: {
    flex: '0 0 400px',
  },
  apiConfigRight: {
    flex: '0 0 auto',
    minWidth: '200px',
  },
  form: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.md,
  },
  label: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
    color: colors.text,
    fontSize: typography.sm,
    fontWeight: typography.medium,
  },
  input: {
    padding: spacing.sm,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.base,
    outline: 'none',
    transition: 'border-color 0.2s',
  },
  inputWithStatus: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
  },
  keyStatus: {
    fontSize: typography.xs,
    color: colors.success,
  },
  buttonRow: {
    display: 'flex',
    gap: spacing.sm,
    marginTop: spacing.sm,
  },
  statusMessage: {
    padding: spacing.sm,
    borderRadius: radius.md,
    fontSize: typography.sm,
  },
  statusGrid: {
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))',
    gap: spacing.md,
  },
  statusGridVertical: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.sm,
  },
  statusItem: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
    padding: spacing.md,
    background: colors.background,
    borderRadius: radius.md,
  },
  statusLabel: {
    fontSize: typography.xs,
    color: colors.textMuted,
    textTransform: 'uppercase',
    letterSpacing: '0.05em',
  },
  statusOk: {
    color: colors.success,
    fontWeight: typography.medium,
  },
  statusPending: {
    color: colors.textMuted,
  },
  loading: {
    color: colors.textSecondary,
    padding: spacing.lg,
    textAlign: 'center',
  },
  error: {
    background: colors.errorBg,
    color: colors.error,
    padding: spacing.sm,
    borderRadius: radius.md,
    fontSize: typography.sm,
    marginBottom: spacing.md,
  },
  addForm: {
    background: colors.background,
    borderRadius: radius.lg,
    padding: spacing.lg,
    marginBottom: spacing.lg,
  },
  formRow: {
    display: 'flex',
    gap: spacing.md,
    alignItems: 'flex-start',
    flexWrap: 'wrap',
  },
  formField: {
    flex: '1 1 200px',
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
  },
  userList: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.sm,
  },
  userCard: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: spacing.md,
    background: colors.background,
    borderRadius: radius.lg,
    border: `1px solid ${colors.borderLight}`,
  },
  userInfo: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
  },
  userName: {
    fontWeight: typography.semibold,
    color: colors.text,
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
  },
  userMeta: {
    fontSize: typography.sm,
    color: colors.textSecondary,
  },
  userDate: {
    color: colors.textMuted,
  },
  userActions: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.md,
  },
  deleteButton: {
    width: '28px',
    height: '28px',
    borderRadius: radius.full,
    border: `1px solid ${colors.border}`,
    background: colors.surface,
    color: colors.textSecondary,
    fontSize: '1.25rem',
    cursor: 'pointer',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    transition: 'all 0.2s',
  },
  iframeContainer: {
    borderRadius: radius.lg,
    overflow: 'hidden',
    border: `1px solid ${colors.borderLight}`,
    height: 'calc(100vh - 280px)',
    minHeight: '500px',
  },
  iframe: {
    width: '100%',
    height: '100%',
    border: 'none',
  },
  // Room Categories styles
  roomCategoryHeader: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginTop: spacing.md,
    marginBottom: spacing.sm,
  },
  roomCategorySummary: {
    fontSize: typography.sm,
    color: colors.textSecondary,
    fontWeight: typography.medium,
  },
  roomCategoryList: {
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
    gap: spacing.sm,
    background: colors.background,
    borderRadius: radius.md,
    padding: spacing.md,
  },
  roomCategoryItem: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
    padding: spacing.sm,
    borderRadius: radius.sm,
    cursor: 'pointer',
    transition: 'background 0.15s',
  },
  checkbox: {
    width: '18px',
    height: '18px',
    accentColor: colors.accent,
  },
  roomCategoryName: {
    flex: 1,
    fontSize: typography.sm,
    color: colors.text,
  },
  roomCategoryCount: {
    fontSize: typography.xs,
    color: colors.textMuted,
    marginRight: spacing.sm,
  },
  displayOrderInput: {
    width: '50px',
    padding: `${spacing.xs} ${spacing.sm}`,
    fontSize: typography.xs,
    border: `1px solid ${colors.border}`,
    borderRadius: radius.sm,
    textAlign: 'center',
  },
  emptyState: {
    padding: spacing.lg,
    textAlign: 'center',
    color: colors.textSecondary,
    background: colors.background,
    borderRadius: radius.md,
    marginTop: spacing.md,
  },
  // GL Revenue Mapping styles
  glAccountCount: {
    fontSize: typography.sm,
    color: colors.textSecondary,
    marginLeft: spacing.md,
  },
  departmentGrid: {
    display: 'flex',
    gap: spacing.lg,
    marginTop: spacing.lg,
  },
  departmentColumn: {
    flex: 1,
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.sm,
  },
  departmentHeader: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    paddingBottom: spacing.sm,
    borderBottom: `1px solid ${colors.borderLight}`,
  },
  departmentTitle: {
    fontSize: typography.base,
    fontWeight: typography.semibold,
    color: colors.text,
  },
  departmentCount: {
    fontSize: typography.xs,
    color: colors.textMuted,
  },
  departmentAccountList: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
    minHeight: '120px',
    maxHeight: '200px',
    overflowY: 'auto',
    background: colors.background,
    borderRadius: radius.md,
    padding: spacing.sm,
  },
  departmentEmpty: {
    color: colors.textMuted,
    fontSize: typography.sm,
    fontStyle: 'italic',
    textAlign: 'center',
    padding: spacing.md,
  },
  departmentAccountItem: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
    padding: spacing.xs,
    borderRadius: radius.sm,
    background: colors.surface,
  },
  departmentAccountName: {
    flex: 1,
    fontSize: typography.sm,
    color: colors.text,
  },
  departmentAccountCode: {
    fontSize: typography.xs,
    color: colors.textMuted,
  },
  removeButton: {
    width: '20px',
    height: '20px',
    borderRadius: radius.full,
    border: 'none',
    background: colors.borderLight,
    color: colors.textSecondary,
    fontSize: '14px',
    cursor: 'pointer',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    flexShrink: 0,
  },
  // Modal styles
  modalOverlay: {
    position: 'fixed',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    background: 'rgba(0, 0, 0, 0.5)',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    zIndex: 1000,
  },
  modalContent: {
    background: colors.surface,
    borderRadius: radius.xl,
    boxShadow: shadows.lg,
    width: '90%',
    maxWidth: '600px',
    maxHeight: '80vh',
    display: 'flex',
    flexDirection: 'column',
  },
  modalHeader: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: spacing.lg,
    borderBottom: `1px solid ${colors.borderLight}`,
  },
  modalTitle: {
    margin: 0,
    fontSize: typography.lg,
    fontWeight: typography.semibold,
    color: colors.text,
  },
  modalCloseButton: {
    width: '32px',
    height: '32px',
    borderRadius: radius.full,
    border: 'none',
    background: colors.background,
    color: colors.textSecondary,
    fontSize: '1.25rem',
    cursor: 'pointer',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
  modalBody: {
    flex: 1,
    overflowY: 'auto',
    padding: spacing.lg,
  },
  modalFooter: {
    display: 'flex',
    justifyContent: 'flex-end',
    padding: spacing.lg,
    borderTop: `1px solid ${colors.borderLight}`,
  },
  // GL Group styles
  glGroup: {
    marginBottom: spacing.lg,
  },
  glGroupHeader: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
    padding: `${spacing.sm} ${spacing.md}`,
    background: colors.background,
    borderLeft: `3px solid ${colors.accent}`,
    borderRadius: `0 ${radius.sm} ${radius.sm} 0`,
    cursor: 'pointer',
    fontWeight: typography.semibold,
    fontSize: typography.sm,
    color: colors.text,
  },
  glGroupName: {
    flex: 1,
  },
  glGroupCount: {
    fontSize: typography.xs,
    color: colors.textMuted,
    fontWeight: typography.normal,
  },
  glGroupItems: {
    paddingLeft: spacing.lg,
    borderLeft: `1px solid ${colors.borderLight}`,
    marginLeft: spacing.sm,
    marginTop: spacing.xs,
  },
  glItem: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
    padding: spacing.sm,
    cursor: 'pointer',
    borderRadius: radius.sm,
    transition: 'background 0.15s',
  },
  glItemName: {
    flex: 1,
    fontSize: typography.sm,
    color: colors.text,
  },
  glItemCode: {
    fontSize: typography.xs,
    color: colors.textMuted,
  },
  glItemMapped: {
    fontSize: typography.xs,
    color: colors.warning,
    fontStyle: 'italic',
  },
  // Sync section styles
  syncStatusRow: {
    display: 'flex',
    gap: spacing.lg,
    marginTop: spacing.md,
    marginBottom: spacing.lg,
  },
  syncStatusItem: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
    padding: spacing.md,
    background: colors.background,
    borderRadius: radius.md,
    minWidth: '150px',
  },
  syncStatusLabel: {
    fontSize: typography.xs,
    color: colors.textMuted,
    textTransform: 'uppercase',
    letterSpacing: '0.05em',
  },
  syncStatusValue: {
    fontSize: typography.base,
    fontWeight: typography.medium,
    color: colors.text,
  },
  syncControlsSection: {
    display: 'flex',
    gap: spacing.lg,
    flexWrap: 'wrap',
  },
  syncControlBox: {
    flex: '1 1 250px',
    padding: spacing.md,
    background: colors.background,
    borderRadius: radius.md,
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.sm,
  },
  syncControlTitle: {
    margin: 0,
    fontSize: typography.sm,
    fontWeight: typography.semibold,
    color: colors.text,
  },
  syncControlHint: {
    margin: 0,
    fontSize: typography.xs,
    color: colors.textMuted,
    marginBottom: spacing.xs,
  },
  syncDateRow: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
    marginBottom: spacing.sm,
  },
  dateInput: {
    padding: spacing.sm,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.sm,
    flex: 1,
  },
  dateTo: {
    fontSize: typography.sm,
    color: colors.textMuted,
  },
  syncCheckboxLabel: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
    fontSize: typography.sm,
    color: colors.text,
    cursor: 'pointer',
  },
  syncSelect: {
    padding: spacing.sm,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.sm,
    background: colors.surface,
    flex: 1,
  },
  syncAutoRow: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
  },
  syncTimeLabel: {
    fontSize: typography.sm,
    color: colors.textMuted,
  },
  syncTimeInput: {
    padding: spacing.sm,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.sm,
    background: colors.surface,
    width: '100px',
  },
  syncLogsSection: {
    marginTop: spacing.xl,
  },
  syncLogsTitle: {
    margin: `0 0 ${spacing.sm} 0`,
    fontSize: typography.sm,
    fontWeight: typography.semibold,
    color: colors.text,
  },
  syncLogsList: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
  },
  syncLogItem: {
    padding: spacing.sm,
    background: colors.background,
    borderRadius: radius.sm,
    borderLeft: `3px solid ${colors.borderLight}`,
  },
  syncLogMain: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
  },
  syncLogStatus: {
    fontWeight: typography.bold,
    fontSize: typography.sm,
  },
  syncLogDate: {
    fontSize: typography.sm,
    color: colors.text,
  },
  syncLogRecords: {
    fontSize: typography.xs,
    color: colors.textMuted,
    marginLeft: 'auto',
  },
  syncLogMeta: {
    display: 'flex',
    gap: spacing.md,
    marginTop: spacing.xs,
    paddingLeft: spacing.lg,
  },
  syncLogTrigger: {
    fontSize: typography.xs,
    color: colors.textSecondary,
  },
  syncLogRange: {
    fontSize: typography.xs,
    color: colors.textMuted,
  },
  syncLogError: {
    fontSize: typography.xs,
    color: colors.error,
    marginTop: spacing.xs,
    paddingLeft: spacing.lg,
  },
  // Table styles
  tableContainer: {
    overflowX: 'auto',
  },
  table: {
    width: '100%',
    borderCollapse: 'collapse',
    fontSize: typography.sm,
  },
  th: {
    padding: spacing.sm,
    textAlign: 'left',
    borderBottom: `2px solid ${colors.border}`,
    color: colors.textSecondary,
    fontWeight: typography.medium,
    whiteSpace: 'nowrap',
  },
  td: {
    padding: spacing.sm,
    borderBottom: `1px solid ${colors.borderLight}`,
    color: colors.text,
  },
  // Special Dates styles
  formContainer: {
    background: colors.background,
    padding: spacing.lg,
    borderRadius: radius.lg,
    marginBottom: spacing.lg,
    border: `1px solid ${colors.border}`,
  },
  formGrid: {
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
    gap: spacing.md,
  },
  formGroup: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
  },
  select: {
    padding: spacing.sm,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.base,
    outline: 'none',
    background: colors.surface,
    color: colors.text,
    cursor: 'pointer',
  },
  previewCard: {
    padding: spacing.sm,
    background: colors.background,
    borderRadius: radius.md,
    border: `1px solid ${colors.borderLight}`,
    minWidth: '150px',
  },
  actionButton: {
    background: 'transparent',
    border: 'none',
    padding: spacing.xs,
    cursor: 'pointer',
    fontSize: typography.sm,
    fontWeight: typography.medium,
  },
  // Settings grid styles
  settingsGrid: {
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
    gap: spacing.md,
    marginBottom: spacing.md,
  },
  settingItem: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
  },
  settingLabel: {
    fontSize: typography.sm,
    fontWeight: typography.medium,
    color: colors.text,
    display: 'flex',
    alignItems: 'center',
    gap: spacing.xs,
  },
  settingInput: {
    padding: spacing.sm,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.base,
    background: colors.surface,
    color: colors.text,
    width: '100%',
  },
  settingSelect: {
    padding: spacing.sm,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
    fontSize: typography.base,
    background: colors.surface,
    color: colors.text,
    cursor: 'pointer',
  },
  settingHint: {
    fontSize: typography.xs,
    color: colors.textMuted,
  },
  trainControlRow: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: spacing.md,
    alignItems: 'flex-end',
    marginBottom: spacing.md,
  },
  trainControl: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.xs,
    minWidth: '200px',
  },
  trainingProgress: {
    background: colors.background,
    padding: spacing.md,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
  },
  progressHeader: {
    display: 'flex',
    justifyContent: 'space-between',
    marginBottom: spacing.sm,
    fontSize: typography.sm,
    color: colors.text,
  },
  progressStatus: {
    fontWeight: typography.medium,
    color: colors.primary,
  },
  progressBarOuter: {
    height: '8px',
    background: colors.borderLight,
    borderRadius: radius.full,
    overflow: 'hidden',
  },
  progressBarInner: {
    height: '100%',
    background: colors.primary,
    transition: 'width 0.3s ease',
  },
  modelsList: {
    display: 'flex',
    flexDirection: 'column',
    gap: spacing.md,
  },
  modelCard: {
    background: colors.background,
    padding: spacing.md,
    borderRadius: radius.md,
    border: `1px solid ${colors.border}`,
  },
  modelHeader: {
    display: 'flex',
    alignItems: 'center',
    gap: spacing.sm,
    marginBottom: spacing.sm,
  },
  modelName: {
    fontSize: typography.base,
    fontWeight: typography.semibold,
    color: colors.text,
  },
  modelMeta: {
    display: 'flex',
    flexWrap: 'wrap',
    gap: spacing.md,
    fontSize: typography.sm,
    color: colors.textMuted,
    marginBottom: spacing.sm,
  },
  modelActions: {
    display: 'flex',
    gap: spacing.sm,
    marginTop: spacing.sm,
    paddingTop: spacing.sm,
    borderTop: `1px solid ${colors.borderLight}`,
  },
}

export default Settings
