import { useEffect, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { apiFetch } from '../lib/api';
import { SettingsSkeleton } from './Skeleton';
import type { AIProvider, ScanSchedule, Settings as SettingsType } from '../lib/types';

const PROVIDERS: { value: AIProvider; label: string; models: string[]; needsKey: boolean }[] = [
  { value: 'none',      label: 'None (scan and widget only, no AI)', models: [],                                                    needsKey: false },
  { value: 'anthropic', label: 'Anthropic Claude',                   models: ['claude-haiku-4-5-20251001', 'claude-sonnet-4-20250514'], needsKey: true  },
  { value: 'openai',    label: 'OpenAI',                             models: ['gpt-4o-mini', 'gpt-4o'],                            needsKey: true  },
  { value: 'gemini',    label: 'Google Gemini',                      models: ['gemini-1.5-flash', 'gemini-1.5-pro'],               needsKey: true  },
  { value: 'ollama',    label: 'Ollama (local)',                      models: ['llama3.2', 'mistral', 'phi3'],                     needsKey: false },
];

const SCHEDULES: { value: ScanSchedule; label: string }[] = [
  { value: 'daily',   label: 'Daily'   },
  { value: 'weekly',  label: 'Weekly'  },
  { value: 'monthly', label: 'Monthly' },
];

export default function Settings() {
  const qc = useQueryClient();

  const { data: saved, isLoading } = useQuery({
    queryKey: ['settings'],
    queryFn: () => apiFetch<SettingsType>('/settings'),
    retry: false,
  });

  const [provider, setProvider] = useState<AIProvider>('none');
  const [apiKey, setApiKey]     = useState('');
  const [showKey, setShowKey]   = useState(false);
  const [model, setModel]       = useState('');
  const [schedule, setSchedule] = useState<ScanSchedule>('weekly');
  const [saveOk, setSaveOk]     = useState(false);

  // Hydrate form from server once loaded.
  useEffect(() => {
    if (!saved) return;
    setProvider(saved.ai_provider);
    setSchedule(saved.scan_schedule);
    setModel(saved.ai_model || (PROVIDERS.find((p) => p.value === saved.ai_provider)?.models[0] ?? ''));
  }, [saved]);

  const save = useMutation({
    mutationFn: () =>
      apiFetch<{ saved: boolean }>('/settings', {
        method: 'POST',
        body: JSON.stringify({ ai_provider: provider, ai_key: apiKey, ai_model: model, scan_schedule: schedule }),
      }),
    onSuccess: () => {
      setSaveOk(true);
      setApiKey('');
      qc.invalidateQueries({ queryKey: ['settings'] });
      setTimeout(() => setSaveOk(false), 3000);
    },
  });

  const testConnection = useMutation({
    mutationFn: () =>
      apiFetch<{ text?: string; error?: string }>('/ai/proxy', {
        method: 'POST',
        body: JSON.stringify({ task: 'explain', params: { title: 'test', wcag: '1.1.1' } }),
      }),
  });

  const providerDef = PROVIDERS.find((p) => p.value === provider)!;

  if (isLoading) return <SettingsSkeleton />;

  return (
    <div className="aai-settings">
      <h2>Settings</h2>

      {/* AI Provider */}
      <section className="aai-settings__section">
        <h3>AI Provider</h3>
        <p className="aai-muted">
          AI features are optional. The API key is stored encrypted in{' '}
          <code>wp_options</code> and never sent to the browser.
        </p>

        <fieldset className="aai-field aai-field--fieldset">
          <legend className="screen-reader-text">Select AI provider</legend>
          {PROVIDERS.map((p) => (
            <label key={p.value} className="aai-radio">
              <input
                type="radio"
                name="ai_provider"
                value={p.value}
                checked={provider === p.value}
                onChange={() => {
                  setProvider(p.value);
                  setModel(p.models[0] ?? '');
                  setApiKey('');
                  testConnection.reset();
                }}
              />
              {p.label}
            </label>
          ))}
        </fieldset>

        {providerDef.models.length > 0 && (
          <label className="aai-field">
            <span>Model</span>
            <select value={model} onChange={(e) => setModel(e.target.value)}>
              {providerDef.models.map((m) => (
                <option key={m} value={m}>{m}</option>
              ))}
            </select>
          </label>
        )}

        {providerDef.needsKey && (
          <div className="aai-field aai-field--key">
            <label htmlFor="aai-api-key">
              API Key
              {saved?.ai_key_set && !apiKey && (
                <span className="aai-key-set"> (key saved — enter a new one to replace)</span>
              )}
            </label>
            <div className="aai-field__key-row">
              <input
                id="aai-api-key"
                type={showKey ? 'text' : 'password'}
                value={apiKey}
                onChange={(e) => { setApiKey(e.target.value); testConnection.reset(); }}
                placeholder={saved?.ai_key_set ? '••••••••••••••••' : 'Paste your API key'}
                autoComplete="off"
              />
              <button
                type="button"
                className="aai-btn aai-btn--ghost"
                onClick={() => setShowKey((s) => !s)}
                aria-label={showKey ? 'Hide API key' : 'Show API key'}
              >
                {showKey ? 'Hide' : 'Show'}
              </button>
              <button
                type="button"
                className="aai-btn aai-btn--ghost"
                onClick={() => testConnection.mutate()}
                disabled={testConnection.isPending || (!apiKey && !saved?.ai_key_set)}
              >
                {testConnection.isPending
                  ? <><span className="aai-spinner aai-spinner--dark" aria-hidden="true" /> Testing…</>
                  : 'Test connection'
                }
              </button>
            </div>

            {/* Test connection feedback */}
            {testConnection.isSuccess && !testConnection.data?.error && (
              <p className="aai-success">Connection verified.</p>
            )}
            {(testConnection.isError || testConnection.data?.error) && (
              <p className="aai-error">
                {testConnection.data?.error ?? (testConnection.error as Error)?.message ?? 'Connection failed.'}
              </p>
            )}
          </div>
        )}
      </section>

      {/* Scan schedule */}
      <section className="aai-settings__section">
        <h3>Scheduled Scans</h3>
        <label className="aai-field">
          <span>Frequency</span>
          <select value={schedule} onChange={(e) => setSchedule(e.target.value as ScanSchedule)}>
            {SCHEDULES.map((s) => (
              <option key={s.value} value={s.value}>{s.label}</option>
            ))}
          </select>
        </label>
      </section>

      {/* Accessibility note */}
      <section className="aai-settings__section aai-settings__section--note">
        <p className="aai-muted">
          <strong>Accessibility note:</strong> AccessMate uses automated scanning to identify and help fix accessibility issues. Automated tools can detect only a subset of accessibility problems. For full WCAG 2.1 AA compliance, manual testing — including testing with assistive technologies such as screen readers — is recommended.
        </p>
        <p className="aai-muted" style={{ marginTop: 8 }}>
          AccessMate helps you find and fix accessibility issues faster. It does not replace a full manual accessibility audit.
        </p>
      </section>

      {/* Save */}
      <div className="aai-settings__save-row">
        <button
          className="aai-btn aai-btn--primary"
          onClick={() => save.mutate()}
          disabled={save.isPending}
        >
          {save.isPending
            ? <><span className="aai-spinner" aria-hidden="true" /> Saving…</>
            : 'Save Settings'
          }
        </button>
        {saveOk && <span className="aai-success">Saved.</span>}
        {save.isError && (
          <span className="aai-error">{(save.error as Error).message}</span>
        )}
      </div>
    </div>
  );
}
