import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import axios from 'axios'
import { SparkleIcon, XIcon } from '@phosphor-icons/react'
import { Alert, Button, TextArea } from '@/ui'
import { useAiSuggestField } from '@/api/mutations'
import { cn } from '@/lib/utils'

/**
 * AI Schema Assist — per-field suggest panel.
 *
 * <p>Expanded inline (не modal) — admin вводит описание → preview JSON suggestion
 * → accept/reject. Accept callback получает {fieldName, schema} как plain JSON
 * fragment, caller интегрирует в свой schema state.
 *
 * <p>Graceful degradation:
 * <ul>
 *   <li>404 от endpoint (AI disabled на бэке) → caller должен hide button entirely</li>
 *   <li>503 circuit_open → banner «AI временно недоступен», retry в 5 мин</li>
 *   <li>422 bad_output → error message, suggest другой prompt</li>
 *   <li>429 rate_limit → «слишком много запросов, подожди минуту»</li>
 * </ul>
 */
type Props = {
  /** Current schema serialized as JSON object — будет передан как context */
  existingSchema: Record<string, unknown>
  /** Called когда юзер accepted suggestion */
  onAccept: (suggestion: { fieldName: string; schema: Record<string, unknown> }) => void
  /** Optional close handler — hide panel */
  onClose?: () => void
}

export function AiFieldSuggestPanel({ existingSchema, onAccept, onClose }: Props) {
  const { t } = useTranslation()
  const [prompt, setPrompt] = useState('')
  const [suggestion, setSuggestion] = useState<{
    fieldName: string
    schema: Record<string, unknown>
  } | null>(null)
  const mutation = useAiSuggestField()

  const handleSuggest = () => {
    if (!prompt.trim()) return
    setSuggestion(null)
    mutation.mutate(
      { existingSchema, prompt },
      {
        onSuccess: (data) => setSuggestion(data),
      },
    )
  }

  const handleAccept = () => {
    if (!suggestion) return
    onAccept(suggestion)
    setPrompt('')
    setSuggestion(null)
  }

  const handleRetry = () => {
    setSuggestion(null)
    handleSuggest()
  }

  const errorMessage = mutation.error ? formatError(mutation.error, t) : null

  return (
    <div className="flex flex-col gap-3 p-4 rounded-md border border-line bg-surface-2/50">
      <div className="flex items-center gap-2">
        <SparkleIcon size={16} weight="fill" className="text-accent shrink-0" />
        <span className="text-body font-semibold text-ink flex-1">
          {t('aiSuggest.title', { defaultValue: 'AI: добавить поле' })}
        </span>
        {onClose && (
          <button
            type="button"
            onClick={onClose}
            aria-label={t('common.close', { defaultValue: 'Закрыть' })}
            className="text-mute hover:text-ink p-1 rounded-sm hover:bg-surface"
          >
            <XIcon size={14} />
          </button>
        )}
      </div>

      <div className="flex flex-col gap-1">
        <TextArea
          value={prompt}
          onChange={(e) => setPrompt(e.target.value)}
          placeholder={t('aiSuggest.placeholder', {
            defaultValue: 'Опиши поле — например "орбита: апогей, перигей, наклонение"',
          })}
          rows={2}
          disabled={mutation.isPending}
          maxLength={500}
        />
        <div className="text-cell text-mute">
          {t('aiSuggest.hint', {
            defaultValue: 'AI предложит структуру (type/format/x-references). GOST коды и validations добавь сам.',
          })}
        </div>
      </div>

      {!suggestion && (
        <div className="flex justify-end">
          <Button
            type="button"
            variant="primary"
            size="sm"
            onClick={handleSuggest}
            disabled={mutation.isPending || !prompt.trim()}
          >
            {mutation.isPending
              ? t('aiSuggest.thinking', { defaultValue: 'Думаю…' })
              : t('aiSuggest.suggest', { defaultValue: 'Предложить' })}
          </Button>
        </div>
      )}

      {errorMessage && (
        <Alert variant="error">{errorMessage}</Alert>
      )}

      {suggestion && (
        <div className="flex flex-col gap-2">
          <div className="text-cap text-mute uppercase tracking-wider">
            {t('aiSuggest.preview', { defaultValue: 'Предложение' })}
          </div>
          <div className="rounded-sm border border-line bg-surface p-3">
            <div className="text-body font-semibold text-ink mb-1">
              <span className="text-mono text-accent">{suggestion.fieldName}</span>
            </div>
            <pre className={cn(
              'text-mono text-cell text-ink-2 max-h-64 overflow-auto whitespace-pre-wrap',
              'bg-surface-2 rounded-sm p-2',
            )}>
              {JSON.stringify(suggestion.schema, null, 2)}
            </pre>
          </div>
          <div className="flex justify-end gap-2">
            <Button
              type="button"
              variant="secondary"
              size="sm"
              onClick={handleRetry}
              disabled={mutation.isPending}
            >
              {t('aiSuggest.retry', { defaultValue: 'Перегенерировать' })}
            </Button>
            <Button
              type="button"
              variant="primary"
              size="sm"
              onClick={handleAccept}
              disabled={mutation.isPending}
            >
              {t('aiSuggest.accept', { defaultValue: 'Добавить в схему' })}
            </Button>
          </div>
        </div>
      )}
    </div>
  )
}

function formatError(
  err: unknown,
  t: (k: string, opts?: Record<string, unknown>) => string,
): string {
  if (axios.isAxiosError(err)) {
    const status = err.response?.status
    if (status === 503) {
      return t('aiSuggest.error.circuit', {
        defaultValue: 'AI временно недоступен. Попробуй через несколько минут.',
      })
    }
    if (status === 429) {
      return t('aiSuggest.error.rate', {
        defaultValue: 'Слишком много запросов. Подожди минуту.',
      })
    }
    if (status === 422) {
      return t('aiSuggest.error.bad_output', {
        defaultValue: 'AI вернул невалидный ответ. Попробуй переформулировать prompt.',
      })
    }
    if (status === 502) {
      return t('aiSuggest.error.upstream', {
        defaultValue: 'LLM endpoint недоступен. Жди restore или попробуй позже.',
      })
    }
    if (status === 404) {
      return t('aiSuggest.error.disabled', {
        defaultValue: 'AI отключён в этой инсталляции.',
      })
    }
  }
  return t('aiSuggest.error.generic', { defaultValue: 'Не удалось получить предложение.' })
}
