'use client'

import { AlertTriangle, Info, Loader2, Plus } from 'lucide-react'
import { useId, useMemo, useState } from 'react'
import { toast } from 'sonner'
import { AiFeaturesCard } from './AiFeaturesCard.js'
import { BrandVoiceCard } from './BrandVoiceCard.js'
import { ModelSelector } from './ModelSelector.js'
import { MonthlyUsageCard } from './MonthlyUsageCard.js'
import { ProviderConnectionCard } from './ProviderConnectionCard.js'
import { SettingsCard, SettingsSaveBar } from './components.js'
import {
  useAiSettings,
  type AiProviderKey,
  type ProviderInput,
  type UseAiSettings,
} from './useAiSettings.js'

const INPUT_CLASS =
  'w-full rounded-md border border-border bg-input-background px-3 py-2 text-base text-foreground focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-60'
const LABEL_CLASS = 'mb-1 flex items-center gap-2 text-sm font-medium text-foreground'

const PROVIDER_OPTIONS: Array<{ value: AiProviderKey; label: string }> = [
  { value: 'anthropic', label: 'Anthropic (Claude)' },
  { value: 'openai', label: 'OpenAI (GPT)' },
  { value: 'xai', label: 'xAI (Grok)' },
  { value: 'custom', label: 'Custom (OpenAI-compatible)' },
]

export interface AISettingsTabProps {
  /** Current user's role. Only ADMIN can persist changes. */
  role?: string
}

export function AISettingsTab({ role }: AISettingsTabProps) {
  const canEdit = role === 'ADMIN'
  const ai = useAiSettings(canEdit)

  if (ai.loading) {
    return (
      <div className="space-y-4" aria-busy="true" aria-live="polite">
        <span className="sr-only">Loading AI settings…</span>
        {[0, 1, 2].map((i) => (
          <div key={i} className="border-border bg-card rounded-lg border p-6">
            <div className="bg-muted mb-4 h-4 w-40 animate-pulse rounded" />
            <div className="space-y-3">
              <div className="bg-muted h-9 w-full animate-pulse rounded" />
              <div className="bg-muted h-9 w-full animate-pulse rounded" />
            </div>
          </div>
        ))}
      </div>
    )
  }

  return (
    <div className="space-y-4">
      {ai.loadError && (
        <div
          role="alert"
          className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-3 text-sm"
        >
          <AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
          <span className="flex-1">{ai.loadError}</span>
          <button
            type="button"
            onClick={ai.refetch}
            className="border-destructive/40 rounded-md border px-3 py-1 transition-colors hover:opacity-80"
          >
            Retry
          </button>
        </div>
      )}

      {!canEdit && (
        <div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-3 text-sm">
          <Info size={16} className="shrink-0" aria-hidden="true" />
          You have read-only access to AI settings. Only administrators can make changes.
        </div>
      )}

      <AssistantCard ai={ai} canEdit={canEdit} />
      <ProviderConnectionsSection ai={ai} canEdit={canEdit} />
      <AiFeaturesCard
        features={ai.form.features}
        models={ai.models}
        defaultModelId={ai.form.defaultModelId}
        canEdit={canEdit}
        onToggle={ai.toggleFeature}
        onSetFeatureModel={ai.setFeatureModel}
      />
      <BrandVoiceCard value={ai.form.brandVoice} canEdit={canEdit} onChange={ai.setBrandVoice} />
      <MonthlyUsageCard
        usage={ai.usage}
        monthlyTokenLimit={ai.form.monthlyTokenLimit}
        onChangeLimit={ai.setMonthlyTokenLimit}
        budgetError={ai.budgetError}
        canEdit={canEdit}
      />

      {ai.saveState === 'error' && ai.saveError && (
        <div
          role="alert"
          className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-3 text-sm"
        >
          <AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
          <span className="flex-1">{ai.saveError}</span>
        </div>
      )}

      <SettingsSaveBar
        dirty={ai.dirty}
        canEdit={canEdit}
        hasErrors={Boolean(ai.budgetError)}
        saveState={ai.saveState}
        onSave={ai.save}
        onReset={ai.reset}
      />
    </div>
  )
}

// ---------------------------------------------------------------------------
// AI Assistant — default provider + default model
// ---------------------------------------------------------------------------

function AssistantCard({ ai, canEdit }: { ai: UseAiSettings; canEdit: boolean }) {
  const providerSelectId = useId()
  const [refreshing, setRefreshing] = useState(false)

  const defaultProvider = ai.providers.find((p) => p.id === ai.form.defaultProviderId)
  const modelsForDefault = useMemo(() => {
    if (!defaultProvider) return ai.models
    return ai.models.filter((m) => m.provider === defaultProvider.provider)
  }, [ai.models, defaultProvider])

  async function handleRefresh() {
    if (!defaultProvider) return
    setRefreshing(true)
    try {
      const res = await ai.syncModels(defaultProvider.id)
      if (!res.ok) toast.error(res.error ?? 'Failed to refresh models.')
      else if (res.fromFallback)
        toast.warning(res.warning ?? 'Showing the curated model list (live listing unavailable).')
      else toast.success('Model list refreshed.')
    } finally {
      setRefreshing(false)
    }
  }

  return (
    <SettingsCard
      title="AI Assistant"
      description="The default provider and model used across AI features."
    >
      {ai.providers.length === 0 ? (
        <div className="border-border bg-muted/40 text-muted-foreground rounded-md border border-dashed p-4 text-sm">
          No AI providers are connected yet. Add one below to enable AI features.
        </div>
      ) : (
        <div className="space-y-4">
          <div>
            <label htmlFor={providerSelectId} className={LABEL_CLASS}>
              Default provider
            </label>
            <select
              id={providerSelectId}
              value={ai.form.defaultProviderId}
              disabled={!canEdit}
              onChange={(e) => ai.setDefaultProvider(e.target.value)}
              className={INPUT_CLASS}
            >
              <option value="">Select a provider…</option>
              {ai.providers.map((p) => (
                <option key={p.id} value={p.id}>
                  {p.displayName}
                </option>
              ))}
            </select>
          </div>

          <ModelSelector
            models={modelsForDefault}
            value={ai.form.defaultModelId}
            onChange={ai.setDefaultModel}
            onRefresh={handleRefresh}
            refreshing={refreshing}
            disabled={!canEdit || !defaultProvider}
            noModelsHint={
              defaultProvider
                ? 'No models cached yet. Use “Refresh models” to load them.'
                : 'Select a default provider to choose a model.'
            }
          />
        </div>
      )}
    </SettingsCard>
  )
}

// ---------------------------------------------------------------------------
// Provider connections (manage multiple)
// ---------------------------------------------------------------------------

function ProviderConnectionsSection({ ai, canEdit }: { ai: UseAiSettings; canEdit: boolean }) {
  const [adding, setAdding] = useState(false)

  return (
    <SettingsCard
      title="Provider connections"
      description="Connect Anthropic, OpenAI, xAI, or a custom OpenAI-compatible endpoint."
      actions={
        canEdit && !adding ? (
          <button
            type="button"
            onClick={() => setAdding(true)}
            className="border-border text-foreground hover:bg-accent inline-flex items-center gap-1.5 rounded-md border px-3 py-1.5 text-sm transition-colors"
          >
            <Plus size={14} aria-hidden="true" />
            Add provider
          </button>
        ) : undefined
      }
    >
      <div className="space-y-3">
        {adding && (
          <AddProviderForm
            ai={ai}
            onDone={() => setAdding(false)}
            onCancel={() => setAdding(false)}
          />
        )}

        {ai.providers.map((p) => (
          <ProviderConnectionCard
            key={p.id}
            provider={p}
            canEdit={canEdit}
            busy={ai.busyProviderId === p.id}
            onTest={async () => {
              const res = await ai.testProvider(p.id)
              if (!res.ok) toast.error(res.error ?? res.message ?? 'Connection test failed.')
              else toast.success(res.message ?? 'Connection successful.')
            }}
            onSyncModels={async () => {
              const res = await ai.syncModels(p.id)
              if (!res.ok) toast.error(res.error ?? 'Failed to refresh models.')
              else if (res.fromFallback)
                toast.warning(res.warning ?? 'Showing the curated model list.')
              else toast.success('Model list refreshed.')
            }}
            onUpdateKey={async (apiKey) => {
              const res = await ai.updateProvider(p.id, { apiKey })
              if (!res.ok) toast.error(res.error ?? 'Failed to update key.')
              else toast.success('API key updated.')
            }}
            onUpdateBaseUrl={async (baseUrl) => {
              const res = await ai.updateProvider(p.id, { baseUrl })
              if (!res.ok) toast.error(res.error ?? 'Failed to update base URL.')
              else toast.success('Base URL updated.')
            }}
            onDisconnect={async () => {
              const res = await ai.deleteProvider(p.id)
              if (!res.ok) toast.error(res.error ?? 'Failed to disconnect.')
              else toast.success(`${p.displayName} disconnected.`)
            }}
          />
        ))}

        {ai.providers.length === 0 && !adding && (
          <p className="text-muted-foreground text-sm">No providers connected.</p>
        )}
      </div>
    </SettingsCard>
  )
}

function AddProviderForm({
  ai,
  onDone,
  onCancel,
}: {
  ai: UseAiSettings
  onDone: () => void
  onCancel: () => void
}) {
  const providerId = useId()
  const nameId = useId()
  const keyId = useId()
  const baseUrlId = useId()
  const [provider, setProvider] = useState<AiProviderKey>('anthropic')
  const [displayName, setDisplayName] = useState('')
  const [apiKey, setApiKey] = useState('')
  const [baseUrl, setBaseUrl] = useState('')
  const [submitting, setSubmitting] = useState(false)

  const needsBaseUrl = provider === 'custom'
  const canSubmit = !submitting && (!needsBaseUrl || baseUrl.trim() !== '')

  async function submit() {
    setSubmitting(true)
    try {
      const input: ProviderInput = {
        provider,
        displayName: displayName.trim() || undefined,
        apiKey: apiKey.trim() || undefined,
        baseUrl: needsBaseUrl ? baseUrl.trim() : undefined,
        test: true,
      }
      const res = await ai.createProvider(input)
      if (!res.ok) {
        toast.error(res.error ?? 'Failed to add provider.')
        return
      }
      toast.success('Provider connected.')
      onDone()
    } finally {
      setSubmitting(false)
    }
  }

  return (
    <div className="border-border bg-background rounded-lg border p-4">
      <h4 className="text-foreground mb-3 text-base font-medium">Add a provider</h4>
      <div className="space-y-3">
        <div>
          <label htmlFor={providerId} className={LABEL_CLASS}>
            Provider
          </label>
          <select
            id={providerId}
            value={provider}
            onChange={(e) => setProvider(e.target.value as AiProviderKey)}
            className={INPUT_CLASS}
          >
            {PROVIDER_OPTIONS.map((o) => (
              <option key={o.value} value={o.value}>
                {o.label}
              </option>
            ))}
          </select>
        </div>
        <div>
          <label htmlFor={nameId} className={LABEL_CLASS}>
            Display name (optional)
          </label>
          <input
            id={nameId}
            type="text"
            value={displayName}
            placeholder="e.g. Production Anthropic"
            onChange={(e) => setDisplayName(e.target.value)}
            className={INPUT_CLASS}
          />
        </div>
        {needsBaseUrl && (
          <div>
            <label htmlFor={baseUrlId} className={LABEL_CLASS}>
              Base URL
            </label>
            <input
              id={baseUrlId}
              type="url"
              value={baseUrl}
              placeholder="https://api.example.com/v1"
              onChange={(e) => setBaseUrl(e.target.value)}
              className={INPUT_CLASS}
            />
          </div>
        )}
        <div>
          <label htmlFor={keyId} className={LABEL_CLASS}>
            API key
          </label>
          <input
            id={keyId}
            type="password"
            autoComplete="off"
            spellCheck={false}
            value={apiKey}
            placeholder="Paste API key (or leave blank if set via environment)"
            onChange={(e) => setApiKey(e.target.value)}
            className={INPUT_CLASS}
          />
        </div>
        <div className="flex items-center justify-end gap-3 pt-1">
          <button
            type="button"
            onClick={onCancel}
            disabled={submitting}
            className="text-muted-foreground hover:text-foreground rounded-md px-3 py-2 text-sm transition-colors disabled:opacity-50"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={submit}
            disabled={!canSubmit}
            className="bg-brand text-brand-foreground inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50"
          >
            {submitting && <Loader2 size={14} className="animate-spin" aria-hidden="true" />}
            Connect &amp; test
          </button>
        </div>
      </div>
    </div>
  )
}
