import { describe, it, expect, vi, beforeEach } from 'vitest';
import { AdminService } from '@/lib/services/admin/AdminService';
import { AdminApiClient } from '@/lib/api/admin/AdminApiClient';
import { ApiError } from '@/lib/api/base/ApiError';
import type { DashboardStats, UserDto, UserListResponse } from '@/lib/types/admin';

// Mock the API client
vi.mock('@/lib/api/admin/AdminApiClient');

describe('AdminService', () => {
  let service: AdminService;
  let mockApiClient: any;

  beforeEach(() => {
    vi.clearAllMocks();
    service = new AdminService();
    mockApiClient = (service as any).apiClient;
  });

  describe('happy paths', () => {
    it('should successfully fetch dashboard statistics', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [
          { label: 'This week', value: 45, color: '#10b981' },
          { label: 'Last week', value: 38, color: '#3b82f6' },
        ],
        roleDistribution: [
          { label: 'Users', value: 1200, color: '#6b7280' },
          { label: 'Admins', value: 50, color: '#8b5cf6' },
        ],
        statusDistribution: {
          active: 1100,
          suspended: 50,
          deleted: 100,
        },
        activityTimeline: [
          { date: '2024-01-01', newUsers: 10, logins: 200 },
          { date: '2024-01-02', newUsers: 15, logins: 220 },
        ],
      };

      mockApiClient.getDashboardStats.mockResolvedValue(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      expect(result.unwrap()).toEqual(mockStats);
      expect(mockApiClient.getDashboardStats).toHaveBeenCalledTimes(1);
    });

    it('should successfully list users with filtering', async () => {
      const mockUsers: UserDto[] = [
        {
          id: '1',
          email: 'admin@example.com',
          displayName: 'Admin User',
          roles: ['owner', 'admin'],
          status: 'active',
          isSystemAdmin: true,
          createdAt: '2024-01-01T00:00:00.000Z',
          updatedAt: '2024-01-01T00:00:00.000Z',
          lastLoginAt: '2024-01-15T10:00:00.000Z',
          primaryDriverId: 'driver-1',
        },
        {
          id: '2',
          email: 'user@example.com',
          displayName: 'Regular User',
          roles: ['user'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-02T00:00:00.000Z',
          updatedAt: '2024-01-02T00:00:00.000Z',
          lastLoginAt: '2024-01-14T15:00:00.000Z',
        },
      ];

      const mockResponse: UserListResponse = {
        users: mockUsers,
        total: 2,
        page: 1,
        limit: 50,
        totalPages: 1,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      expect(result.unwrap()).toEqual(mockResponse);
      expect(mockApiClient.listUsers).toHaveBeenCalledTimes(1);
    });

    it('should successfully update user status', async () => {
      const userId = 'user-123';
      const newStatus = 'suspended';
      const mockUpdatedUser: UserDto = {
        id: userId,
        email: 'test@example.com',
        displayName: 'Test User',
        roles: ['user'],
        status: newStatus,
        isSystemAdmin: false,
        createdAt: '2024-01-01T00:00:00.000Z',
        updatedAt: '2024-01-01T00:00:00.000Z',
      };

      mockApiClient.updateUserStatus.mockResolvedValue(mockUpdatedUser);

      const result = await service.updateUserStatus(userId, newStatus);

      expect(result.isOk()).toBe(true);
      expect(result.unwrap()).toEqual(mockUpdatedUser);
      expect(mockApiClient.updateUserStatus).toHaveBeenCalledWith(userId, newStatus);
    });

    it('should successfully delete user', async () => {
      mockApiClient.deleteUser.mockResolvedValue(undefined);

      const result = await service.deleteUser();

      expect(result.isOk()).toBe(true);
      expect(result.unwrap()).toBeUndefined();
      expect(mockApiClient.deleteUser).toHaveBeenCalledTimes(1);
    });
  });

  describe('failure modes', () => {
    it('should handle dashboard stats fetch errors', async () => {
      const error = new ApiError(
        'Dashboard stats not found',
        'NOT_FOUND',
        {
          endpoint: '/admin/dashboard/stats',
          method: 'GET',
          timestamp: new Date().toISOString(),
          statusCode: 404,
        }
      );

      mockApiClient.getDashboardStats.mockRejectedValue(error);

      const result = await service.getDashboardStats();

      expect(result.isErr()).toBe(true);
      expect(result.getError()).toEqual({
        type: 'notFound',
        message: 'Dashboard stats not found',
      });
    });

    it('should handle user list fetch errors', async () => {
      const error = new ApiError(
        'Failed to fetch users',
        'SERVER_ERROR',
        {
          endpoint: '/admin/users',
          method: 'GET',
          timestamp: new Date().toISOString(),
          statusCode: 500,
        }
      );

      mockApiClient.listUsers.mockRejectedValue(error);

      const result = await service.listUsers();

      expect(result.isErr()).toBe(true);
      expect(result.getError()).toEqual({
        type: 'serverError',
        message: 'Failed to fetch users',
      });
    });

    it('should handle user status update errors', async () => {
      const error = new ApiError(
        'Invalid user ID',
        'VALIDATION_ERROR',
        {
          endpoint: '/admin/users/user-123/status',
          method: 'PATCH',
          timestamp: new Date().toISOString(),
          statusCode: 400,
        }
      );

      mockApiClient.updateUserStatus.mockRejectedValue(error);

      const result = await service.updateUserStatus('user-123', 'active');

      expect(result.isErr()).toBe(true);
      expect(result.getError()).toEqual({
        type: 'unknown',
        message: 'Invalid user ID',
      });
    });

    it('should handle user deletion errors', async () => {
      const error = new ApiError(
        'User not found',
        'NOT_FOUND',
        {
          endpoint: '/admin/users/user-123',
          method: 'DELETE',
          timestamp: new Date().toISOString(),
          statusCode: 404,
        }
      );

      mockApiClient.deleteUser.mockRejectedValue(error);

      const result = await service.deleteUser();

      expect(result.isErr()).toBe(true);
      expect(result.getError()).toEqual({
        type: 'notFound',
        message: 'User not found',
      });
    });

    it('should handle invalid user ID', async () => {
      const error = new ApiError(
        'Invalid user ID format',
        'VALIDATION_ERROR',
        {
          endpoint: '/admin/users/invalid-id/status',
          method: 'PATCH',
          timestamp: new Date().toISOString(),
          statusCode: 400,
        }
      );

      mockApiClient.updateUserStatus.mockRejectedValue(error);

      const result = await service.updateUserStatus('invalid-id', 'active');

      expect(result.isErr()).toBe(true);
      expect(result.getError()).toEqual({
        type: 'unknown',
        message: 'Invalid user ID format',
      });
    });

    it('should handle invalid status value', async () => {
      const error = new ApiError(
        'Invalid status value',
        'VALIDATION_ERROR',
        {
          endpoint: '/admin/users/user-123/status',
          method: 'PATCH',
          timestamp: new Date().toISOString(),
          statusCode: 400,
        }
      );

      mockApiClient.updateUserStatus.mockRejectedValue(error);

      const result = await service.updateUserStatus('user-123', 'invalid-status');

      expect(result.isErr()).toBe(true);
      expect(result.getError()).toEqual({
        type: 'unknown',
        message: 'Invalid status value',
      });
    });
  });

  describe('retries', () => {
    it('should retry on transient API failures', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [],
        roleDistribution: [],
        statusDistribution: { active: 1100, suspended: 50, deleted: 100 },
        activityTimeline: [],
      };

      const error = new ApiError(
        'Network error',
        'NETWORK_ERROR',
        {
          endpoint: '/admin/dashboard/stats',
          method: 'GET',
          timestamp: new Date().toISOString(),
        }
      );

      // First call fails, second succeeds
      mockApiClient.getDashboardStats
        .mockRejectedValueOnce(error)
        .mockResolvedValueOnce(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      expect(result.unwrap()).toEqual(mockStats);
      expect(mockApiClient.getDashboardStats).toHaveBeenCalledTimes(2);
    });

    it('should retry on timeout when fetching dashboard stats', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [],
        roleDistribution: [],
        statusDistribution: { active: 1100, suspended: 50, deleted: 100 },
        activityTimeline: [],
      };

      const error = new ApiError(
        'Request timed out after 30 seconds',
        'TIMEOUT_ERROR',
        {
          endpoint: '/admin/dashboard/stats',
          method: 'GET',
          timestamp: new Date().toISOString(),
        }
      );

      // First call times out, second succeeds
      mockApiClient.getDashboardStats
        .mockRejectedValueOnce(error)
        .mockResolvedValueOnce(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      expect(result.unwrap()).toEqual(mockStats);
      expect(mockApiClient.getDashboardStats).toHaveBeenCalledTimes(2);
    });
  });

  describe('fallback logic', () => {
    it('should use mock data when API is unavailable', async () => {
      const error = new ApiError(
        'Unable to connect to server',
        'NETWORK_ERROR',
        {
          endpoint: '/admin/dashboard/stats',
          method: 'GET',
          timestamp: new Date().toISOString(),
        }
      );

      mockApiClient.getDashboardStats.mockRejectedValue(error);

      const result = await service.getDashboardStats();

      // The service should return the mock data from the service itself
      expect(result.isOk()).toBe(true);
      const stats = result.unwrap();
      expect(stats.totalUsers).toBe(1250);
      expect(stats.activeUsers).toBe(1100);
    });

    it('should handle partial user data gracefully', async () => {
      const mockUsers: UserDto[] = [
        {
          id: '1',
          email: 'admin@example.com',
          displayName: 'Admin User',
          roles: ['owner', 'admin'],
          status: 'active',
          isSystemAdmin: true,
          createdAt: '2024-01-01T00:00:00.000Z',
          updatedAt: '2024-01-01T00:00:00.000Z',
          lastLoginAt: '2024-01-15T10:00:00.000Z',
          primaryDriverId: 'driver-1',
        },
        {
          id: '2',
          email: 'user@example.com',
          displayName: 'Regular User',
          roles: ['user'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-02T00:00:00.000Z',
          updatedAt: '2024-01-02T00:00:00.000Z',
          // Missing lastLoginAt - partial data
        },
      ];

      const mockResponse: UserListResponse = {
        users: mockUsers,
        total: 2,
        page: 1,
        limit: 50,
        totalPages: 1,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      const response = result.unwrap();
      expect(response.users).toHaveLength(2);
      expect(response.users[0].lastLoginAt).toBeDefined();
      expect(response.users[1].lastLoginAt).toBeUndefined();
    });

    it('should handle empty user list', async () => {
      const mockResponse: UserListResponse = {
        users: [],
        total: 0,
        page: 1,
        limit: 50,
        totalPages: 0,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      const response = result.unwrap();
      expect(response.users).toHaveLength(0);
      expect(response.total).toBe(0);
    });
  });

  describe('aggregation logic', () => {
    it('should aggregate dashboard statistics correctly', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [
          { label: 'This week', value: 45, color: '#10b981' },
          { label: 'Last week', value: 38, color: '#3b82f6' },
        ],
        roleDistribution: [
          { label: 'Users', value: 1200, color: '#6b7280' },
          { label: 'Admins', value: 50, color: '#8b5cf6' },
        ],
        statusDistribution: {
          active: 1100,
          suspended: 50,
          deleted: 100,
        },
        activityTimeline: [
          { date: '2024-01-01', newUsers: 10, logins: 200 },
          { date: '2024-01-02', newUsers: 15, logins: 220 },
        ],
      };

      mockApiClient.getDashboardStats.mockResolvedValue(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      const stats = result.unwrap();

      // Verify aggregation
      expect(stats.totalUsers).toBe(1250);
      expect(stats.activeUsers).toBe(1100);
      expect(stats.suspendedUsers).toBe(50);
      expect(stats.deletedUsers).toBe(100);
      expect(stats.systemAdmins).toBe(5);
      expect(stats.recentLogins).toBe(450);
      expect(stats.newUsersToday).toBe(12);

      // Verify user growth aggregation
      expect(stats.userGrowth).toHaveLength(2);
      expect(stats.userGrowth[0].value).toBe(45);
      expect(stats.userGrowth[1].value).toBe(38);

      // Verify role distribution aggregation
      expect(stats.roleDistribution).toHaveLength(2);
      expect(stats.roleDistribution[0].value).toBe(1200);
      expect(stats.roleDistribution[1].value).toBe(50);

      // Verify status distribution aggregation
      expect(stats.statusDistribution.active).toBe(1100);
      expect(stats.statusDistribution.suspended).toBe(50);
      expect(stats.statusDistribution.deleted).toBe(100);

      // Verify activity timeline aggregation
      expect(stats.activityTimeline).toHaveLength(2);
      expect(stats.activityTimeline[0].newUsers).toBe(10);
      expect(stats.activityTimeline[1].newUsers).toBe(15);
    });

    it('should calculate user growth metrics', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [
          { label: 'This week', value: 45, color: '#10b981' },
          { label: 'Last week', value: 38, color: '#3b82f6' },
        ],
        roleDistribution: [],
        statusDistribution: { active: 1100, suspended: 50, deleted: 100 },
        activityTimeline: [],
      };

      mockApiClient.getDashboardStats.mockResolvedValue(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      const stats = result.unwrap();

      // Calculate growth percentage
      const growth = stats.userGrowth;
      expect(growth).toHaveLength(2);
      expect(growth[0].value).toBe(45);
      expect(growth[1].value).toBe(38);

      // Verify growth trend
      const growthTrend = ((45 - 38) / 38) * 100;
      expect(growthTrend).toBeCloseTo(18.42, 1);
    });

    it('should aggregate role distribution data', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [],
        roleDistribution: [
          { label: 'Users', value: 1200, color: '#6b7280' },
          { label: 'Admins', value: 50, color: '#8b5cf6' },
        ],
        statusDistribution: { active: 1100, suspended: 50, deleted: 100 },
        activityTimeline: [],
      };

      mockApiClient.getDashboardStats.mockResolvedValue(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      const stats = result.unwrap();

      // Verify role distribution
      expect(stats.roleDistribution).toHaveLength(2);
      expect(stats.roleDistribution[0].label).toBe('Users');
      expect(stats.roleDistribution[0].value).toBe(1200);
      expect(stats.roleDistribution[1].label).toBe('Admins');
      expect(stats.roleDistribution[1].value).toBe(50);

      // Verify total matches
      const totalRoles = stats.roleDistribution.reduce((sum, role) => sum + role.value, 0);
      expect(totalRoles).toBe(1250);
    });

    it('should aggregate status distribution data', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [],
        roleDistribution: [],
        statusDistribution: {
          active: 1100,
          suspended: 50,
          deleted: 100,
        },
        activityTimeline: [],
      };

      mockApiClient.getDashboardStats.mockResolvedValue(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      const stats = result.unwrap();

      // Verify status distribution
      expect(stats.statusDistribution.active).toBe(1100);
      expect(stats.statusDistribution.suspended).toBe(50);
      expect(stats.statusDistribution.deleted).toBe(100);

      // Verify total matches
      const totalStatuses = stats.statusDistribution.active + stats.statusDistribution.suspended + stats.statusDistribution.deleted;
      expect(totalStatuses).toBe(1250);
    });

    it('should aggregate activity timeline data', async () => {
      const mockStats: DashboardStats = {
        totalUsers: 1250,
        activeUsers: 1100,
        suspendedUsers: 50,
        deletedUsers: 100,
        systemAdmins: 5,
        recentLogins: 450,
        newUsersToday: 12,
        userGrowth: [],
        roleDistribution: [],
        statusDistribution: { active: 1100, suspended: 50, deleted: 100 },
        activityTimeline: [
          { date: '2024-01-01', newUsers: 10, logins: 200 },
          { date: '2024-01-02', newUsers: 15, logins: 220 },
          { date: '2024-01-03', newUsers: 20, logins: 250 },
        ],
      };

      mockApiClient.getDashboardStats.mockResolvedValue(mockStats);

      const result = await service.getDashboardStats();

      expect(result.isOk()).toBe(true);
      const stats = result.unwrap();

      // Verify activity timeline
      expect(stats.activityTimeline).toHaveLength(3);
      expect(stats.activityTimeline[0].date).toBe('2024-01-01');
      expect(stats.activityTimeline[0].newUsers).toBe(10);
      expect(stats.activityTimeline[0].logins).toBe(200);

      // Calculate total new users
      const totalNewUsers = stats.activityTimeline.reduce((sum, day) => sum + day.newUsers, 0);
      expect(totalNewUsers).toBe(45);

      // Calculate total logins
      const totalLogins = stats.activityTimeline.reduce((sum, day) => sum + day.logins, 0);
      expect(totalLogins).toBe(670);
    });
  });

  describe('decision branches', () => {
    it('should handle different user roles correctly', async () => {
      const mockUsers: UserDto[] = [
        {
          id: '1',
          email: 'owner@example.com',
          displayName: 'Owner',
          roles: ['owner'],
          status: 'active',
          isSystemAdmin: true,
          createdAt: '2024-01-01T00:00:00.000Z',
          updatedAt: '2024-01-01T00:00:00.000Z',
        },
        {
          id: '2',
          email: 'admin@example.com',
          displayName: 'Admin',
          roles: ['admin'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-02T00:00:00.000Z',
          updatedAt: '2024-01-02T00:00:00.000Z',
        },
        {
          id: '3',
          email: 'user@example.com',
          displayName: 'User',
          roles: ['user'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-03T00:00:00.000Z',
          updatedAt: '2024-01-03T00:00:00.000Z',
        },
      ];

      const mockResponse: UserListResponse = {
        users: mockUsers,
        total: 3,
        page: 1,
        limit: 50,
        totalPages: 1,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      const response = result.unwrap();

      // Verify different roles are handled correctly
      expect(response.users[0].roles).toContain('owner');
      expect(response.users[0].isSystemAdmin).toBe(true);
      expect(response.users[1].roles).toContain('admin');
      expect(response.users[1].isSystemAdmin).toBe(false);
      expect(response.users[2].roles).toContain('user');
      expect(response.users[2].isSystemAdmin).toBe(false);
    });

    it('should handle different user statuses', async () => {
      const mockUsers: UserDto[] = [
        {
          id: '1',
          email: 'active@example.com',
          displayName: 'Active User',
          roles: ['user'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-01T00:00:00.000Z',
          updatedAt: '2024-01-01T00:00:00.000Z',
        },
        {
          id: '2',
          email: 'suspended@example.com',
          displayName: 'Suspended User',
          roles: ['user'],
          status: 'suspended',
          isSystemAdmin: false,
          createdAt: '2024-01-02T00:00:00.000Z',
          updatedAt: '2024-01-02T00:00:00.000Z',
        },
        {
          id: '3',
          email: 'deleted@example.com',
          displayName: 'Deleted User',
          roles: ['user'],
          status: 'deleted',
          isSystemAdmin: false,
          createdAt: '2024-01-03T00:00:00.000Z',
          updatedAt: '2024-01-03T00:00:00.000Z',
        },
      ];

      const mockResponse: UserListResponse = {
        users: mockUsers,
        total: 3,
        page: 1,
        limit: 50,
        totalPages: 1,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      const response = result.unwrap();

      // Verify different statuses are handled correctly
      expect(response.users[0].status).toBe('active');
      expect(response.users[1].status).toBe('suspended');
      expect(response.users[2].status).toBe('deleted');
    });

    it('should handle different pagination scenarios', async () => {
      const mockUsers: UserDto[] = [
        {
          id: '1',
          email: 'user1@example.com',
          displayName: 'User 1',
          roles: ['user'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-01T00:00:00.000Z',
          updatedAt: '2024-01-01T00:00:00.000Z',
        },
      ];

      const mockResponse: UserListResponse = {
        users: mockUsers,
        total: 100,
        page: 2,
        limit: 50,
        totalPages: 2,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      const response = result.unwrap();

      // Verify pagination metadata
      expect(response.page).toBe(2);
      expect(response.limit).toBe(50);
      expect(response.totalPages).toBe(2);
      expect(response.total).toBe(100);
    });

    it('should handle different filtering options', async () => {
      const mockUsers: UserDto[] = [
        {
          id: '1',
          email: 'admin@example.com',
          displayName: 'Admin User',
          roles: ['admin'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-01T00:00:00.000Z',
          updatedAt: '2024-01-01T00:00:00.000Z',
        },
      ];

      const mockResponse: UserListResponse = {
        users: mockUsers,
        total: 1,
        page: 1,
        limit: 50,
        totalPages: 1,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      const response = result.unwrap();

      // Verify filtered results
      expect(response.users).toHaveLength(1);
      expect(response.users[0].roles).toContain('admin');
      expect(response.users[0].status).toBe('active');
    });

    it('should handle system admin vs regular admin', async () => {
      const mockUsers: UserDto[] = [
        {
          id: '1',
          email: 'system@example.com',
          displayName: 'System Admin',
          roles: ['owner', 'admin'],
          status: 'active',
          isSystemAdmin: true,
          createdAt: '2024-01-01T00:00:00.000Z',
          updatedAt: '2024-01-01T00:00:00.000Z',
        },
        {
          id: '2',
          email: 'regular@example.com',
          displayName: 'Regular Admin',
          roles: ['admin'],
          status: 'active',
          isSystemAdmin: false,
          createdAt: '2024-01-02T00:00:00.000Z',
          updatedAt: '2024-01-02T00:00:00.000Z',
        },
      ];

      const mockResponse: UserListResponse = {
        users: mockUsers,
        total: 2,
        page: 1,
        limit: 50,
        totalPages: 1,
      };

      mockApiClient.listUsers.mockResolvedValue(mockResponse);

      const result = await service.listUsers();

      expect(result.isOk()).toBe(true);
      const response = result.unwrap();

      // Verify system admin vs regular admin
      expect(response.users[0].isSystemAdmin).toBe(true);
      expect(response.users[0].roles).toContain('owner');
      expect(response.users[1].isSystemAdmin).toBe(false);
      expect(response.users[1].roles).not.toContain('owner');
    });

    it('should handle soft delete vs hard delete', async () => {
      // Test soft delete (status change to 'deleted')
      const mockUpdatedUser: UserDto = {
        id: 'user-123',
        email: 'test@example.com',
        displayName: 'Test User',
        roles: ['user'],
        status: 'deleted',
        isSystemAdmin: false,
        createdAt: '2024-01-01T00:00:00.000Z',
        updatedAt: '2024-01-01T00:00:00.000Z',
      };

      mockApiClient.updateUserStatus.mockResolvedValue(mockUpdatedUser);

      const result = await service.updateUserStatus('user-123', 'deleted');

      expect(result.isOk()).toBe(true);
      const user = result.unwrap();
      expect(user.status).toBe('deleted');
      expect(user.id).toBe('user-123');

      // Test hard delete (actual deletion)
      mockApiClient.deleteUser.mockResolvedValue(undefined);

      const deleteResult = await service.deleteUser();

      expect(deleteResult.isOk()).toBe(true);
      expect(deleteResult.unwrap()).toBeUndefined();
    });
  });
});
