import type { IRoleItem, IRoleRequest, IRolePageable } from 'src/contexts/types/role';

import axios from 'axios';
import { create } from 'zustand';

import { transformDate } from 'src/contexts/types/user';

import { roleEndpoints } from '../endpoints/role';

export type SearchRolesParams = {
  name?: string;
  description?: string;
  createdAt?: string;
  sortBy?: string;
  sortDirection?: 'asc' | 'desc';
  page?: number;
  size?: number;
};

type RoleStore = {
  roles: IRoleItem[];
  loading: boolean;
  error: string | null;
  totalElements: number;
  totalPages: number;
  currentPage: number;
  pageSize: number;
  currentFilters: SearchRolesParams;
  addRole: (roleData: IRoleRequest) => Promise<void>;
  updateRole: (id: string, roleData: IRoleRequest) => Promise<void>;
  deleteRole: (id: number) => Promise<void>;
  getAllRoles: (params?: SearchRolesParams) => Promise<void>;
  clearFilters: () => void;
  setCurrentFilters: (filters: SearchRolesParams) => void;
  resetState: () => void;
};
const initialState = {
  roles: [],
  loading: false,
  error: null,
  totalElements: 0,
  totalPages: 0,
  currentPage: 0,
  pageSize: 10,
  currentFilters: {},
};
export const useRoleStore = create<RoleStore>((set) => ({
  ...initialState,

  addRole: async (roleData) => {
    set({ loading: true, error: null });
    try {
      const response = await axios({
        method: 'post',
        url: roleEndpoints.role.add,
        data: roleData,
      });
      const newRole = response.data;

      set((state) => ({
        roles: [newRole, ...state.roles],
        loading: false,
      }));
    } catch (error: any) {
      set({ error: error.message || 'Failed to add role', loading: false });
      throw error;
    }
  },

  updateRole: async (id, roleData) => {
    set({ loading: true, error: null });
    try {
      const response = await axios.put(
        roleEndpoints.role.edit.replace(':id', String(id)),
        roleData
      );

      const updatedRole = response.data;

      set((state) => ({
        roles: state.roles.map((role) => (role.id === updatedRole.id ? updatedRole : role)),
        loading: false,
        error: null,
      }));
    } catch (error: any) {
      set({ error: error.message || 'Failed to update role', loading: false });
      throw error;
    }
  },

  deleteRole: async (id) => {
    set({ loading: true, error: null });
    try {
      await axios({
        method: 'delete',
        url: roleEndpoints.role.delete.replace(':id', id.toString()),
        headers: { 'Content-Type': 'application/json' },
      });

      set((state) => ({
        roles: state.roles.filter((role: IRoleItem) => role.id !== id),
        totalElements: state.totalElements - 1,
        loading: false,
      }));
    } catch (error: any) {
      set({ error: error.message || 'Failed to delete role', loading: false });
      throw error;
    }
  },

  getAllRoles: async (params) => {
    set({ loading: true, error: null });
    try {
      if (params) {
        set({ currentFilters: params });
      }
      const response = await axios({
        method: 'get',
        url: roleEndpoints.role.list,
        headers: { 'Content-Type': 'application/json' },
        params,
      });
      console.log('hellooooo', params);

      const transformedData = response.data.content.map((roleItem: any): IRoleItem => {
        const createdAtDate = transformDate(roleItem.createdAt);
        return {
          id: roleItem.id,
          name: roleItem.name,
          description: roleItem.description,
          permissions: roleItem.permissions,
          createdAt: createdAtDate,
        };
      });

      set({
        roles: transformedData,
        totalElements: response.data.totalElements,
        totalPages: response.data.totalPages,
        currentPage: response.data.number,
        pageSize: response.data.size,
        loading: false,
      });
    } catch (error: any) {
      set({ error: error.message || 'Failed to fetch roles', loading: false });
      throw error;
    }
  },
  clearFilters: () => {
    set({ currentFilters: {} });
  },

  setCurrentFilters: (filters: SearchRolesParams) => {
    set({ currentFilters: filters });
  },

  resetState: () => {
    set(initialState);
  },
}));
