import { createFileRoute } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { useAuth } from 'react-oidc-context'
import {
  Button,
  EmptyState,
  LoadingBlock,
  PageHeader,
  Panel,
  QueryErrorState,
  Switch,
} from '@/ui'
import { useMyNotificationPreferences } from '@/api/queries'
import { useUpdateNotificationPreferences } from '@/api/mutations'
import type { NotificationPreferences } from '@/api/client'

export const Route = createFileRoute('/me/notifications/preferences')({
  component: NotificationPreferencesPage,
})

/**
 * Phase B — UI для per-channel notification opt-in/out.
 *
 * <p>Email — единственный actually wired channel в Phase A/B (через Spring
 * \`spring.mail.host\`). Express + Telegram toggles disabled с подсказкой
 * "Скоро" — backend хранит preference (на случай early opt-in), но dispatcher
 * никогда не пошлёт пока channel bean не зарегистрирован.
 *
 * <p>Optimistic update — toggle flips мгновенно, network roundtrip ~200ms
 * почти не виден. onError refetch восстанавливает state если PUT 4xx/5xx.
 */
function NotificationPreferencesPage() {
  const { t } = useTranslation()
  const auth = useAuth()
  const prefsQ = useMyNotificationPreferences()
  const updateMut = useUpdateNotificationPreferences()

  if (!auth.isAuthenticated) {
    return (
      <Panel>
        <PageHeader
          title={t('prefs.title', { defaultValue: 'Уведомления' })}
          description={t('prefs.description', {
            defaultValue:
              'Per-channel настройки доставки. Применяется только к вашим уведомлениям.',
          })}
        />
        <EmptyState
          title={t('prefs.anonTitle', {
            defaultValue: 'Войдите чтобы управлять подписками',
          })}
          description={t('prefs.anonDescription', {
            defaultValue:
              'Настройки уведомлений хранятся per-user (по JWT sub claim). Войдите через Keycloak чтобы открыть страницу.',
          })}
          action={
            <Button onClick={() => auth.signinRedirect()}>
              {t('auth.login', { defaultValue: 'Войти' })}
            </Button>
          }
        />
      </Panel>
    )
  }

  if (prefsQ.isLoading) {
    return <LoadingBlock size="md" label={t('loading')} />
  }
  if (prefsQ.error) {
    return <QueryErrorState error={prefsQ.error} onRetry={() => prefsQ.refetch()} />
  }

  const prefs: NotificationPreferences = prefsQ.data ?? {
    email: true,
    express: false,
    telegram: false,
  }

  const handleToggle = (channel: keyof NotificationPreferences, next: boolean) => {
    updateMut.mutate({ ...prefs, [channel]: next })
  }

  return (
    <Panel>
      <PageHeader
        title={t('prefs.title', { defaultValue: 'Уведомления' })}
        description={t('prefs.description', {
          defaultValue:
            'Per-channel настройки доставки. Применяется только к вашим уведомлениям (reviewer pool inbox остаётся ON).',
        })}
      />

      <div className="mt-6 space-y-1">
        <ToggleRow
          label={t('prefs.email.label', { defaultValue: 'Email' })}
          description={t('prefs.email.description', {
            defaultValue:
              'SMTP доставка через сконфигурированный mail.host. На staging это mailpit catcher; на prod — реальный relay.',
          })}
          checked={prefs.email}
          onChange={(v) => handleToggle('email', v)}
        />
        <ToggleRow
          label={t('prefs.express.label', { defaultValue: 'Express' })}
          description={t('prefs.express.description', {
            defaultValue:
              'Корпоративный мессенджер. Канал ещё не подключён — toggle сохраняется на будущее.',
          })}
          checked={prefs.express}
          onChange={(v) => handleToggle('express', v)}
          disabled
          comingSoon
        />
        <ToggleRow
          label={t('prefs.telegram.label', { defaultValue: 'Telegram' })}
          description={t('prefs.telegram.description', {
            defaultValue:
              'Telegram бот. Канал ещё не подключён — toggle сохраняется на будущее.',
          })}
          checked={prefs.telegram}
          onChange={(v) => handleToggle('telegram', v)}
          disabled
          comingSoon
        />
      </div>

      {updateMut.isError && (
        <div
          role="alert"
          className="mt-4 rounded border border-danger bg-danger-bg p-3 text-sm text-danger"
        >
          {t('prefs.saveError', {
            defaultValue: 'Не удалось сохранить настройки. Попробуйте ещё раз.',
          })}
        </div>
      )}
    </Panel>
  )
}

type ToggleRowProps = {
  label: string
  description: string
  checked: boolean
  onChange: (v: boolean) => void
  disabled?: boolean
  comingSoon?: boolean
}

function ToggleRow({
  label,
  description,
  checked,
  onChange,
  disabled,
  comingSoon,
}: ToggleRowProps) {
  const { t } = useTranslation()
  return (
    <div className="flex items-start justify-between gap-6 border-b border-line py-4 last:border-b-0">
      <div className="flex-1">
        <div className="flex items-center gap-2">
          <span className="text-base font-medium text-ink">{label}</span>
          {comingSoon && (
            <span className="rounded bg-mute-bg px-2 py-0.5 text-xs text-mute">
              {t('prefs.comingSoon', { defaultValue: 'Скоро' })}
            </span>
          )}
        </div>
        <p className="mt-1 text-sm text-ink-2">{description}</p>
      </div>
      <Switch
        checked={checked}
        onCheckedChange={onChange}
        disabled={disabled}
        aria-label={label}
      />
    </div>
  )
}
