import axios from "axios";
import { store } from "../../redux/store";
import { showLoading, hideLoading } from "../../redux/slices/loadingSlice";
import { clearToken } from "../../redux/slices/authSlice";
import { clearProfile } from "../../redux/slices/profileSlice";
import { showToast } from "../../redux/slices/toastSlice";
import { toastIgnore } from "./toastIgnore";

const BASE_URL = 'https://cafeju.maksiran.ir/api';
const TIMEOUT = 600000;

axios.defaults.baseURL = BASE_URL;
axios.defaults.timeout = TIMEOUT;

// Helpers
const isMutatingMethod = (method) => ["post", "put", "delete", "patch"].includes(method?.toLowerCase());

const extractMessage = (obj) =>
  obj?.response?.data?.data?.message ||
  obj?.data?.data?.message ||
  obj?.message ||
  obj?.data?.message ||
  obj?.response?.data?.message ||
  obj?.response?.message ||
  "خطایی رخ داده است!";

const getErrorMessageByStatus = (status, data) => {
  switch (status) {
    case 400: return data?.message || "درخواست نامعتبر است";
    case 401: return data?.message || "نشست شما منقضی شده، مجدد وارد شوید";
    case 403: return data?.message || "دسترسی شما محدود شده است";
    case 404: return data?.message || "صفحه یا اطلاعات درخواستی یافت نشد";
    case 422: return data?.message || "اطلاعات ارسالی نامعتبر است";
    case 429: return data?.message || "تعداد درخواست‌ها زیاد است، کمی صبر کنید";
    case 500: return data?.message || "خطای داخلی سرور، لطفاً بعداً تلاش کنید";
    case 502:
    case 503: return data?.message || "سرور در حال حاضر در دسترس نیست";
    case 504: return data?.message || "سرور پاسخ نداد، دوباره تلاش کنید";
    default: return data?.message || `خطای غیرمنتظره (کد: ${status})`;
  }
};

// Request Interceptor
axios.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem("token");
    if (token) config.headers.Authorization = `Bearer ${token}`;
    store.dispatch(showLoading());
    return config;
  },
  (error) => {
    store.dispatch(hideLoading());
    return Promise.reject(error);
  }
);

// Response Interceptor
axios.interceptors.response.use(
  (response) => {
    try {
      const method = response.config.method;
      const url = response.config.url;
      if (!toastIgnore.some(u => url.includes(u)) && isMutatingMethod(method)) {
        const message = extractMessage(response) || "عملیات با موفقیت انجام شد";
        store.dispatch(showToast({ type: "success", message }));
      }
    } catch (e) {
      console.error("toast response error:", e);
    } finally {
      store.dispatch(hideLoading());
    }
    return response;
  },
  (error) => {
    store.dispatch(hideLoading());

    if (!error.response) {
      const networkMessage = error.message.includes("Network Error") 
        ? "لطفا اتصال اینترنت خود را بررسی کنید" 
        : error.message.includes("timeout") 
        ? "مهلت زمانی درخواست تمام شد، دوباره تلاش کنید" 
        : "خطا در برقراری ارتباط با سرور";

      store.dispatch(showToast({ message: networkMessage, type: "error" }));
      return Promise.reject(error);
    }

    const { status, data } = error.response;
    const url = error.config?.url || "";

    // برای خطاهای 401 و 403: فورا توکن پاک شود
    if ([401, 403].includes(status)) {
      store.dispatch(clearToken());
      store.dispatch(clearProfile());
      
      // redirect به login اگر در protected route هستیم
      if (typeof window !== "undefined") {
        const currentPath = window.location.pathname;
        const publicRoutes = ["/login", "/register", "/"];
        const isPublicRoute = publicRoutes.some(route => currentPath.startsWith(route));
        
        if (!isPublicRoute) {
          window.location.href = "/login";
        }
      }
    }

    if (!toastIgnore.some(u => url.includes(u))) {
      const message = getErrorMessageByStatus(status, data);
      store.dispatch(showToast({ type: "error", message }));
    }

    return Promise.reject(error);
  }
);

// Request Wrappers
const requests = {
  get: (url) => axios.get(url),
  getByParams: (url, params) => axios.get(url, { params }),
  post: (url, body) => axios.post(url, body),
  put: (url, body) => axios.put(url, body),
  patch: (url, body) => axios.patch(url, body),
  delete: (url) => axios.delete(url),
  postFormData: (url, formData) =>
    axios.post(url, formData, { headers: { "Content-Type": "multipart/form-data" } }),
  putMedia: (url, body) =>
    axios.put(url, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } }),
};

export default requests;