'use client'

import { useState, useEffect, useCallback } from 'react'
import type { ApiProvider, ApiProviderStatus } from '@/lib/types'
import { readArrayResponse } from '@/lib/auth/client-redirect'

/** Drizzle 返回的 api_providers 行（camelCase 字段名，经 PROVIDER_SELECT 的 CASE 重映射 id） */
interface DbApiProvider {
  id: string
  name: string
  provider: string
  apiKey: string
  baseUrl: string
  modelName: string
  isActive: number
  status: string
  statusError: string
  createdAt: string
  updatedAt: string
}

function mapProvider(row: DbApiProvider): ApiProvider {
  return {
    id: row.id,
    name: row.name,
    provider: row.provider as ApiProvider['provider'],
    apiKey: row.apiKey,
    baseUrl: row.baseUrl,
    modelName: row.modelName || '',
    isActive: row.isActive === 1,
    status: (row.status || 'not_configured') as ApiProviderStatus,
    statusError: row.statusError || '',
    createdAt: row.createdAt,
    updatedAt: row.updatedAt,
  }
}

export function useApiProviders() {
  const [providers, setProviders] = useState<ApiProvider[]>([])
  const [loading, setLoading] = useState(true)

  const fetchProviders = useCallback(async () => {
    try {
      const res = await fetch('/api/api-providers')
      if (!res.ok) throw new Error(`Failed to load providers: ${res.status}`)
      const data = await readArrayResponse<DbApiProvider>(res)
      setProviders(data.map(mapProvider))
    } catch {
      // 静默失败：provider 列表加载失败不应阻塞 UI
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => { fetchProviders() }, [fetchProviders])

  const updateProvider = useCallback(async (id: string, updates: Record<string, unknown>) => {
    const res = await fetch(`/api/api-providers/${id}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(updates),
    })
    if (!res.ok) {
      let msg = `Failed to update provider (${res.status})`
      try { const data = await res.json(); if (data?.error) msg = data.error } catch { /* ignore */ }
      throw new Error(msg)
    }
    const updated = await res.json() as DbApiProvider
    const mapped = mapProvider(updated)
    setProviders((prev) => prev.map((p) => (p.id === id ? mapped : p)))
    return mapped
  }, [])

  const testConnection = useCallback(async (id: string) => {
    setProviders((prev) => prev.map((p) => (p.id === id ? { ...p, status: 'testing' as ApiProviderStatus, statusError: '' } : p)))
    try {
      const res = await fetch(`/api/api-providers/${id}/test`, { method: 'POST' })
      if (!res.ok) {
        setProviders((prev) => prev.map((p) => (p.id === id ? { ...p, status: 'error' as ApiProviderStatus, statusError: `Failed to test provider (${res.status})` } : p)))
        return null
      }
      const data = await res.json() as DbApiProvider
      const mapped = mapProvider(data)
      setProviders((prev) => prev.map((p) => (p.id === id ? mapped : p)))
      return mapped
    } catch {
      setProviders((prev) => prev.map((p) => (p.id === id ? { ...p, status: 'error' as ApiProviderStatus, statusError: 'Network error' } : p)))
      return null
    }
  }, [])

  const createProvider = useCallback(async (data: { name: string; baseUrl: string; apiKey: string; modelName: string }): Promise<ApiProvider> => {
    const res = await fetch('/api/api-providers', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    })
    if (!res.ok) {
      let msg = `Failed to create provider (${res.status})`
      try { const e = await res.json(); if (e?.error) msg = e.error } catch { /* ignore */ }
      throw new Error(msg)
    }
    const createdRow = await res.json() as DbApiProvider
    const created = mapProvider(createdRow)
    setProviders((prev) => [...prev, created])
    return created
  }, [])

  const deleteProvider = useCallback(async (id: string) => {
    const res = await fetch(`/api/api-providers/${id}`, { method: 'DELETE' })
    if (!res.ok) {
      let msg = `Failed to delete provider (${res.status})`
      try { const data = await res.json(); if (data?.error) msg = data.error } catch { /* ignore */ }
      throw new Error(msg)
    }
    await fetchProviders()
  }, [fetchProviders])

  return { providers, loading, updateProvider, testConnection, createProvider, deleteProvider, refreshProviders: fetchProviders }
}