import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';

import { message } from 'ant-design-vue';
import axios, { AxiosError } from 'axios';
// 导入 RSA 相关库
import { KEYUTIL, KJUR } from 'jsrsasign';

export interface ResopnseType<T> {
  reason: string;
  message: string;
  data: T;
  ts: string;
}
export const YCODE_BASEURL: string = import.meta.env.VITE_YCODE_BASEURL;

// RSA 签名相关配置
const CLIENT_ID = import.meta.env.VITE_CLIENT_ID;

// 私钥配置，请在实际使用中安全存储
const PRIVATE_KEY = `-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAySeb8CMlvGzI8KasmiQwMCX4240e8Ap6W8Pb63iX57pBFpmV
fcOy7BAsfOEtp3TrJkssszUxdnCmsASZQNHaJtIhide7DjXjct9MQ3tqeEtc2R2K
EkauK7oLsAiQqkpb9XpWAURfoE+83kCrJuQ49frw/zz7PElTPgjAjPknyF/JJFEp
BoasWhoFBwrZWFwQKWUmFaUodG3UjtXdepYFVfdGKmgPYerm1Os3BQu6oSCKvh+p
4uaRrAyKLBdTYXHfYiJi+oRt9wSSA0eGS8IcMxWn0azzEeZoPldLRSZ4Hpxx9Amq
iNOu7FmKP5azKxmTG6dp+ZyVgpQt9FA4YYNU9wIDAQABAoIBAFZEQGIKEMLwPHTI
Zjlsz6W2gzVVHjF/rN3x7zza6PqeLA/PKgdXiEIo5Ytg3r10LOytTKxGYcITqcjP
EBJ2bQI9F9kPxc7gWX0IOqKuKQkR+O2791zDJyrljOGfqrr9TNbH8l50vjX4PF1s
inoRYkRLrFMqCeze3W47Pqi2qdMKTmb0fjAjf9pQM/lE/jAWquUQhU8efZW0+2SD
MMhXJceMS7SgkoOgsg1Qw7iEY5iMBMUOMb9bh4RxRkEZDECgm1iZsZqq004wFuVz
RKbM//jGyNDQYZKH6TCZgC4UAPXt+PrwLC0oPrL0qZgK47dJznWzLZln2efYli+I
PuAa6DECgYEA67J/XfLbyow2fLArbmiO1Gt9fQtFnd9xapMcj+xOQtP/DBmbukLK
CYluSKED8+zKdP33t0dk4FHsrshEI85NsfBjp3GiHjbcFiOjddEyY9tHZxzMlJxB
dS9u+LAfkPN8LBk4hX5YJ/oAhWcmCJ7agDPSGt+nJeTP2U3Mu5+7B+MCgYEA2ntk
s3Gmi+n6gFQq97ANsYik+81wo/TDtqTcbmekqgSelsfNFlOeN4EOWJnXdt6/lZqs
54kmlTUZzXy3I1Fe+z8FKBpulKxvVlCZ+Ks4tbjI5peJXL0mWHdbJ2Tg4AvbjQ5E
z5efQGHbuBeFMty20JnjFlUrDd4x8Mj+dwP3Qt0CgYAhje3YACUONtvi8GmedEAx
OYRJ8vrcON06oOrmCmwx02Bx5otm/u8oYGpU6KdZaJKCCU3kx8MytDcPwu8AcfRZ
qrFlOyYrSwAWHsi8kyWrVaJaqZzuYzhmaHRR7zDvP9qjpIuJZa1DM7IzS7X8cDEH
I1l7/e8b0/FLLGpDI8BKpQKBgQCJos5vlRs8bSwYB+4Bl3Eo9FIrJuLdBub8eqM7
EiPTz5Ewn7H9bLPxd2XYPyJTikPbNVPTkL0zpf4ZS4X7w9k4Ih1XhD9Bfdet4pz8
4LCbGkvFqJUqTSaI+Lf9+zkHK7EmDWUf+f6jCoLmWDrbLdwlUayTdxfmZqHDdHuJ
8n+kKQKBgA1lR4zITE1qh+eMsueYPlOs32SP9jcx5fbTPxQpaqQJXSqvVb7ZHmfx
qwzhQTzcKjSEhlD15ct5RqxD+4KmGid8bM5fewzYnORw+u2O1g74owgq0ApCVsRU
/wsYRNpoRHJxU69kzkl8rSulJjQ0rOOz0/TyDbONhmM7Bv0cQAAA
-----END RSA PRIVATE KEY-----`;

// 需要添加签名的 API 路径前缀
const NEED_SIGN_PATHS = [
  '/v1/project',
  '/v1/preview',
  '/v1/modular',
  '/v1/field',
];

// 初始化私钥
let privateKey: string;
try {
  privateKey = KEYUTIL.getKey(PRIVATE_KEY);
} catch (error) {
  console.error('RSA 私钥初始化失败:', error);
}

const requestType = {
  base: YCODE_BASEURL,
};

const baseAxios: AxiosInstance = axios.create({
  baseURL: '',
  timeout: 100_000,
  withCredentials: true,
});

// 创建 RSA 签名
function createSignature(message: string): string {
  try {
    const sig = new KJUR.crypto.Signature({ alg: 'SHA256withRSA' });
    sig.init(privateKey);
    sig.updateString(message);
    return btoa(sig.sign());
  } catch (error) {
    console.error('签名创建失败:', error);
    return '';
  }
}

// 请求拦截器 - 添加 RSA 签名认证
baseAxios.interceptors.request.use(
  (config) => {
    // 检查是否需要添加签名
    const needSign = NEED_SIGN_PATHS.some(
      (path) => config.url && config.url.startsWith(path),
    );

    if (needSign && privateKey) {
      // 生成当前时间戳（秒）
      const timestamp = Math.floor(Date.now() / 1000).toString();

      // 构建要签名的消息: clientID + timestamp
      const message = CLIENT_ID + timestamp;

      // 创建签名
      const signature = createSignature(message);

      // 设置请求头
      config.headers = config.headers || {};
      config.headers['X-Client-ID'] = CLIENT_ID;
      config.headers['X-Timestamp'] = timestamp;
      config.headers['X-Signature'] = signature;

      console.log('已添加签名认证:', {
        url: config.url,
        clientId: CLIENT_ID,
        timestamp,
      });
    }

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

const errorHandle = (error: AxiosError) => {
  if (error.response) {
    const status = error.response?.status;
    switch (status) {
      case 401: {
        message.warning('请先登录');
        window.location.href = `${YCODE_BASEURL}/login?redirect=${encodeURIComponent(window.location.href)}`;
        break;
      }
      case 403: {
        message.warning('权限不足');
        break;
      }
      case 500: {
        message.warning('服务器出错了……  (>_<)');
        break;
      }
      default: {
        message.warning('服务器出错了……  (>_<)');
        break;
      }
    }
    return Promise.reject(error);
  }
  message.error(error.message);
  return Promise.reject(error);
};
// 响应拦截器
baseAxios.interceptors.response.use((response: AxiosResponse) => {
  const { data, status } = response;

  if (status !== 200) {
    return Promise.reject(data);
  }
  if (data.code) {
    if (data.code === 200) {
      return data;
    } else {
      message.warning(data.message);
      return Promise.reject(data);
    }
  }
}, errorHandle);

type RequestConfig = Omit<AxiosRequestConfig, 'baseURL'> & {
  baseURL?: keyof typeof requestType;
};
const request = <T = any>(config: RequestConfig) => {
  const host = requestType[config.baseURL || 'base'];
  return new Promise<T>((resolve, reject) => {
    baseAxios
      .request<any, T>({ ...config, baseURL: host })
      .then((res: T) => {
        resolve(res);
      })
      .catch((error: unknown) => {
        reject(error);
      });
  });
};

const get = <T = any>(config?: RequestConfig) => {
  return request<ResopnseType<T>>({
    ...config,
    method: 'GET',
  });
};

const post = <T = any>(config?: RequestConfig) =>
  request<ResopnseType<T>>({
    ...config,
    method: 'POST',
  });

const put = <T = any>(config?: RequestConfig) =>
  request<ResopnseType<T>>({
    ...config,
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
  });

const del = <T = any>(config?: { url: string }) =>
  request<ResopnseType<T>>({ ...config, method: 'DELETE' });

export { baseAxios, del, get, post, put, request };
