import { useState, useRef, useEffect } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import { CheckCircle2, XCircle, Loader2, Zap, ChevronRight, HardDrive } from 'lucide-react'
import toast from 'react-hot-toast'
import { useAppStore } from '../store/app'
import { Button, Input, Card } from '../components/ui'
import { clsx } from '../lib/clsx'
import { useMode, MODE_META, type DeploymentMode } from '../api/mode'

// ── Step helpers ──────────────────────────────────────────────────

type StepState = 'idle' | 'loading' | 'ok' | 'error'

function StepIndicator({ n, label, active, done }: { n: number; label: string; active: boolean; done: boolean }) {
  return (
    <div className={clsx('flex items-center gap-3', !active && !done && 'opacity-40')}>
      <div
        className={clsx(
          'w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold shrink-0',
          done ? 'bg-green-500 text-white' : active ? 'bg-indigo-600 text-white' : 'bg-gray-200 text-gray-500',
        )}
      >
        {done ? <CheckCircle2 size={16} /> : n}
      </div>
      <span className={clsx('text-sm font-medium', active ? 'text-gray-900' : 'text-gray-500')}>{label}</span>
    </div>
  )
}

// ── Step 1: Environment check ─────────────────────────────────────

interface DataDirInfo {
  data_dir: string
  is_default: boolean
  mode: string
  subdirs?: { instances?: string; knowledge_bases?: string; logs?: string }
}

function Step1({ onNext }: { onNext: () => void }) {
  const [state, setState] = useState<StepState>('idle')
  const [info, setInfo] = useState<{ ok: boolean; python?: string; platform?: string } | null>(null)
  // FR-002: show the user where their research data lives. Fetched
  // after the env check succeeds; the endpoint is loopback-only and the
  // wizard runs on the user's own machine, so it resolves locally.
  const [dataDir, setDataDir] = useState<DataDirInfo | null>(null)

  async function check() {
    setState('loading')
    try {
      const res = await fetch('/api/v1/setup/health')
      const data = await res.json()
      setInfo(data)
      if (data.ok) {
        try {
          const ddRes = await fetch('/api/v1/setup/data-dir')
          if (ddRes.ok) setDataDir(await ddRes.json())
        } catch {
          /* data-dir is informational; don't block the wizard */
        }
      }
      setState(data.ok ? 'ok' : 'error')
    } catch {
      setInfo({ ok: false })
      setState('error')
    }
  }

  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-lg font-semibold text-gray-900">环境检测</h2>
        <p className="mt-1 text-sm text-gray-500">检查本地服务是否正在运行。</p>
      </div>

      {state === 'idle' && (
        <Button onClick={check} size="lg" className="w-full">
          开始检测
        </Button>
      )}

      {state === 'loading' && (
        <div className="flex items-center gap-3 py-4 text-sm text-gray-600">
          <Loader2 size={18} className="animate-spin text-indigo-600" />
          正在连接服务…
        </div>
      )}

      {(state === 'ok' || state === 'error') && info && (
        <div
          className={clsx(
            'rounded-xl border p-4 space-y-2',
            info.ok ? 'border-green-200 bg-green-50' : 'border-red-200 bg-red-50',
          )}
        >
          <div className="flex items-center gap-2">
            {info.ok ? (
              <CheckCircle2 size={18} className="text-green-600" />
            ) : (
              <XCircle size={18} className="text-red-600" />
            )}
            <span className={clsx('text-sm font-medium', info.ok ? 'text-green-700' : 'text-red-700')}>
              {info.ok ? '服务运行正常' : '无法连接到服务'}
            </span>
          </div>
          {info.python && (
            <p className="text-xs text-gray-600 pl-6">
              Python {info.python} · {info.platform}
            </p>
          )}
          {!info.ok && (
            <p className="text-xs text-gray-600 pl-6">
              请先在终端运行：<code className="bg-white px-1 rounded">agentpaas serve --dev</code>
            </p>
          )}
        </div>
      )}

      {/* FR-002: data directory location */}
      {state === 'ok' && dataDir && (
        <div className="rounded-xl border border-gray-200 bg-gray-50 p-4 space-y-1.5">
          <div className="flex items-center gap-2 text-sm font-medium text-gray-700">
            <HardDrive size={16} className="text-gray-500" />
            你的资料保存在本机
          </div>
          <code className="block text-xs text-gray-600 bg-white border border-gray-200 rounded px-2 py-1.5 break-all">
            {dataDir.data_dir}
          </code>
          <p className="text-[11px] text-gray-400 leading-relaxed">
            论文、笔记、索引、任务产物都存放在这个目录里，不会上传到任何服务器。
            {dataDir.mode === 'desktop' && ' 可在「模型与隐私」中查看或更换位置（需重启生效）。'}
          </p>
        </div>
      )}

      {state === 'ok' && (
        <Button onClick={onNext} size="lg" className="w-full" icon={<ChevronRight size={16} />}>
          下一步
        </Button>
      )}

      {state === 'error' && (
        <Button onClick={check} variant="secondary" size="lg" className="w-full">
          重新检测
        </Button>
      )}
    </div>
  )
}

// ── Step 2: Provider selection ────────────────────────────────────

export interface ProviderChoice {
  id: string
  apiKey: string
}

const QUICK_PROVIDERS = [
  {
    id: 'claude-code',
    name: 'Claude Code',
    desc: '使用本地 Claude Code 订阅，无需 API Key',
    noKey: true,
    badge: '推荐',
  },
  {
    id: 'ollama',
    name: 'Ollama（本地模型）',
    desc: '完全本地运行，免费，需要先安装 Ollama',
    noKey: true,
    badge: '免费',
  },
  {
    id: 'dashscope',
    name: '阿里云通义千问',
    desc: 'DashScope API，国内访问稳定',
    noKey: false,
    placeholder: 'sk-...',
  },
  {
    id: 'deepseek',
    name: 'DeepSeek',
    desc: '性价比极高的国产大模型',
    noKey: false,
    placeholder: 'sk-...',
  },
  {
    id: 'anthropic',
    name: 'Anthropic (Claude API)',
    desc: '直接调用 Anthropic API',
    noKey: false,
    placeholder: 'sk-ant-...',
  },
]

function Step2({ onNext }: { onNext: (choice: ProviderChoice) => void }) {
  const [selected, setSelected] = useState<string | null>(null)
  const [apiKey, setApiKey] = useState('')

  const provider = QUICK_PROVIDERS.find(p => p.id === selected)
  const canProceed = !!selected && (provider?.noKey || !!apiKey)

  return (
    <div className="space-y-5">
      <div>
        <h2 className="text-lg font-semibold text-gray-900">选择 AI 模型</h2>
        <p className="mt-1 text-sm text-gray-500">
          选择智能体使用的 AI 提供商。API Key 将在下一步完成初始化后保存。
        </p>
      </div>

      <div className="space-y-2">
        {QUICK_PROVIDERS.map(p => (
          <button
            key={p.id}
            onClick={() => { setSelected(p.id); setApiKey('') }}
            className={clsx(
              'w-full text-left rounded-xl border p-4 transition-colors',
              selected === p.id
                ? 'border-indigo-500 bg-indigo-50 ring-1 ring-indigo-500'
                : 'border-gray-200 hover:border-gray-300 bg-white',
            )}
          >
            <div className="flex items-center justify-between">
              <span className="text-sm font-medium text-gray-900">{p.name}</span>
              {p.badge && (
                <span className="text-xs bg-green-100 text-green-700 px-2 py-0.5 rounded-full font-medium">
                  {p.badge}
                </span>
              )}
            </div>
            <p className="mt-0.5 text-xs text-gray-500">{p.desc}</p>
          </button>
        ))}
      </div>

      {selected && !provider?.noKey && (
        <Input
          label="API Key"
          type="password"
          placeholder={provider?.placeholder ?? 'sk-...'}
          value={apiKey}
          onChange={e => setApiKey(e.target.value)}
          hint="仅保存在本机，不会上传"
        />
      )}

      <Button
        onClick={() => canProceed && onNext({ id: selected!, apiKey })}
        size="lg"
        className="w-full"
        disabled={!canProceed}
        icon={<ChevronRight size={16} />}
      >
        {canProceed ? '继续' : '请先选择提供商'}
      </Button>
    </div>
  )
}

// ── Step 3: Bootstrap ─────────────────────────────────────────────

function Step3({ providerChoice, onDone }: { providerChoice: ProviderChoice; onDone: (key: string) => void }) {
  const [state, setState] = useState<StepState>('idle')
  const [message, setMessage] = useState('')
  const [manualKey, setManualKey] = useState('')
  const [showManual, setShowManual] = useState(false)
  const mountedRef = useRef(true)
  useEffect(() => { return () => { mountedRef.current = false } }, [])

  async function saveProvider(apiKey: string) {
    if (!providerChoice.apiKey) return
    await fetch(`/api/v1/providers/${providerChoice.id}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
      body: JSON.stringify({ api_key: providerChoice.apiKey }),
    })
  }

  async function bootstrap() {
    if (state === 'loading') return
    setState('loading')
    setMessage('')
    try {
      const res = await fetch('/api/v1/setup/bootstrap', { method: 'POST' })
      const data = await res.json()

      if (data.status === 'created') {
        await saveProvider(data.api_key)
        if (!mountedRef.current) return
        setMessage('平台初始化成功！')
        setState('ok')
        setTimeout(() => { if (mountedRef.current) onDone(data.api_key) }, 800)
      } else if (data.status === 'already_configured') {
        setMessage(`已有配置（Key 前缀：${data.key_prefix}...），请粘贴现有 API Key 继续。`)
        setShowManual(true)
        setState('idle')
      } else if (data.status === 'tenant_exists') {
        setMessage(data.message)
        setShowManual(true)
        setState('idle')
      } else {
        setMessage(JSON.stringify(data))
        setState('error')
      }
    } catch (e) {
      setMessage(`连接失败: ${e}`)
      setState('error')
    }
  }

  return (
    <div className="space-y-5">
      <div>
        <h2 className="text-lg font-semibold text-gray-900">初始化平台</h2>
        <p className="mt-1 text-sm text-gray-500">创建本地租户并生成 API Key，完成后自动进入管理界面。</p>
      </div>

      {state === 'idle' && !showManual && (
        <Button onClick={bootstrap} size="lg" className="w-full" icon={<Zap size={16} />}>
          一键初始化
        </Button>
      )}

      {state === 'loading' && (
        <div className="flex items-center gap-3 py-4 text-sm text-gray-600">
          <Loader2 size={18} className="animate-spin text-indigo-600" />
          正在初始化…
        </div>
      )}

      {message && (
        <div
          className={clsx(
            'rounded-lg border p-3 text-sm',
            state === 'ok' || showManual
              ? 'border-blue-200 bg-blue-50 text-blue-700'
              : 'border-red-200 bg-red-50 text-red-700',
          )}
        >
          {message}
        </div>
      )}

      {showManual && (
        <div className="space-y-3">
          <p className="text-sm text-gray-600">
            请在终端运行 <code className="bg-gray-100 px-1 rounded text-xs">agentpaas create-tenant --name local</code>，
            然后将输出的 API Key 粘贴到下方：
          </p>
          <Input
            label="API Key"
            type="password"
            placeholder="ap_..."
            value={manualKey}
            onChange={e => setManualKey(e.target.value)}
          />
          <Button
            onClick={async () => {
              if (!manualKey.startsWith('ap_')) return
              await saveProvider(manualKey)
              onDone(manualKey)
            }}
            disabled={!manualKey.startsWith('ap_')}
            size="lg"
            className="w-full"
          >
            进入管理界面
          </Button>
        </div>
      )}

      {state === 'error' && (
        <Button onClick={bootstrap} variant="secondary" size="lg" className="w-full">
          重试
        </Button>
      )}
    </div>
  )
}

// ── Main wizard ───────────────────────────────────────────────────

export default function SetupWizard() {
  const [step, setStep] = useState(1)
  const [providerChoice, setProviderChoice] = useState<ProviderChoice>({ id: '', apiKey: '' })
  const { setApiKey } = useAppStore()
  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const { data: modeData } = useMode()
  const mode = (modeData?.mode ?? 'desktop') as DeploymentMode
  const brand = MODE_META[mode].brand

  // ?reconfigure=1 means the user explicitly clicked "切换数据 / 重新配置".
  // In that case we must show the full wizard; auto-login would immediately
  // bounce them back to /dashboard, making the button a no-op.
  const isReconfigure = searchParams.get('reconfigure') === '1'

  function handleDone(key: string) {
    setApiKey(key)
    toast.success('配置完成，欢迎使用！')
    navigate('/dashboard')
  }

  // FR-001 one-click desktop login: if the server already auto-bootstrapped
  // a tenant (mode=desktop + bootstrapped), grab the key from the
  // loopback-only /setup/desktop-key endpoint and skip straight into the
  // app. A professor double-clicking the app should NOT have to paste a
  // key. Dogfooding found the wizard otherwise dead-ends here.
  // EXCEPTION: skip auto-login when the user arrived via "切换数据 / 重新配置"
  // (?reconfigure=1) — they want to see the wizard, not bounce back.
  useEffect(() => {
    if (isReconfigure) return          // user wants to reconfigure — show wizard
    if (mode !== 'desktop' || !modeData?.bootstrapped) return
    let cancelled = false
    ;(async () => {
      try {
        const r = await fetch('/api/v1/setup/desktop-key')
        if (!r.ok) return // fall back to the manual wizard
        const data = await r.json()
        if (!cancelled && data.api_key) {
          setApiKey(data.api_key)
          navigate('/dashboard')
        }
      } catch {
        /* fall back to manual wizard */
      }
    })()
    return () => {
      cancelled = true
    }
  }, [isReconfigure, mode, modeData?.bootstrapped, setApiKey, navigate])

  const steps = [
    { n: 1, label: '环境检测' },
    { n: 2, label: '选择模型' },
    { n: 3, label: mode === 'desktop' ? '完成设置' : '初始化平台' },
  ]

  return (
    <div className="min-h-screen bg-gray-50 flex items-center justify-center p-4">
      <div className="w-full max-w-lg">
        {/* Header */}
        <div className="text-center mb-8">
          <div className="inline-flex items-center gap-2 mb-3">
            <Zap size={28} className="text-indigo-600" />
            <span className="text-2xl font-bold text-gray-900">{brand}</span>
          </div>
          <p className="text-sm text-gray-500">
            {mode === 'desktop' ? '本地科研工作台 · 首次安装向导' : '本地管理界面 · 首次安装向导'}
          </p>
        </div>

        <Card>
          {/* Step indicators */}
          <div className="flex items-center gap-2 mb-8">
            {steps.map((s, i) => (
              <div key={s.n} className="flex items-center gap-2 flex-1">
                <StepIndicator n={s.n} label={s.label} active={step === s.n} done={step > s.n} />
                {i < steps.length - 1 && (
                  <div className={clsx('h-px flex-1 mx-2', step > s.n ? 'bg-green-400' : 'bg-gray-200')} />
                )}
              </div>
            ))}
          </div>

          {step === 1 && <Step1 onNext={() => setStep(2)} />}
          {step === 2 && (
            <Step2
              onNext={choice => {
                setProviderChoice(choice)
                setStep(3)
              }}
            />
          )}
          {step === 3 && <Step3 providerChoice={providerChoice} onDone={handleDone} />}
        </Card>
      </div>
    </div>
  )
}
