import { request } from './index';
import $storage from '@/sheep/utils/storage';
import { ElMessage } from 'element-plus';

// 检测是否为mall前缀的接口
const isMallAPI = (url) => {
  return url.startsWith('/mall') || url.startsWith('mall');
};
// CRUD 配置常量
const CRUD_VERSIONS = {
  V1: 'v1', // 旧版本 CRUD
  V2: 'v2', // 新版本 CRUD
};

// 默认 CRUD 配置
const DEFAULT_CRUD_CONFIG = {
  version: CRUD_VERSIONS.V1,
  endpoints: {
    list: '/list',
    detail: '/detail',
    add: '/add',
    edit: '/update',
    delete: '/delete',
  },
  methods: {
    list: 'POST',
    detail: 'POST',
    add: 'POST',
    edit: 'POST',
    delete: 'DELETE',
  },
};

// 新版本 CRUD 配置
const V2_CRUD_CONFIG = {
  version: CRUD_VERSIONS.V2,
  endpoints: {
    list: '/page',
    detail: '/info',
    add: '/save',
    edit: '/update',
    delete: '/delete',
  },
  methods: {
    list: 'GET',
    detail: 'GET',
    add: 'POST',
    edit: 'PATCH',
    delete: 'DELETE',
  },
};

// 获取 CRUD 配置
const getCrudConfig = (options = {}) => {
  const { version = CRUD_VERSIONS.V1 } = options;

  if (version === CRUD_VERSIONS.V2) {
    return V2_CRUD_CONFIG;
  }

  return DEFAULT_CRUD_CONFIG;
};

// 查看列表
export const LIST = (url, data, options = {}) => {
  const config = getCrudConfig(options);
  const endpoint = url + config.endpoints.list;
  const method = config.methods.list;

  return request({
    url: endpoint,
    method,
    ...(method === 'GET' ? { params: data } : { data }),
  });
};

// 查看详情
export const DETAIL = (url, idOrParams, options = {}) => {
  const config = getCrudConfig(options);
  const method = config.methods.detail;
  const isMall = isMallAPI(url);

  if (config.version === CRUD_VERSIONS.V2) {
    // 新版本：使用 RESTful 风格的 URL
    if (typeof idOrParams === 'object') {
      // 如果是对象参数（如 {orderNo: 'xxx'}），使用查询参数
      return request({
        url: url + config.endpoints.detail,
        method,
        params: idOrParams,
      });
    } else {
      // 如果是ID，使用RESTful风格URL
      return request({
        url: url + config.endpoints.detail + `/${idOrParams}`,
        method,
      });
    }
  } else {
    // 旧版本：使用参数传递
    if (typeof idOrParams === 'object') {
      // 如果是对象参数（如 {orderNo: 'xxx'}），直接传递
      return request({
        url: url + config.endpoints.detail,
        method: isMall ? 'GET' : 'POST', // mall用GET，其他用POST
        params: idOrParams,
      });
    } else {
      // 如果是ID，使用id参数
      return request({
        url: url + config.endpoints.detail,
        method: isMall ? 'GET' : 'POST', // mall用GET，其他用POST
        params: { id: idOrParams },
      });
    }
  }
};

// 新增
export const ADD = (url, data, options = {}) => {
  const config = getCrudConfig(options);

  return request({
    url: url + config.endpoints.add,
    method: config.methods.add,
    data,
    options: {
      showSuccessMessage: false,
    },
  });
};

// 编辑&更新
export const EDIT = (url, id, data, options = {}) => {
  const config = getCrudConfig(options);
  const isMall = isMallAPI(url);

  if (config.version === CRUD_VERSIONS.V2) {
    // 新版本：使用 RESTful 风格的 URL
    return request({
      url: url + config.endpoints.edit + `/${id}`,
      method: config.methods.edit,
      data,
      options: {
        showSuccessMessage: false,
      },
    });
  } else {
    // 旧版本：将 ID 包含在数据中
    return request({
      url: url + config.endpoints.edit,
      method: isMall ? 'PUT' : 'POST', // mall用PUT，其他用POST
      data: id,
      options: {
        showSuccessMessage: false,
      },
    });
  }
};

// 删除(软删除/真实删除)
export const DELETE = (url, id, options = {}) => {
  const config = getCrudConfig(options);
  const method = config.methods.delete;
  const isMall = isMallAPI(url);

  if (config.version === CRUD_VERSIONS.V2) {
    // 新版本：使用 RESTful 风格的 URL
    return request({
      url: url + config.endpoints.delete + `/${id}`,
      method,
      options: {
        showSuccessMessage: true,
      },
    });
  } else {
    // 旧版本：使用参数传递 ID
    return request({
      url: url + config.endpoints.delete,
      method: isMall ? 'DELETE' : 'POST', // mall用DELETE，其他用POST
      params: id,
      options: {
        showSuccessMessage: true,
      },
    });
  }
};

// 选择
export const SELECT = (url, params) =>
  request({
    url: url + '/select',
    method: 'GET',
    params,
  });

// 回收站列表
export const RECYCLE_BIN = (url, params) =>
  request({
    url: url + '/recyclebin',
    method: 'GET',
    params,
  });

// 销毁
export const DESTROY = (url, id) =>
  request({
    url: url + '/destroy/' + id,
    method: 'DELETE',
  });

// 还原
export const RESTORE = (url, id) =>
  request({
    url: url + '/restore/' + id,
    method: 'PUT',
  });

// 通用增删改查
export const CRUD = (
  url,
  methods = ['list', 'detail', 'add', 'edit', 'delete', 'export'],
  options = {},
) => {
  const apis = {};
  const crudOptions = { version: options.version || CRUD_VERSIONS.V1 };

  if (methods.includes('list')) apis.list = (params) => LIST(url, params, crudOptions);
  if (methods.includes('detail')) apis.detail = (id) => DETAIL(url, id, crudOptions);
  if (methods.includes('add')) apis.add = (data) => ADD(url, data, crudOptions);
  if (methods.includes('edit')) apis.edit = (id, data) => EDIT(url, id, data, crudOptions);
  if (methods.includes('delete')) apis.delete = (id) => DELETE(url, id, crudOptions);

  if (methods.includes('report'))
    apis.report = (params, filename) =>
      REPORT(url, params, filename, 'report', options.reportMethod);
  if (methods.includes('export'))
    apis.export = (params, filename) =>
      REPORT(url, params, filename, 'export', options.exportMethod);
  return apis;
};

// 新版本 CRUD 的便捷函数
export const CRUD_V2 = (
  url,
  methods = ['list', 'detail', 'add', 'edit', 'delete', 'export'],
  options = {},
) => {
  return CRUD(url, methods, { ...options, version: CRUD_VERSIONS.V2 });
};

// 通用回收站
export const RECYCLE = (url) => {
  return {
    recyclebin: (params) => RECYCLE_BIN(url, params),
    restore: (id) => RESTORE(url, id),
    destroy: (id) => DESTROY(url, id),
  };
};

// 导出报表 - 需要超级管理员权限
export const REPORT = async (
  url,
  params,
  filename = '导出数据',
  typeName = 'report',
  method = null,
) => {
  // 获取用户信息进行权限验证
  const userInfo = $storage.get('userInfo');

  // 检查用户是否为超级管理员
  if (!userInfo || userInfo.roleName !== '超级管理员') {
    ElMessage.error('只有超级管理员可以导出');
    return Promise.reject(new Error('权限不足：只有超级管理员可以导出'));
  }

  // 确定HTTP方法：优先使用传入的method参数，否则使用默认逻辑
  const httpMethod = method || (typeName == 'report' ? 'GET' : 'POST');

  let response = null;
  try {
    // 发送导出请求
    response = await request({
      url: url + `/${typeName}`,
      method: httpMethod,
      ...(httpMethod === 'GET' ? { params } : { data: params }),
      responseType: 'blob', // 用于文件下载
      headers: {
        Accept:
          'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/octet-stream, */*',
      },
      options: {
        showSuccessMessage: false,
      },
    });

    // 检查响应状态和内容类型
    if (response.status === 200 && response.headers['content-type']?.includes('excel')) {
      // 成功响应，处理文件下载
      const blob = response.data; // 从响应对象中获取 Blob 数据
      const downloadUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = downloadUrl;

      // 优先从响应头的 content-disposition 中获取文件名
      let finalFilename = `${filename}_${new Date().toISOString().slice(0, 10)}.xlsx`;

      // 尝试多种方式获取 content-disposition
      const contentDisposition =
        response.headers['content-disposition'] ||
        response.headers['Content-Disposition'] ||
        response.headers.get?.('content-disposition') ||
        response.headers.get?.('Content-Disposition');

      if (contentDisposition) {
        // 尝试从 content-disposition 中提取文件名
        const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
        if (filenameMatch && filenameMatch[1]) {
          let extractedFilename = filenameMatch[1].replace(/['"]/g, '');
          // 处理 URL 编码的文件名
          try {
            extractedFilename = decodeURIComponent(extractedFilename);
          } catch (e) {
            // 如果解码失败，使用原始文件名
          }
          if (extractedFilename) {
            finalFilename = extractedFilename;
          }
        }
      }

      link.download = finalFilename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(downloadUrl);

      ElMessage.success('导出成功');
      return Promise.resolve();
    } else {
      // 如果不是成功的文件响应，说明返回的是错误信息
      let errorData;
      try {
        // 尝试解析 Blob 中的 JSON 错误信息
        const text = await response.data.text();
        errorData = JSON.parse(text);
      } catch (parseError) {
        // 如果解析失败，使用默认错误信息
        errorData = { code: '500', message: '导出失败' };
      }

      // 检查返回的 code
      // if (errorData.code !== '200') {
      //   const errorMessage = errorData.message || '导出失败';
      //   ElMessage.error(errorMessage);
      //   return Promise.reject(new Error(errorMessage));
      // }
    }
  } catch (error) {
    console.error('导出失败:', error);

    // 如果是网络错误或其他异常
    if (error.response) {
      // 有响应但状态码不是 2xx
      const errorMessage = error.response.data?.message || '服务器错误';
      ElMessage.error(errorMessage);
    } else if (error.message?.includes('权限不足')) {
      // 权限错误已经在上面处理了，不需要重复提示
    } else {
      // 其他错误
      ElMessage.error('导出失败，请稍后重试');
    }

    return Promise.reject(error);
  }
};

/**
 * CRUD 使用说明：
 *
 * 1. 旧版本 CRUD（默认）：
 *    ...CRUD('shop/admin/user', ['list', 'detail', 'add', 'edit', 'delete'])
 *
 * 2. 新版本 CRUD（通过参数指定）：
 *    ...CRUD('mall/notice', ['list', 'detail', 'add', 'edit', 'delete'], { version: 'v2' })
 *
 * 3. 新版本 CRUD（便捷函数）：
 *    ...CRUD_V2('mall/notice', ['list', 'detail', 'add', 'edit', 'delete'])
 *
 * 接口映射对照：
 * 操作   | 旧版本(V1)        | 新版本(V2)
 * ------ | ---------------- | ------------------
 * 列表   | POST /list       | GET /page
 * 详情   | POST /detail     | GET /info/{id}
 * 新增   | POST /add        | POST /save
 * 更新   | POST /update     | PATCH /update/{id}
 * 删除   | POST /delete     | DELETE /delete/{id}
 */

// 支持的方法: add, list, delete, edit, detail, select, recyclebin, restore, destroy, report
