import axios, { type AxiosInstance, type AxiosResponse, type InternalAxiosRequestConfig } from 'axios';
import { ElMessage } from 'element-plus';
import { useAuthStore } from '@/stores/auth';
import { useServerStore } from '@/stores/server';
import router from '@/router';
import type { ApiResponse } from '@media-manager/shared';

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

// 将 localhost 规范为 127.0.0.1，避免 Windows 上 IPv6(::1) 导致 ECONNREFUSED
function normalizeBaseUrlForRequest(url: string): string {
  try {
    const u = new URL(url);
    if (u.hostname === 'localhost' || u.hostname === '::1') {
      u.hostname = '127.0.0.1';
    }
    return u.origin.replace(/\/$/, '');
  } catch {
    return url;
  }
}

function isLocalBackend(url: string): boolean {
  try {
    const u = new URL(url);
    const port = u.port || (u.protocol === 'https:' ? '443' : '80');
    return (u.hostname === 'localhost' || u.hostname === '127.0.0.1' || u.hostname === '::1') && port === '3000';
  } catch {
    return false;
  }
}

// 请求拦截器
request.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const serverStore = useServerStore();
    const authStore = useAuthStore();

    // 设置基础 URL：显式传入的 baseURL 优先，否则用 store
    const rawBaseUrl = config.baseURL ?? serverStore.currentServer?.url;
    if (rawBaseUrl) {
      // 开发环境下本地 3000 端口走 Vite 代理，避免 CORS 和重复 Access-Control-Allow-Origin 头
      const isDevLocal = import.meta.env.DEV && isLocalBackend(rawBaseUrl);
      config.baseURL = isDevLocal ? '' : normalizeBaseUrlForRequest(rawBaseUrl);
    }

    // 添加认证 token
    if (authStore.accessToken) {
      config.headers.Authorization = `Bearer ${authStore.accessToken}`;
    }

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

// 是否正在刷新 token
let isRefreshing = false;
// 等待刷新的请求队列
let refreshSubscribers: ((token: string) => void)[] = [];

// 通知所有等待的请求
function onRefreshed(token: string) {
  refreshSubscribers.forEach(callback => callback(token));
  refreshSubscribers = [];
}

// 添加到等待队列
function addRefreshSubscriber(callback: (token: string) => void) {
  refreshSubscribers.push(callback);
}

// GET 请求重试机制：对网络错误和超时自动重试
const GET_RETRY_COUNT = 2;
const GET_RETRY_DELAY = 1000; // 1秒

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse<ApiResponse>) => {
    const data = response.data;

    if (data.success) {
      return data.data as any;
    }

    // 业务错误
    ElMessage.error(data.message || '请求失败');
    return Promise.reject(new Error(data.message));
  },
  async (error) => {
    const originalRequest = error.config;

    // GET 请求自动重试：网络错误或超时时重试，避免后端暂时不可用导致失败
    const isGetRequest = originalRequest.method?.toLowerCase() === 'get';
    const isRetryable = !error.response && (error.code === 'ERR_NETWORK' || error.code === 'ECONNABORTED');
    const retryCount = (originalRequest as any)._retryCount ?? 0;

    if (isGetRequest && isRetryable && retryCount < GET_RETRY_COUNT && !originalRequest.url?.includes('/api/auth/')) {
      (originalRequest as any)._retryCount = retryCount + 1;
      console.warn(`[Request] Retrying GET ${originalRequest.url} (attempt ${retryCount + 1}/${GET_RETRY_COUNT})`);
      await new Promise(resolve => setTimeout(resolve, GET_RETRY_DELAY));
      return request(originalRequest);
    }

    // 排除不需要刷新 token 的请求
    const isAuthRequest = originalRequest.url?.includes('/api/auth/refresh')
      || originalRequest.url?.includes('/api/auth/login')
      || originalRequest.url?.includes('/api/auth/register');

    // Token 过期，尝试刷新（排除认证相关请求）
    if (error.response?.status === 401 && !originalRequest._retry && !isAuthRequest) {
      originalRequest._retry = true;

      // 如果已经在刷新中，将请求加入队列等待
      if (isRefreshing) {
        return new Promise((resolve) => {
          addRefreshSubscriber((token: string) => {
            originalRequest.headers.Authorization = `Bearer ${token}`;
            resolve(request(originalRequest));
          });
        });
      }

      isRefreshing = true;
      const authStore = useAuthStore();

      try {
        const refreshed = await authStore.refreshAccessToken();

        if (refreshed) {
          const newToken = authStore.accessToken!;
          onRefreshed(newToken);
          originalRequest.headers.Authorization = `Bearer ${newToken}`;
          return request(originalRequest);
        }
      } catch {
        // 刷新失败
      } finally {
        isRefreshing = false;
      }

      // 刷新失败，清除等待队列并跳转登录
      refreshSubscribers = [];
      authStore.clearTokens();
      ElMessage.error('登录已过期，请重新登录');
      router.push('/login');
      return Promise.reject(error);
    }

    // 认证请求失败（login/register 等）
    if (isAuthRequest) {
      // 获取错误消息
      const message = error.response?.data?.error?.message
        || error.response?.data?.message
        || error.message
        || '认证失败';

      // 显示错误消息
      ElMessage.error(message);

      // refresh 请求失败才清除 token 并跳转
      if (originalRequest.url?.includes('/api/auth/refresh')) {
        const authStore = useAuthStore();
        authStore.clearTokens();
        router.push('/login');
      }

      return Promise.reject(error);
    }

    // 网络错误（无响应）：不弹错误弹窗，仅在控制台记录，避免后端未就绪时频繁弹窗干扰用户
    if (!error.response && error.code === 'ERR_NETWORK') {
      console.warn('[Request] Network error (backend may be unavailable):', error.message, error.config?.url);
      return Promise.reject(error);
    }

    // 请求超时：不弹错误弹窗，仅在控制台记录
    if (error.code === 'ECONNABORTED' && error.message?.includes('timeout')) {
      console.warn('[Request] Request timeout:', error.config?.url);
      return Promise.reject(error);
    }

    // 其他错误
    const message = error.response?.data?.error?.message
      || error.response?.data?.message
      || error.message
      || '网络错误';

    ElMessage.error(message);
    return Promise.reject(error);
  }
);

export default request;
