import {
  APIUrlGenerator,
  httpGetRequest,
  httpPostRequest,
  httpPutRequest,
  httpDeleteRequest,
} from "@/utils/baseHttpService";
import { API_ROUTES } from "@/constant/routes";
import { Role, Permission } from "@/types/auth";
import {
  CreateRoleRequest,
  UpdateRoleRequest,
  RoleResponse,
  DeleteRoleResponse,
  AssignPermissionResponse,
  RoleFilters,
} from "./_models";

export const getRoles = async (filters?: RoleFilters) => {
  try {
    const queryParams: Record<string, string | number | null> = {};

    if (filters?.search) queryParams.search = filters.search;
    if (filters?.page) queryParams.page = filters.page;
    if (filters?.limit) queryParams.limit = filters.limit;

    const response = await httpGetRequest<{ roles: Role[] | null }>(
      APIUrlGenerator(API_ROUTES.GET_ROLES, queryParams)
    );
    console.log("Roles API Response:", response);
    console.log("Roles data:", response.data);

    if (
      response.data &&
      response.data.roles &&
      Array.isArray(response.data.roles)
    ) {
      return response.data.roles;
    }

    console.warn("Roles is null or not an array:", response.data);
    return [];
  } catch (error) {
    console.error("Error fetching roles:", error);
    return [];
  }
};

export const getRole = async (id: string) => {
  try {
    const response = await httpGetRequest<RoleResponse>(
      APIUrlGenerator(API_ROUTES.GET_ROLE(id))
    );
    console.log("Role API Response:", response);

    // Try nested structure first (like categories)
    if (response.data && response.data.role) {
      return response.data.role;
    }

    // Fallback to direct structure if nested doesn't exist
    if (response.data) {
      return response.data as unknown as Role;
    }

    throw new Error("No role data found in response");
  } catch (error) {
    console.error("Error fetching role:", error);
    throw error;
  }
};

export const createRole = async (roleData: CreateRoleRequest) => {
  const response = await httpPostRequest<Role>(
    APIUrlGenerator(API_ROUTES.CREATE_ROLE),
    roleData
  );
  return response.data;
};

export const updateRole = async (id: string, roleData: UpdateRoleRequest) => {
  const response = await httpPutRequest<Role>(
    APIUrlGenerator(API_ROUTES.UPDATE_ROLE(id)),
    roleData
  );
  return response.data;
};

export const deleteRole = async (id: string) => {
  const response = await httpDeleteRequest<DeleteRoleResponse>(
    APIUrlGenerator(API_ROUTES.DELETE_ROLE(id))
  );
  return response.data;
};

export const getRolePermissions = async (id: string) => {
  try {
    const response = await httpGetRequest<{ permissions: Permission[] | null }>(
      APIUrlGenerator(API_ROUTES.GET_ROLE_PERMISSIONS(id))
    );

    console.log("Role Permissions API Response:", response);
    console.log("Role Permissions data:", response.data);

    // Handle API response structure: {data: {permissions: Permission[] | null}}
    if (
      response.data &&
      response.data.permissions &&
      Array.isArray(response.data.permissions)
    ) {
      return response.data.permissions;
    }

    // If permissions is null or not an array, return empty array
    console.warn("Role Permissions is null or not an array:", response.data);
    return [];
  } catch (error) {
    console.error("Error fetching role permissions:", error);
    return [];
  }
};

export const assignPermissionToRole = async (
  roleId: string,
  permissionId: string
) => {
  const response = await httpPostRequest<AssignPermissionResponse>(
    APIUrlGenerator(API_ROUTES.ASSIGN_ROLE_PERMISSION(roleId, permissionId)),
    {}
  );
  return response.data;
};

export const removePermissionFromRole = async (
  roleId: string,
  permissionId: string
) => {
  const response = await httpDeleteRequest<AssignPermissionResponse>(
    APIUrlGenerator(API_ROUTES.REMOVE_ROLE_PERMISSION(roleId, permissionId))
  );
  return response.data;
};

export const getAllPermissions = async () => {
  const response = await httpGetRequest<Permission[]>(
    APIUrlGenerator(API_ROUTES.GET_PERMISSIONS)
  );
  return response.data;
};
