class ApiInterceptor {
  constructor() {
    this.baseUrl = 'https://www.3qniuma.com/api';
    this.tokenHeaderName = 'Authorization';
    this.lastRequestTime = 0;
    // 并发请求去重：key -> Promise
    this.pendingRequests = {};
    // 最近请求时间戳：key -> timestamp，用于短时间内拦截重复请求
    this.lastRequestTimestamps = {};
    // 最近一次成功响应缓存：key -> response
    this.lastSuccessResponses = {};
    // 默认短时间窗口（毫秒），在此窗口内相同请求会被拦截
    this.THROTTLE_MS = 500;
  }
  
  // Token 相关操作改为私有方法
  #getToken() {
    try {
      // 自动从本地存储获取 token
      return localStorage.getItem('access_token');
    } catch (error) {
      console.error('获取 Token 失败:', error);
      return null;
    }
  }
  
  #setToken(token) {
    try {
      localStorage.setItem('access_token', token);
      return true;
    } catch (error) {
      console.error('设置 Token 失败:', error);
      return false;
    }
  }
  
  #removeToken() {
    try {
      localStorage.removeItem('access_token');
      return true;
    } catch (error) {
      console.error('移除 Token 失败:', error);
      return false;
    }
  }
  
  #addAuthorizationHeader(headers) {
    // const token = this.#getToken();
    // if (token) {
    //   return {
    //     ...headers,
    //     [this.tokenHeaderName]: `Bearer ${token}`
    //   };
    // }
    return headers;
  }
  
  #handleUnauthorizedResponse(response) {
    if (response.status === 401) {
      // 处理未授权情况
      console.error('未授权访问，Token 可能已过期或无效');
      this.#removeToken();
      
      // 这里可以添加重定向到登录页面或其他处理逻辑
      // 但在浏览器插件环境中，可能需要通知用户或重新获取 Token
      return Promise.reject(new Error('未授权访问，请重新登录'));
    }
    return response;
  }
  
  // 拦截 fetch 请求
  async #interceptedFetch(url, options = {}) {
    // 确保 URL 格式正确
    const requestUrl = url.startsWith('http') ? url : `${this.baseUrl}${url}`;
    
    // 处理请求头，添加 Token
    const headers = this.#addAuthorizationHeader({
      'Content-Type': 'application/json',
      ...options.headers
    });
    
    // 创建新的请求选项
    const fetchOptions = {
      ...options,
      headers
    };

    // 生成请求去重键：使用请求地址 + method + body（若有）
    const method = (fetchOptions.method || 'GET').toUpperCase();
    const bodyKey = fetchOptions.body ? String(fetchOptions.body) : '';
    const dedupeKey = `${method}::${requestUrl}::${bodyKey}`;

    const now = Date.now();

    // 如果同一请求正在进行中，复用该 Promise，避免重复请求
    if (this.pendingRequests[dedupeKey]) {
      console.log(dedupeKey, '请求已在进行中，复用中');
      return this.pendingRequests[dedupeKey];
    }

    // 如果在短时间窗口内已发送相同请求，则返回上次成功的响应缓存（若存在），否则拦截
    if (this.lastRequestTimestamps[dedupeKey] && (now - this.lastRequestTimestamps[dedupeKey] < this.THROTTLE_MS)) {
      if (this.lastSuccessResponses[dedupeKey]) {
        console.log(requestUrl, '短时间内重复请求，返回上次缓存响应');
        return Promise.resolve(this.lastSuccessResponses[dedupeKey]);
      }
      console.log(requestUrl, '短时间内重复请求，已被拦截（无缓存）');
      return Promise.reject(new Error(`请求被拦截：短时间内只能请求一次（${this.THROTTLE_MS}ms）`));
    }

    // 标记为正在进行的请求，并在完成后清理
    this.pendingRequests[dedupeKey] = (async () => {
      try {
        const res = await fetch(requestUrl, fetchOptions)
          .then(this.#handleUnauthorizedResponse)
          .then(response => {
            if (!response.ok) {
              throw new Error(`HTTP error! status: ${response.status}`);
            }
            return response.json();
          });

        // 记录时间戳用于短时间内拦截重复请求
        this.lastRequestTimestamps[dedupeKey] = Date.now();
        // 缓存此次成功响应，后续短时间重复请求可直接返回该缓存
        try { this.lastSuccessResponses[dedupeKey] = res; } catch (e) { /* ignore cache errors */ }

        return res;
      } catch (error) {
        console.error('API 请求错误:', error);
        alert(`API 请求错误: 请刷新，如果问题持续存在，请检查网络或联系管理员。\n错误详情: ${error.message}`);
        //刷新
          window.location.reload();
        throw error;
      } finally {
        // 无论成功或失败，移除 pending 标记
        delete this.pendingRequests[dedupeKey];
      }
    })();

    return this.pendingRequests[dedupeKey];
  }
  
  // 公开的 API 方法
  async get(url, params) {

    // 处理参数
    if (params) {

      const queryString = Object.values(params).toString().replaceAll(",","/");
      console.log('queryString', queryString);
      url = `${url}/${queryString}`;
    }

    return await this.#interceptedFetch(url, {
      method: 'GET'
    });
  }
  
  async post(url, data, options = {}) {
    return await this.#interceptedFetch(url, {
      ...options,
      method: 'POST',
      body: JSON.stringify(data)
    });
  }
  
  async put(url, data, options = {}) {
    return await this.#interceptedFetch(url, {
      ...options,
      method: 'PUT',
      body: JSON.stringify(data)
    });
  }
  
  async delete(url, options = {}) {
    return await this.#interceptedFetch(url, {
      ...options,
      method: 'DELETE'
    });
  }

  /**
   * 记录操作日志
   * @param {string} operation - 操作名称
   */
  async logOperation(operation) {
    try {
      const shopId = sessionStorage.getItem("im-yoda-cached-user");
      const shopNameElement = document.querySelector("div.shop-item-name--DHhspW1l");
      const shopName = shopNameElement ? shopNameElement.textContent : "";

      const data = {
        ShopId: shopId || "",
        Shop: shopName || "",
        Operation: operation
      };

      // 发送日志数据
      await this.post('/plugin/access', data);
    } catch (error) {
      console.error('记录操作日志失败:', error);
    }
  }
  
  // 公开的 Token 管理方法（如果需要外部调用）
  updateToken(token) {
    return this.#setToken(token);
  }
  
  clearToken() {
    return this.#removeToken();
  }
  
  hasToken() {
    return !!this.#getToken();
  }
}


// 将实例绑定到 window 对象，便于全局访问
window.api = new ApiInterceptor();
