"use server";
import NextCrypto from "next-crypto";
import { fetchData, fetchDataWithToken } from "@/apifetchers/api-fetcher";
import { baseUrlAuth, cookieObject, tokenSecret } from "@/apifetchers/basics";
import { cookies } from "next/headers";
import { setNewCompleteToRedis, getCompleteFromRedis } from "@/apifetchers/mutual/context/complete/fetch";
import {
  defaultClientHeader,
  defaultClientMenu,
  defaultClientOnline,
  defaultClientPageConfig,
  defaultLinkList
} from "@/types/mutual/context/validations";
import { retrievePageList } from "@/apifetchers/mutual/cookies/token";
import { deleteAllCookies } from "@/apifetchers/mutual/cookies/cookie-actions";
import { setMenuToRedis } from "@/apifetchers/mutual/context/page/menu/fetch";

const loginEndpoint = `${baseUrlAuth}/authentication/login`;
const loginSelectEndpoint = `${baseUrlAuth}/authentication/select`;
const logoutEndpoint = `${baseUrlAuth}/authentication/logout`;

interface LoginViaAccessKeys {
  accessKey: string;
  password: string;
  rememberMe: boolean;
}

interface LoginSelect {
  uuid: string;
}

interface LoginSelectOccupant {
  uuid: any;
}

async function logoutActiveSession() {
  const response = await fetchDataWithToken(logoutEndpoint, {}, "GET", false);
  await deleteAllCookies();
  return response;
}

async function initRedis(loginRespone: any, firstSelection: any, accessToken: string, redisKey: string) {
  let alreadyAtRedis = null
  try {
    const redisData = await getCompleteFromRedis();
    alreadyAtRedis = redisData;
  } catch (error) { }
  if (!alreadyAtRedis) {
    const loginObjectToRedis = {
      online: {
        ...defaultClientOnline,
        lastLogin: new Date(),
        userType: `${loginRespone.user_type}`.toUpperCase(),
        lang: loginRespone.user.person.country_code.toLowerCase(),
      },
      pageConfig: defaultClientPageConfig,
      menu: defaultClientMenu,
      header: defaultClientHeader,
      selection: { selectionList: loginRespone.selection_list, activeSelection: firstSelection },
      user: loginRespone.user,
      settings: { lastOnline: new Date(), token: accessToken },
      chatRoom: defaultLinkList,
      notifications: defaultLinkList,
      messages: defaultLinkList,
    }
    await setNewCompleteToRedis(loginObjectToRedis, redisKey);
  }
}

async function loginViaAccessKeys(payload: LoginViaAccessKeys) {
  const cookieStore = await cookies();
  try {
    const response = await fetchData(
      loginEndpoint,
      {
        access_key: payload.accessKey,
        password: payload.password,
        remember_me: payload.rememberMe,
      },
      "POST",
      false
    );
    await deleteAllCookies()
    if (response.status === 200 || response.status === 202) {

      const loginRespone: any = response?.data;
      const firstSelection = loginRespone.selection_list.find((item: any) => item.uu_id === loginRespone.selection_list[0].uu_id);

      const nextCrypto = new NextCrypto(tokenSecret);
      const accessToken = await nextCrypto.encrypt(loginRespone.access_token);

      const redisKey = `CLIENT:${loginRespone.user_type.toUpperCase()}:${firstSelection.uu_id}`;
      const redisKeyAccess = await nextCrypto.encrypt(redisKey);
      const usersSelection = await nextCrypto.encrypt(
        JSON.stringify({
          selected: firstSelection.uu_id,
          userType: loginRespone.user_type.toUpperCase(),
          redisKey,
        })
      );

      await initRedis(loginRespone, firstSelection, accessToken, redisKey);
      cookieStore.set({
        name: "eys-zzz",
        value: accessToken,
        ...cookieObject,
      });
      cookieStore.set({
        name: "eys-yyy",
        value: redisKeyAccess,
        ...cookieObject,
      });
      cookieStore.set({
        name: "eys-sel",
        value: usersSelection,
        ...cookieObject,
      });
      try {
        return {
          completed: true,
          message: "Login successful",
          status: 200,
          data: loginRespone,
        };
      } catch (error) {
        console.error("JSON parse error:", error);
        return {
          completed: false,
          message: "Login NOT successful",
          status: 401,
          data: "{}",
        };
      }
    }

    return {
      completed: false,
      // error: response.error || "Login failed",
      // message: response.message || "Authentication failed",
      status: response.status || 500,
    };
  } catch (error) {
    console.error("Login error:", error);
    return {
      completed: false,
      // error: error instanceof Error ? error.message : "Login error",
      // message: "An error occurred during login",
      status: 500,
    };
  }
}

async function loginSelectEmployee(payload: LoginSelect) {
  const cookieStore = await cookies();
  const nextCrypto = new NextCrypto(tokenSecret);
  const employeeUUID = payload.uuid;
  const redisKey = `CLIENT:EMPLOYEE:${employeeUUID}`;
  const selectResponse: any = await fetchDataWithToken(loginSelectEndpoint, { uuid: employeeUUID }, "POST", false);
  cookieStore.delete({ name: "eys-sel", ...cookieObject });

  if (selectResponse.status === 200 || selectResponse.status === 202) {
    const usersSelection = await nextCrypto.encrypt(
      JSON.stringify({
        selected: employeeUUID,
        userType: "employee",
        redisKey,
      })
    );
    cookieStore.set({
      name: "eys-sel",
      value: usersSelection,
      ...cookieObject,
    });
    try {
      const pageList = await retrievePageList()
      await setMenuToRedis({
        selectionList: pageList,
        activeSelection: "/dashboard"
      })
    } catch (error) { }
  }
  return selectResponse;
}

async function loginSelectOccupant(payload: LoginSelectOccupant) {
  const livingSpaceUUID = payload.uuid;
  const cookieStore = await cookies();
  const nextCrypto = new NextCrypto(tokenSecret);

  const selectResponse: any = await fetchDataWithToken(loginSelectEndpoint, { uuid: livingSpaceUUID }, "POST", false);
  const redisKey = `CLIENT:OCCUPANT:${livingSpaceUUID}`;
  cookieStore.delete("eys-sel");

  if (selectResponse.status === 200 || selectResponse.status === 202) {
    const usersSelection = await nextCrypto.encrypt(
      JSON.stringify({
        selected: livingSpaceUUID,
        userType: "OCCUPANT",
        redisKey,
      })
    );
    cookieStore.set({
      name: "eys-sel",
      value: usersSelection,
      ...cookieObject,
    });
  }
  return selectResponse;
}

export {
  loginViaAccessKeys,
  loginSelectEmployee,
  loginSelectOccupant,
  logoutActiveSession,
};
