import {
  createApi,
  fetchBaseQuery,
  BaseQueryFn,
  FetchArgs,
  FetchBaseQueryError,
} from "@reduxjs/toolkit/query/react";
import { getSession, signOut } from "next-auth/react";
import URLS from "./constants";
import { toast } from "@/hooks/use-toast";
import { performServerLogout } from "@/lib/server/logout";

const baseQueryWithAuth: BaseQueryFn<
  FetchArgs,
  unknown,
  FetchBaseQueryError
> = async (args, api, extraOptions) => {
  const session = await getSession();

  // if (!session?.accessToken) {
  //   console.warn("No session available, skipping API call.");
  //   return { data: null };
  // }

  let result;

  const rawBaseQuery = fetchBaseQuery({
    baseUrl: `${URLS.HOST_URL}${URLS.COMMON_SUFFIX_URL}`,
    credentials: "same-origin",
    prepareHeaders: (headers) => {
      if (session?.accessToken) {
        headers.set("Authorization", `Bearer ${session.accessToken}`);
      }
      const deviceToken = localStorage.getItem("fcmToken");
      if (deviceToken) headers.set("deviceToken", deviceToken);

      return headers;
    },
  });

  const handleLogout = async () => {
    console.warn("Unauthorized! Signing out...");

    const deviceTokenRaw =
      typeof window !== "undefined"
        ? localStorage.getItem("fcmToken")
        : undefined;

    if (deviceTokenRaw) {
      await performServerLogout(deviceTokenRaw ?? undefined);

      signOut({ callbackUrl: "/login" });
    } else {
      signOut({ callbackUrl: "/login" });
    }
  };

  const refreshToken = async (): Promise<string | null> => {
    const refreshToken = session?.refreshToken;
    if (!refreshToken) return null;

    try {
      const response = await fetch(
        `${URLS.HOST_URL}${URLS.AUTH}/refresh-tokens`,
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ refreshToken }),
        }
      );
      if (!response.ok) {
        let errorMessage = "Invalid token";

        try {
          const errorData = (await response.json()) as { message?: string };
          if (errorData?.message) {
            errorMessage = errorData.message;
          }
        } catch (e) {
          console.error("Failed to parse error response:", e);
        }

        toast({
          variant: "destructive",
          title: "Unauthorized",
          description: errorMessage,
        });

        handleLogout();
        return null;
      }

      const data = await response.json();
      const { accessToken } = data;
      if (accessToken) {
        localStorage.setItem("accessToken", accessToken);
        return accessToken;
      }

      handleLogout();
      return null;
    } catch (error) {
      console.log(error);
      handleLogout();
      return null;
    }
  };

  result = await rawBaseQuery(args, api, extraOptions);

  if (result?.error?.status === 401) {
    const newAccessToken = await refreshToken();
    if (newAccessToken) {
      args.headers = {
        ...args.headers,
        Authorization: `Bearer ${newAccessToken}`,
      };
      result = await rawBaseQuery(args, api, extraOptions);
    }
  }

  return result;
};

export const apiSlice = createApi({
  baseQuery: baseQueryWithAuth,
  tagTypes: [
    "Category",
    "SubCategory",
    "PropertyUsage",
    "PropertySize",
    "Area",
    "City",
    "State",
    "Country",
    "Amenities",
    "Tags",
    "Source",
    "Company",
    "User",
    "PropertyConfiguration",
    "individualProperties",
    "editIndividualProperties",
    "Contact",
    "Support",
    "LeadStage",
    "Role",
    "Team",
    "Lead",
    "BankAccount",
    "Task",
    "Project",
    "PaymentPlan",
    "ProjectCharge",
    "InvoiceSettings",
    "ProjectUnits",
    "Quotation",
    "Target",
    "Document",
    "Activity",
    "PaymentTerm",
    "Invoice",
    "ProjectFiles",
    "ProjectTimeline",
    "UnitJobs",
    "Notification",
    "PushNotification",
    "Customer",
    "Campaign",
    "PartnerNetwork",
    "MakanifySite",
    "LeadScore",
    "Rules",
    "Dashboard",
    "individualPropertiesProspects",
    "Whatsapp",
    "Fast2sms",
    "ClickStats",
    "EmailTemplate",
    "ProfileUser",
    "CaptureLead",
    "CompanyById",
    "SidebarAnalytics",
  ],
  endpoints: () => ({}),
});
