import { Authorization } from '@/constants/authorization';
import type { ResponseType } from '@/interfaces/database/base';
import i18n from '@/locales';
import axios from 'axios';
import type { AxiosRequestConfig, AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios';

import { snackbar, notification } from '@/utils/snackbarInstance';
import logger from './logger';

const FAILED_TO_FETCH = 'Failed to fetch';

export const RetcodeMessage = {
  200: i18n.t('message.200'),
  201: i18n.t('message.201'),
  202: i18n.t('message.202'),
  204: i18n.t('message.204'),
  400: i18n.t('message.400'),
  401: i18n.t('message.401'),
  403: i18n.t('message.403'),
  404: i18n.t('message.404'),
  406: i18n.t('message.406'),
  410: i18n.t('message.410'),
  413: i18n.t('message.413'),
  422: i18n.t('message.422'),
  500: i18n.t('message.500'),
  502: i18n.t('message.502'),
  503: i18n.t('message.503'),
  504: i18n.t('message.504'),
};

export type ResultCode =
  | 200
  | 201
  | 202
  | 204
  | 400
  | 401
  | 403
  | 404
  | 406
  | 410
  | 413
  | 422
  | 500
  | 502
  | 503
  | 504;

// 获取授权token
const getAuthorization = (): string => {
  return localStorage.getItem(Authorization) || '';
};

// 重定向到登录页
const redirectToLogin = (): void => {
  localStorage.removeItem(Authorization);
  window.location.href = '/login';
};

// 转换对象键为snake_case
const convertTheKeysOfTheObjectToSnake = (obj: any): any => {
  if (!obj || typeof obj !== 'object') return obj;

  if (Array.isArray(obj)) {
    return obj.map(convertTheKeysOfTheObjectToSnake);
  }

  const result: any = {};
  Object.keys(obj).forEach(key => {
    const snakeKey = key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
    result[snakeKey] = convertTheKeysOfTheObjectToSnake(obj[key]);
  });

  return result;
};

const getBaseURL = (): string => {
  if (import.meta.env.DEV) {
    if (import.meta.env.MODE == 'flask') {
      return import.meta.env.VITE_FLASK_API_BASE_URL;
    }
  }
  return import.meta.env.VITE_API_BASE_URL;
}

// 创建axios实例
const request: AxiosInstance = axios.create({
  baseURL: getBaseURL(),
  timeout: 300000,
  headers: {
    'Content-Type': 'application/json',
  },
});

class CustomError extends Error {
  code?: number;
  response?: ResponseType;
}

// 请求拦截器
request.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 转换数据格式 - 跳过FormData对象
    // if (config.data && !(config.data instanceof FormData)) {
    //   config.data = convertTheKeysOfTheObjectToSnake(config.data);
    // }
    // if (config.params) {
    //   config.params = convertTheKeysOfTheObjectToSnake(config.params);
    // }

    // 对于FormData，删除默认的Content-Type让浏览器自动设置
    if (config.data instanceof FormData) {
      delete config.headers['Content-Type'];
    }

    // 添加授权头
    const authorization = getAuthorization();
    if (authorization && !config.headers?.skipToken) {
      config.headers['Authorization'] = authorization;
    }

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse) => {
    logger.info('🔍 Response interceptor triggered:', {
      url: response.config.url,
      status: response.status,
      responseType: response.config.responseType,
      hasData: !!response.data
    });

    // 处理blob类型响应
    if (response.config.responseType === 'blob') {
      logger.info('📁 Blob response detected, skipping data processing');
      return response;
    }
    logger.info('interceptors.response ------ response', response);
    const data: ResponseType = response.data;

    // 处理业务错误码
    if (data?.code == 401) {
      logger.info('⚠️ Handling business code 401 unauthorized');
      snackbar.error(data?.message ?? i18n.t('message.401'));
      redirectToLogin();
    } else if (data?.code !== 0) {
      // 处理其他业务错误
      logger.info('❌ Handling business error:', { code: data?.code, message: data?.message });
      const error = new CustomError(data?.message || i18n.t('message.requestError'));
      error.code = data?.code || -1;
      error.response = data;
      snackbar.warning(error.message);
      throw error;
    }
    logger.info('✅ Response processed successfully');
    return response;
  },
  (error) => {
    logger.info('❌ Response interceptor error handler triggered:', {
      message: error.message,
      status: error.response?.status,
      url: error.config?.url,
      hasResponse: !!error.response
    });

    const { status, data } = error.response || {};
    if (status == 401) {
      logger.info('401', data)
      const detail = data['detail']
      if (detail) {
        const error = new CustomError(detail || i18n.t('message.requestError'));
        if (detail.includes('not registered')) {
          error.code = data?.code || -1;
          error.response = data;
          snackbar.error(detail);
        } else {
          redirectToLogin();
        }
        return Promise.reject(error);
      }
    } else if (status == 413 || status == 504) {
      logger.info('⚠️ Handling HTTP error status:', status);
      snackbar.error(RetcodeMessage[status as ResultCode]);
    }

    // 处理网络错误
    if (error.message === FAILED_TO_FETCH || !error.response) {
      logger.info('🌐 Network error detected:', error.message);
    } else if (error.response) {
      const { status, statusText } = error.response;
      const errorText = RetcodeMessage[status as ResultCode] || statusText;
      logger.info('🚫 HTTP error response:', { status, statusText, errorText });
    }

    return Promise.reject(error);
  }
);

export default request;

// 便捷方法
export const get = (url: string, config?: AxiosRequestConfig) => {
  return request.get(url, config);
};

export const post = (url: string, data?: any, config?: AxiosRequestConfig) => {
  return request.post(url, data, config);
};

export const put = (url: string, data?: any, config?: AxiosRequestConfig) => {
  return request.put(url, data, config);
};

export const del = (url: string, config?: AxiosRequestConfig) => {
  return request.delete(url, config);
};