import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";

import { deleteCookie, getCookie, setCookie } from "cookies-next";
import { useLogoutHandler } from "@/models/Auth/AuthModel";
import {
  CreateTopicRequest,
  CreateTopicResponse,
  DeleteTopicRequest,
  DeleteTopicResponse,
  GetAllTopicRequest,
  GetAllTopicResponse,
  GetSingleTopicRequest,
  GetSingleTopicResponse,
  UpdateTopicRequest,
  UpdateTopicResponse,
} from "./TopicTypes";

const baseQuery = fetchBaseQuery({
  baseUrl: process.env.NEXT_PUBLIC_PORT,
  prepareHeaders: (headers) => {
    const user = getCookie("lookna_admin");
    const parsedUser = user ? JSON.parse(user as string) : null;

    const token = parsedUser?.data?.token;
    if (token) headers.set("Authorization", `Bearer ${token}`);
    return headers;
  },
});

const baseQueryWithReauth: typeof baseQuery = async (
  args,
  api,
  extraOptions
) => {
  let result = await baseQuery(args, api, extraOptions);

  if (
    result.error &&
    result.error.status === 403 &&
    (result.error.data as { message?: string })?.message ===
      "Invalid or expired token"
  ) {
    const user = getCookie("lookna_admin");
    const parsedUser = user ? JSON.parse(user as string) : null;
    const refreshToken = parsedUser?.data?.refreshToken;

    const refreshResult = await fetch(
      `${process.env.NEXT_PUBLIC_PORT}/api/refresh-token`,
      {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ refreshToken: refreshToken, deviceId: "Web" }),
      }
    );

    if (refreshResult.ok) {
      const data = await refreshResult.json();
      setCookie(
        "lookna_admin",
        JSON.stringify({
          ...parsedUser,
          data: { ...parsedUser.data, token: data.token },
        })
      );
      result = await baseQuery(args, api, extraOptions);
    } else {
      const errorData = await refreshResult.json();
      if (errorData?.message === "Invalid refresh token") {
        deleteCookie("lookna_admin");
        if (typeof window !== "undefined") {
          window.location.href = "/login";
        }
      }
    }
  }

  return result;
};

export const TopicSlice = createApi({
  reducerPath: "Topics",
  baseQuery: baseQueryWithReauth,
  tagTypes: ["Topics"],
  endpoints: (build) => ({
    getAllTopics: build.query<GetAllTopicResponse, GetAllTopicRequest>({
      query: ({ page, limit, search }) => {
        const baseUrl = `/api/topics/all-topics?page=${page}&limit=${limit}`;
        let searchParams = "";
        if (search && typeof search === "object") {
          const searchEntries = Object.entries(search);
          if (searchEntries.length > 0) {
            searchParams =
              "&" +
              searchEntries
                .map(
                  ([key, value]) =>
                    `search[${key}]=${encodeURIComponent(value as string)}`
                )
                .join("&");
          }
        }
        return {
          url: baseUrl + searchParams,
          method: "GET",
        };
      },
      providesTags: ["Topics"],
    }),

    createTopic: build.mutation<CreateTopicResponse, CreateTopicRequest>({
      query: (data) => {
        return {
          url: `/api/topics/create-topic`,
          method: "POST",
          body: data,
        };
      },
      invalidatesTags: ["Topics"],
    }),

    getSingleTopic: build.query<GetSingleTopicResponse, GetSingleTopicRequest>({
      query: ({ topicID, page, limit, search }) => {
        const baseUrl = `/api/topics/single-topics/${topicID}?page=${page}&limit=${limit}`;
        let searchParams = "";
        if (search && typeof search === "object") {
          const searchEntries = Object.entries(search);
          if (searchEntries.length > 0) {
            searchParams =
              "&" +
              searchEntries
                .map(
                  ([key, value]) =>
                    `search[${key}]=${encodeURIComponent(value as string)}`
                )
                .join("&");
          }
        }
        return {
          url: baseUrl + searchParams,
          method: "GET",
        };
      },
      providesTags: ["Topics"],
    }),

    updateTopic: build.mutation<UpdateTopicResponse, UpdateTopicRequest>({
      query: ({ topicID, data }) => {
        return {
          url: `api/topics/update-topic/${topicID}`,
          method: "PATCH",
          body: data,
        };
      },
    }),

    deleteTopic: build.mutation<DeleteTopicResponse, DeleteTopicRequest>({
      query: ({ topicID }) => {
        return {
          url: `api/topics/delete-topic/${topicID}`,
          method: "DELETE",
        };
      },
    }),
  }),
});

export const {
  useGetAllTopicsQuery,
  useCreateTopicMutation,
  useGetSingleTopicQuery,
  useUpdateTopicMutation,
  useDeleteTopicMutation,
} = TopicSlice;
