import api from "../axios";
import type { Role } from "./roles";

export interface User {
  id: string;
  name: string;
  firstName?: string | null;
  lastName?: string | null;
  email: string;
  login: string;
  image?: string;
  roles: string[];
  permissions?: string[];
  createdAt: string;
  updatedAt: string;
}

export interface PermissionCheckResult {
  permission: string;
  hasPermission: boolean;
}

export const users = {
  /**
   * Fetch all users.
   * Requires: user.read.other, user.list.other
   */
  async fetchAll(accessToken: string): Promise<{ data: User[] }> {
    const response = await api.get("/v1/user/users", {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });
    return response.data;
  },

  /**
   * Fetch a specific user by their ID.
   * Requires: user.read.other
   */
  async fetch(
    accessToken: string,
    identifier: string
  ): Promise<{ data: User }> {
    const response = await api.get(`/v1/user/users/${identifier}`, {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });
    return response.data;
  },

  /**
   * Update a specific user's information.
   * Requires: user.write.other
   * Conditional: user.roles.other (if roles included), user.permissions.other (if permissions included)
   */
  async update(
    accessToken: string,
    identifier: string,
    updates: {
      name?: string;
      firstName?: string | null;
      lastName?: string | null;
      image?: string;
      roles?: string[];
      permissions?: string[];
    }
  ): Promise<{ data: User }> {
    const response = await api.patch(`/v1/user/users/${identifier}`, updates, {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });
    return response.data;
  },

  /**
   * Delete a specific user.
   * Requires: user.delete.other
   */
  async delete(
    accessToken: string,
    identifier: string
  ): Promise<{ data: User }> {
    const response = await api.delete(`/v1/user/users/${identifier}`, {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });
    return response.data;
  },

  /**
   * Fetch all roles assigned to a specific user.
   * Requires: user.read.other, role.read
   */
  async fetchRoles(
    accessToken: string,
    identifier: string
  ): Promise<{ data: Role[] }> {
    const response = await api.get(`/v1/user/users/${identifier}/roles`, {
      headers: {
        Authorization: `Bearer ${accessToken}`,
      },
    });
    return response.data;
  },

  /**
   * Check if a specific user has certain permissions.
   * Requires: user.read.other
   */
  async checkPermissions(
    accessToken: string,
    identifier: string,
    permissions: string[]
  ): Promise<{ data: { results: PermissionCheckResult[] } }> {
    const response = await api.post(
      `/v1/user/users/${identifier}/check-permission`,
      { permissions },
      {
        headers: {
          Authorization: `Bearer ${accessToken}`,
        },
      }
    );
    return response.data;
  },
};
