import { useStorage } from "@vueuse/core";

export default defineNuxtPlugin((nuxtApp) => {
  // ======================
  // Runtime Config (Public)
  // ======================
  const config = useRuntimeConfig();

  const BASE_URL = config.public.NUXT_PUBLIC_BASE_URL || "";
  const API_NAME = config.public.NUXT_PUBLIC_API_NAME || "";

  // ======================
  // Safe URL Joiner
  // ======================
  const joinURL = (base: string, path: string) => {
    return `${base.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
  };

  const baseURL = joinURL(BASE_URL, API_NAME);

  // ======================
  // Reactive Token
  // ======================
  const token = useStorage<string>("id_token", "GuestAccess");

  // ======================
  // Fetch Instance
  // ======================
  const api = $fetch.create({
    baseURL,

    // ======================
    // Request Interceptor
    // ======================
    onRequest({ options }) {
      const auth = token.value;
      if (!auth) return;
      const headers = (options.headers ||= {});
      if (headers instanceof Headers) {
        headers.set("Authorization", auth);
      } else if (Array.isArray(headers)) {
        headers.push(["Authorization", auth]);
      } else {
        headers.Authorization = auth;
      }
    },

    // ======================
    // Response Handler
    // ======================
    onResponse({ response }) {
      return response._data;
    },

    // ======================
    // Error Handler
    // ======================
    async onResponseError({ response }) {
      const status = response?.status;

      if (status === 401) {
        token.value = null;
        await nuxtApp.runWithContext(() => navigateTo("/login"));
      }

      throw {
        status,
        message:
          response?._data?.message || response?.statusText || "خطای نامشخص",
        data: response?._data || null,
      };
    },
  });

  // ======================
  // HTTP Service (Public API)
  // ======================
  const http = {
    getRequest: (url: string, options: any = {}) =>
      api(url, { method: "GET", ...options }),

    postRequest: (url: string, body: any, options: any = {}) =>
      api(url, { method: "POST", body, ...options }),

    putRequest: (url: string, body: any, options: any = {}) =>
      api(url, { method: "PUT", body, ...options }),

    patchRequest: (url: string, body: any, options: any = {}) =>
      api(url, { method: "PATCH", body, ...options }),

    deleteRequest: (url: string, options: any = {}) =>
      api(url, { method: "DELETE", ...options }),
  };

  // ======================
  // Provide to Nuxt
  // ======================
  return {
    provide: {
      http,
    },
  };
});
