import { create } from 'zustand';
import axiosInstance from '@/utils/axios';
import { IRole } from '@/shared/types/role';
import { userEndpoints } from '../endpoints/user';
import { processPermissions } from '@/shared/types/permission';
import { Permission } from '@/shared/types/permission';

export enum RoleStatus {
  ENABLED = 'ENABLED',
  DISABLED = 'DISABLED'
}

type RolePageFilterParams = {
  page?: number;
  size?: number;
  sortBy?: string;
  sortDirection?: 'ASC' | 'DESC';
};

type RoleStore = {
  error: string | null;
  loading: boolean;
  roles: IRole[];
  totalElements: number;
  selectedRole: IRole | null;
  getPermissionsByRoleName: (roleName: string) => Promise<string[]>;
  fetchRoles: (params?: RolePageFilterParams) => Promise<void>;
  getRoleById: (id: number) => Promise<IRole>;
  createRole: (data: IRole) => Promise<void>;
  updateRole: (id: number | string, data: IRole) => Promise<void>;
  toggleRoleStatus: (id: number | string, status: 'ENABLED' | 'DISABLED') => Promise<void>;
};



export const useRoleStore = create<RoleStore>((set, get) => ({
  error: null,
  loading: false,
  roles: [],
  totalElements: 0,
  selectedRole: null,

  fetchRoles: async (params = {}) => {
    set({ loading: true, error: null });

    try {
      const { page = 0, size = 10, sortBy = 'name', sortDirection = 'ASC' } = params;
      const response = await axiosInstance.get(
        `/api/user/role/all?page=${page}&size=${size}&sortBy=${sortBy}&sortDirection=${sortDirection}`
      );

      const rolesWithTranslatedPermissions = response.data.content.map((role: IRole) => {
        const transformedPermissions = processPermissions(role.permissions as Permission[]);
        return {
          ...role,
          modules: transformedPermissions,
        };
      });

      set({
        roles: rolesWithTranslatedPermissions,
        totalElements: response.data.totalElements,
        loading: false,
      });
    } catch (error: any) {
      set({
        error: error.message || 'Failed to fetch roles',
        loading: false,
      });
    }
  },

  getRoleById: async (id) => {
    set({ loading: true, error: null });
    try {
      const response = await axiosInstance.get(`/api/user/role/${id}`);
      set({ loading: false, selectedRole: response.data });
      return response.data;
    } catch (error: any) {
      set({
        error: error.message || 'Failed to fetch role',
        loading: false,
      });
      throw error;
    }
  },

  createRole: async (data) => {
    set({ loading: true, error: null });
    try {
      const { data: created } = await axiosInstance.post<IRole>(userEndpoints.user.Role.createRole, data);
      set((s) => ({ roles: [created, ...(s.roles || [])], loading: false }));
    } catch (e: any) {
      set({ error: e.message, loading: false });
      throw e;
    }
  },

  updateRole: async (id, data) => {
    set({ loading: true, error: null });
    try {
      const { data: updated } = await axiosInstance.put<IRole>(userEndpoints.user.Role.updateRole(id), data);
      set((s) => ({
        roles: (s.roles || []).map(r => r.id === id ? updated : r),
        loading: false,
      }));
    } catch (e: any) {
      set({ error: e.message, loading: false });
      throw e;
    }
  },

  toggleRoleStatus: async (id, status) => {
    set({ loading: true, error: null });
    try {
      const { data: updated } = await axiosInstance.put<IRole>(userEndpoints.user.Role.changeStatus(id, status), null);
      set((s) => ({
        roles: (s.roles || []).map(r => r.id === id ? updated : r),
        loading: false,
      }));
    } catch (e: any) {
      set({ error: e.message, loading: false });
    }
  },
  getPermissionsByRoleName: async (roleName) => {
  set({ loading: true, error: null });
  try {
    const response = await axiosInstance.get<string[]>(
      userEndpoints.user.Role.getPermissionsByRoleName(roleName)
    );
    set({ loading: false });
    return response.data;
  } catch (error: any) {
    set({ error: error.message || 'Erreur lors de la récupération des permissions', loading: false });
    throw error;
  }
},
})); 