import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig, AxiosHeaders } from 'axios';
import { BASE_URL } from './constants'
import { errorHandle } from './errorHandle';

/**
 * 统一的错误处理函数
 * @param error - 错误对象
 * @param defaultMessage - 默认错误信息
 */
const handleRequestError = (error: any, defaultMessage: string = '请求失败') => {
  if (error.response) {
    const { status, data } = error.response;
    const errorMessage = data?.message || data?.detail?.message || defaultMessage;
    errorHandle(status, errorMessage);
  } else if (error.request) {
    errorHandle(0);
  } else {
    errorHandle(0, error.message || defaultMessage);
  }
};
// 创建 axios 实例
const request: AxiosInstance = axios.create({
  baseURL: BASE_URL, // 设置基础URL
  timeout: 300000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json',
  },
});

// 请求拦截器
request.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 从 localStorage 获取 token
    const token = localStorage?.getItem('token');
    if (token && config.headers) {
      (config.headers as AxiosHeaders).set('Authorization', `Bearer ${token}`);
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse) => {
    // 检查业务状态码
    if (response.data?.code !== 0 && response.data?.code !== 202) {
      console.log('response', response)
      // 处理业务层面的错误
      const businessCode = response.data?.code;
      const errorMessage = response.data?.message;
      // 其他业务错误
      errorHandle(businessCode, errorMessage);
      return Promise.reject(new Error(errorMessage));
    }

    return response.data;
  },
  (error) => {
    // 处理 402 错误
    if (error.response?.status === 402 && error.response?.data?.detail) {
      // 使用动态导入并确保在下一个事件循环中执行
      setTimeout(() => {
        import('../utils/notifications').then(({ showInsufficientPointsNotification }) => {
          showInsufficientPointsNotification(error.response.data.detail);
        });
      }, 0);
      
      return Promise.reject(new Error('Insufficient points'));
    }

    return Promise.reject(error);
  }
);

// 封装 GET 请求
export const get = <T>(url: string, config?: AxiosRequestConfig): Promise<T> => {
  return request.get(url, config);
};

// 封装 POST 请求
export const post = <T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> => {
  return request.post(url, data, config);
};

// 封装 PUT 请求
export const put = <T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> => {
  return request.put(url, data, config);
};

// 封装 DELETE 请求
export const del = <T>(url: string, config?: AxiosRequestConfig): Promise<T> => {
  return request.delete(url, config);
};
// utils/streamJsonPost.ts
export async function streamJsonPost<T = any>(
  url: string,
  body: any,
  onJson: (json: T) => void
) {
  try {
    const token = localStorage?.getItem('token') || '';
    const response = await fetch(`${BASE_URL}${url}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify(body),
    });

    // 处理 HTTP 错误状态
    if (!response.ok) {
      const error = {
        response: {
          status: response.status,
          data: { message: await response.text().then(text => {
            try {
              const data = JSON.parse(text);
              return data.message || `HTTP error! status: ${response.status}`;
            } catch {
              return `HTTP error! status: ${response.status}`;
            }
          })}
        }
      };
      handleRequestError(error);
      throw error;
    }

    if (!response.body) {
      throw new Error('Stream not supported');
    }

    const reader = response.body.getReader();
    const decoder = new TextDecoder('utf-8');
    let buffer = '';

    try {
      while (true) {
        const { done, value } = await reader.read();

        if (done) {
          // Process any remaining data in the buffer
          if (buffer.trim()) {
            try {
              const parsed = JSON.parse(buffer.trim());
              onJson(parsed);
            } catch (err) {
              console.warn('Final JSON parse error:', err, buffer);
            }
          }
          break;
        }

        // Decode the current chunk and add to buffer
        buffer += decoder.decode(value, { stream: true });

        // Process complete JSON objects
        let boundary = buffer.indexOf('\n');
        while (boundary !== -1) {
          const chunk = buffer.slice(0, boundary).trim();
          buffer = buffer.slice(boundary + 1);

          if (chunk) {
            try {
              const parsed = JSON.parse(chunk);
              onJson(parsed);
            } catch (err) {
              // Only log if it's not an empty line
              if (chunk !== '') {
                console.warn('JSON parse error:', err, chunk);
              }
            }
          }
          boundary = buffer.indexOf('\n');
        }
      }
    } catch (error) {
      console.error('Stream processing error:', error);
      throw error;
    } finally {
      // Ensure reader is released
      reader.releaseLock();
    }
  } catch (error) {
    console.error('Stream request error:', error);
    // Handle specific error types
    if (error instanceof TypeError) {
      console.error('Network error - check your connection');
    }
    if (error instanceof SyntaxError) {
      console.error('Invalid JSON in the stream');
    }
    throw error;
  }
}

// 封装流式数据请求
export const stream = async <T>({
  url,
  method = 'POST',
  data,
  onMessage,
  onError,
  onComplete,
}: {
  url: string;
  method?: 'GET' | 'POST';
  data?: any;
  onMessage: (data: T) => void;
  onError?: (error: any) => void;
  onComplete?: () => void;
}) => {
  try {
    const config: AxiosRequestConfig = {
      url,
      method,
      data,
      responseType: 'stream',
      headers: {
        'Accept': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
      },
      onDownloadProgress: (progressEvent: any) => {
        const responseText = progressEvent.event?.target?.responseText;
        if (!responseText) return;

        // 处理接收到的数据
        const lines: string[] = responseText.split('\n');
        lines.forEach((line: string) => {
          if (line.startsWith('data: ')) {
            try {
              const data = JSON.parse(line.slice(6));
              onMessage(data);
            } catch (e) {
              console.warn('Failed to parse stream data:', e);
            }
          }
        });
      },
    };

    const response = await request(config);
    onComplete?.();
    return response;
  } catch (error: any) {
    handleRequestError(error, 'Stream request failed');
    onError?.(error);
    throw error;
  }
};

// 封装文件下载流请求
export const downloadStream = async (
  url: string,
  filename: string,
  config?: AxiosRequestConfig
) => {
  try {
    const response = await request({
      url,
      method: 'GET',
      responseType: 'blob',
      ...config,
    });

    // 创建下载链接
    const blob = new Blob([response.data], { type: response.headers['content-type'] });
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = downloadUrl;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(downloadUrl);

    return response;
  } catch (error: any) {
    console.error('文件下载失败:', error);
    handleRequestError(error, 'File download failed');
    throw error;
  }
};

// 导出 request 实例
export default request;
