/**
 * 通用 SWR Hooks
 * 封装 useSWR + fetchWithAuth，统一处理加载/错误/重试逻辑
 */

import useSWR, { type SWRConfiguration, type KeyedMutator } from "swr";
import { useCallback, useState } from "react";
import { fetchWithAuth } from "@/lib/api/client";

// ── 类型定义 ────────────────────────────────────────────────────────────────────

export interface UseApiReturn<T> {
  data: T | undefined;
  isLoading: boolean;
  error: Error | undefined;
  mutate: KeyedMutator<T>;
  /** 手动重新获取数据 */
  refresh: () => void;
}

export interface UsePaginatedApiReturn<T> extends UseApiReturn<T[]> {
  total: number;
  page: number;
  pageSize: number;
  setPage: (page: number) => void;
}

export interface UseApiMutationReturn<T, B> {
  trigger: (body?: B) => Promise<T | null>;
  isMutating: boolean;
  error: Error | undefined;
  reset: () => void;
}

// ── SWR 全局 Fetcher ─────────────────────────────────────────────────────────

/**
 * 基于 fetchWithAuth 的 SWR fetcher
 * key 格式：url string 或 [url, token]
 */
export async function swrFetcher<T>(url: string): Promise<T> {
  return fetchWithAuth(url) as Promise<T>;
}

// ── 主 Hook ──────────────────────────────────────────────────────────────────

/**
 * 基础数据获取 Hook
 * @param url  API 路径（null 时暂停请求）
 * @param options  SWR 配置项
 */
export function useApi<T>(
  url: string | null,
  options?: SWRConfiguration<T>
): UseApiReturn<T> {
  const { data, error, isLoading, mutate } = useSWR<T>(
    url,
    swrFetcher<T>,
    {
      revalidateOnFocus: false,
      shouldRetryOnError: true,
      errorRetryCount: 2,
      errorRetryInterval: 3000,
      ...options,
    }
  );

  const refresh = useCallback(() => {
    mutate();
  }, [mutate]);

  return {
    data,
    isLoading,
    error: error as Error | undefined,
    mutate,
    refresh,
  };
}

// ── 分页 Hook ────────────────────────────────────────────────────────────────

export interface PaginatedResponse<T> {
  items: T[];
  total: number;
}

/**
 * 支持分页的数据获取 Hook
 * @param baseUrl  基础 API 路径（不含分页参数）
 * @param params   分页参数
 */
export function usePaginatedApi<T>(
  baseUrl: string | null,
  params: { page: number; pageSize: number }
): UsePaginatedApiReturn<T> {
  const [page, setPage] = useState(params.page);
  const { pageSize } = params;

  const url = baseUrl
    ? `${baseUrl}?limit=${pageSize}&offset=${(page - 1) * pageSize}`
    : null;

  const { data, error, isLoading, mutate } = useSWR<PaginatedResponse<T>>(
    url,
    swrFetcher<PaginatedResponse<T>>,
    {
      revalidateOnFocus: false,
      shouldRetryOnError: true,
      errorRetryCount: 2,
    }
  );

  const refresh = useCallback(() => {
    mutate();
  }, [mutate]);

  return {
    data: data?.items,
    total: data?.total ?? 0,
    isLoading,
    error: error as Error | undefined,
    mutate: mutate as unknown as KeyedMutator<T[]>,
    refresh,
    page,
    pageSize,
    setPage,
  };
}

// ── Mutation Hook ────────────────────────────────────────────────────────────

/**
 * API 数据变更 Hook（POST / PUT / DELETE）
 * @param url     API 路径
 * @param method  HTTP 方法（默认 POST）
 */
export function useApiMutation<T, B = unknown>(
  url: string,
  method: string = "POST"
): UseApiMutationReturn<T, B> {
  const [isMutating, setIsMutating] = useState(false);
  const [error, setError] = useState<Error | undefined>(undefined);

  const trigger = useCallback(
    async (body?: B): Promise<T | null> => {
      try {
        setIsMutating(true);
        setError(undefined);
        const result = await fetchWithAuth(url, {
          method,
          body: body !== undefined ? JSON.stringify(body) : undefined,
        }) as T;
        return result;
      } catch (err) {
        const e = err instanceof Error ? err : new Error(String(err));
        setError(e);
        return null;
      } finally {
        setIsMutating(false);
      }
    },
    [url, method]
  );

  const reset = useCallback(() => {
    setError(undefined);
  }, []);

  return { trigger, isMutating, error, reset };
}
