import useSWR, { SWRConfiguration } from "swr";
import {
  BatchFinancialDataResponse,
  TodaySnapshotResponse,
  RealTimeQuoteResponse,
  LlmProvidersConfig,
  AnalysisTemplateSets, // New type
  FinancialConfigResponse,
  DataSourcesConfig,
  AnalysisResultDto,
} from "@/types";
import { useEffect, useState } from "react";
import { useConfigStore } from "@/stores/useConfigStore";
import type { SystemConfig } from "@/stores/useConfigStore";

const fetcher = (url: string) => fetch(url).then((res) => res.json());

// --- 新的异步任务Hooks ---

// 用于触发数据获取任务
export function useDataRequest() {
  const [isMutating, setIsMutating] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  const trigger = async (symbol: string, market: string, templateId?: string): Promise<string | undefined> => {
    setIsMutating(true);
    setError(null);
    try {
      const res = await fetch(`/api/data-requests`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ symbol, market, template_id: templateId }),
      });

      if (!res.ok) {
        throw new Error(`Request failed with status ${res.status}`);
      }
      
      const data = await res.json();
      return data.request_id;
    } catch (e: any) {
      setError(e);
    } finally {
      setIsMutating(false);
    }
  };

  return {
    trigger,
    isMutating,
    error,
  };
}



// [DEPRECATED] Used for polling, logic removed.
// Backend now pushes progress via SSE.
export function useTaskProgress(requestId: string | null, options?: SWRConfiguration) {
  const { data, error, isLoading } = useSWR<TaskProgress[]>(
    null, // Disable polling
    fetcher,
    options
  );

  return {
    tasks: [],
    progress: null,
    isLoading: false,
    isError: null,
    isFinished: false,
  };
}


// --- Analysis Results Hooks (NEW) ---

export function useAnalysisResults(symbol?: string) {
  return useSWR<AnalysisResultDto[]>(
    symbol ? `/api/analysis-results?symbol=${encodeURIComponent(symbol)}` : null,
    fetcher,
    {
      refreshInterval: 5000, // Poll for new results
    }
  );
}


// --- 保留的旧Hooks (用于查询最终数据) ---

export function useCompanyProfile(symbol?: string, market?: string) {
  const { data, error, isLoading } = useSWR(
    symbol && market ? `/api/companies/${symbol}/profile` : null,
    fetcher
  );

  return {
    profile: data,
    isLoading,
    isError: error,
  };
}

// ... 这里的其他数据查询Hooks (如财务报表等) 也将遵循类似的模式，
// 直接从api-gateway查询持久化后的数据 ...


// --- 废弃的旧Hooks ---

/**
 * @deprecated This hook is deprecated and will be removed.
 * Use useDataRequest and useTaskProgress instead.
 */
export function useChinaFinancials(ts_code?: string, years: number = 10) {
  return useSWR<BatchFinancialDataResponse>(
    ts_code ? `/api/financials/cn/${encodeURIComponent(ts_code)}?years=${encodeURIComponent(String(years))}` : null,
    fetcher,
    {
      revalidateOnFocus: false,      // 不在窗口聚焦时重新验证
      revalidateOnReconnect: false,  // 不在网络重连时重新验证
      dedupingInterval: 300000,      // 5分钟内去重
      errorRetryCount: 1,            // 错误重试1次
    }
  );
}

export function useFinancials(market?: string, stockCode?: string, years: number = 10) {
  const normalizeMarket = (m?: string) => {
    const t = (m || '').toLowerCase();
    if (t === 'usa') return 'us';
    if (t === 'china') return 'cn';
    if (t === 'hkex') return 'hk';
    if (t === 'jpn') return 'jp';
    return t;
  };
  const mkt = normalizeMarket(market);
  return useSWR<BatchFinancialDataResponse>(
    mkt && stockCode ? `/api/financials/${encodeURIComponent(mkt)}/${encodeURIComponent(stockCode)}?years=${encodeURIComponent(String(years))}` : null,
    fetcher,
    {
      revalidateOnFocus: false,
      revalidateOnReconnect: false,
      dedupingInterval: 300000,
      errorRetryCount: 1,
    }
  );
}

export function useChinaSnapshot(ts_code?: string) {
  return useSWR<TodaySnapshotResponse>(
    ts_code ? `/api/financials/china/${encodeURIComponent(ts_code)}/snapshot` : null,
    fetcher,
    {
      revalidateOnFocus: false,
      revalidateOnReconnect: false,
      dedupingInterval: 120000, // 2分钟
      errorRetryCount: 1,
    }
  );
}

export function useSnapshot(market?: string, stockCode?: string) {
  const normalizeMarket = (m?: string) => {
    const t = (m || '').toLowerCase();
    if (t === 'usa') return 'us';
    if (t === 'china') return 'cn';
    if (t === 'hkex') return 'hk';
    if (t === 'jpn') return 'jp';
    return t;
  };
  const mkt = normalizeMarket(market);
  return useSWR<TodaySnapshotResponse>(
    mkt && stockCode ? `/api/financials/${encodeURIComponent(mkt)}/${encodeURIComponent(stockCode)}/snapshot` : null,
    fetcher,
    {
      revalidateOnFocus: false,
      revalidateOnReconnect: false,
      dedupingInterval: 120000,
      errorRetryCount: 1,
    }
  );
}

export function useRealtimeQuote(
  market?: string,
  stockCode?: string,
  options?: {
    maxAgeSeconds?: number;
    refreshIntervalMs?: number;
  }
) {
  const normalizeMarket = (m?: string) => {
    const t = (m || '').toLowerCase();
    if (t === 'usa') return 'us';
    if (t === 'china') return 'cn';
    if (t === 'hkex') return 'hk';
    if (t === 'jpn') return 'jp';
    return t;
  };
  const mkt = normalizeMarket(market);
  const maxAge = options?.maxAgeSeconds ?? 30;
  const refreshMs = options?.refreshIntervalMs ?? 5000;
  return useSWR<RealTimeQuoteResponse>(
    mkt && stockCode ? `/api/financials/${encodeURIComponent(mkt)}/${encodeURIComponent(stockCode)}/realtime?max_age_seconds=${encodeURIComponent(String(maxAge))}` : null,
    fetcher,
    {
      revalidateOnFocus: false,
      revalidateOnReconnect: false,
      refreshInterval: refreshMs,
      dedupingInterval: Math.min(1000, refreshMs),
      shouldRetryOnError: false,
      errorRetryCount: 0,
    }
  );
}

// ===============================
// 配置相关 Hooks 与函数
// ===============================

export function useConfig() {
  const { setConfig, setError, setLoading } = useConfigStore();
  const { data, error, isLoading } = useSWR<SystemConfig>('/api/config', fetcher, {
    revalidateOnFocus: false,
  });

  useEffect(() => {
    setLoading(Boolean(isLoading));
    if (error) {
      setError('加载配置失败');
    } else if (data) {
      setConfig(data);
    }
  }, [data, error, isLoading, setConfig, setError, setLoading]);
  return { data, error, isLoading };
}

export async function updateConfig(payload: Partial<SystemConfig>) {
  // Deprecated
  throw new Error("updateConfig is deprecated. Use specific update functions.");
}

export async function testConfig(type: string, data: any) {
  // Flat the data object to match backend expectation (#[serde(flatten)])
  const payload = {
    type,
    ...(typeof data === 'object' ? data : {})
  };

  // Use /api/configs/test to match backend /v1/configs/test via Rewrite
  const res = await fetch('/api/configs/test', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });
  const text = await res.text();
  if (!res.ok) {
    try {
      const err = JSON.parse(text);
      // 优先从标准字段中提取错误信息；同时分离 details
      const message: string = err?.error || err?.message || '';
      let detailsStr = '';
      if (err?.details !== undefined) {
        if (typeof err.details === 'string') {
          detailsStr = err.details;
          // details 可能是被 JSON 序列化的字符串，尝试解析一次以便还原内部结构
          try {
            const parsed = JSON.parse(detailsStr);
            if (typeof parsed === 'string') {
              detailsStr = parsed;
            } else if (parsed && typeof parsed === 'object' && 'message' in parsed) {
              detailsStr = String((parsed as any).message);
            } else {
              detailsStr = JSON.stringify(parsed);
            }
          } catch {
            // 忽略解析失败，保留原始 details 字符串
          }
        } else {
          try {
            detailsStr = JSON.stringify(err.details);
          } catch {
            detailsStr = String(err.details);
          }
        }
      }
      const summary = message || `HTTP ${res.status}`;
      const detailsOut = (detailsStr && detailsStr.length > 0) ? detailsStr : (text || undefined);
      // 抛出结构化错误对象，供调用方精确展示（details 始终尽量携带原始响应体，便于前端美化）
      throw { summary, details: detailsOut };
    } catch {
      // 无法解析为 JSON 时，仍然把原始文本作为 details 返回，保证前端可美化
      const fallback = text || `HTTP ${res.status}`;
      throw { summary: fallback, details: text || undefined };
    }
  }
  try {
    return JSON.parse(text);
  } catch {
    return { success: true, message: text || 'OK' };
  }
}

export function useFinancialConfig() {
  // 透传后端的财务配置（如指标分组、显示名映射等）
  // 新后端暂未提供该配置，使用 Partial 以避免严格要求字段存在
  return useSWR<Partial<FinancialConfigResponse>>('/api/config', fetcher);
}

// --- LLM Provider Config Hooks ---

export function useLlmProviders() {
  return useSWR<LlmProvidersConfig>('/api/configs/llm_providers', fetcher);
}

export async function updateLlmProviders(payload: LlmProvidersConfig) {
    const res = await fetch('/api/configs/llm_providers', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
    });
    if (!res.ok) {
        const text = await res.text().catch(() => '');
        throw new Error(text || `HTTP ${res.status}`);
    }
    return res.json() as Promise<LlmProvidersConfig>;
}

export async function discoverProviderModels(providerId: string) {
    const res = await fetch(`/api/discover-models/${providerId}`);
    // No error handling for status, as the gateway will return a structured error
    return res.json();
}

export async function discoverProviderModelsPreview(apiBaseUrl: string, apiKey: string) {
  const res = await fetch(`/api/discover-models`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ api_base_url: apiBaseUrl, api_key: apiKey }),
  });
  return res.json();
}

export async function testLlmModel(apiBaseUrl: string, apiKey: string, modelId: string) {
  const res = await fetch('/api/configs/llm/test', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ api_base_url: apiBaseUrl, api_key: apiKey, model_id: modelId }),
  });
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(text || `HTTP ${res.status}`);
  }
  return res.json();
}

// --- Analysis Template Sets Config Hooks (NEW) ---

export function useAnalysisTemplateSets() {
  return useSWR<AnalysisTemplateSets>('/api/configs/analysis_template_sets', fetcher);
}

export async function updateAnalysisTemplateSets(payload: AnalysisTemplateSets) {
    const res = await fetch('/api/configs/analysis_template_sets', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
    });
    if (!res.ok) {
        const text = await res.text().catch(() => '');
        throw new Error(text || `HTTP ${res.status}`);
    }
    return res.json() as Promise<AnalysisTemplateSets>;
}

// --- Data Sources Config Hooks ---

export function useDataSourcesConfig() {
  return useSWR<DataSourcesConfig>('/api/configs/data_sources', fetcher);
}

export async function updateDataSourcesConfig(payload: DataSourcesConfig) {
  const res = await fetch('/api/configs/data_sources', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(text || `HTTP ${res.status}`);
  }
  return res.json() as Promise<DataSourcesConfig>;
}
