import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';

import 'package:superport_v2/core/common/models/paginated_result.dart';
import 'package:superport_v2/core/permissions/permission_manager.dart';
import 'package:superport_v2/core/permissions/permission_resources.dart';
import 'package:superport_v2/features/masters/group_permission/application/permission_synchronizer.dart';
import 'package:superport_v2/features/masters/group_permission/domain/entities/group_permission.dart';
import 'package:superport_v2/features/masters/group_permission/domain/repositories/group_permission_repository.dart';

class _MockGroupPermissionRepository extends Mock
    implements GroupPermissionRepository {}

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('PermissionSynchronizer', () {
    test('그룹 권한을 모두 불러와 PermissionManager에 적용한다', () async {
      final repository = _MockGroupPermissionRepository();
      final manager = PermissionManager();
      final synchronizer = PermissionSynchronizer(
        repository: repository,
        manager: manager,
        pageSize: 1,
      );

      final permissionPage1 = GroupPermission(
        id: 1,
        group: GroupPermissionGroup(id: 1, groupName: '관리자'),
        menu: GroupPermissionMenu(
          id: 10,
          menuCode: 'INBOUND',
          menuName: '입고',
          path: '/inventory/inbound',
        ),
        canCreate: true,
        canRead: true,
        canUpdate: false,
        canDelete: false,
      );

      final permissionPage2 = GroupPermission(
        id: 2,
        group: GroupPermissionGroup(id: 1, groupName: '관리자'),
        menu: GroupPermissionMenu(
          id: 11,
          menuCode: 'OUTBOUND',
          menuName: '출고',
          path: '/inventory/outbound',
        ),
        canCreate: false,
        canRead: true,
        canUpdate: true,
        canDelete: false,
      );

      when(
        () => repository.list(
          page: any(named: 'page'),
          pageSize: any(named: 'pageSize'),
          groupId: any(named: 'groupId'),
          menuId: any(named: 'menuId'),
          isActive: any(named: 'isActive'),
          includeDeleted: any(named: 'includeDeleted'),
        ),
      ).thenAnswer((invocation) async {
        final page = invocation.namedArguments[#page] as int;
        if (page == 1) {
          return PaginatedResult<GroupPermission>(
            items: [permissionPage1],
            page: 1,
            pageSize: 1,
            total: 2,
          );
        }
        return PaginatedResult<GroupPermission>(
          items: [permissionPage2],
          page: 2,
          pageSize: 1,
          total: 2,
        );
      });

      await synchronizer.syncForGroup(1);

      verify(
        () => repository.list(
          page: any(named: 'page'),
          pageSize: 1,
          groupId: 1,
          menuId: null,
          isActive: true,
          includeDeleted: false,
        ),
      ).called(greaterThanOrEqualTo(1));

      expect(
        manager.can(
          PermissionResources.stockTransactions,
          PermissionAction.create,
        ),
        isTrue,
      );
      expect(
        manager.can(
          PermissionResources.stockTransactions,
          PermissionAction.edit,
        ),
        isTrue,
      );
      expect(
        manager.can(
          PermissionResources.stockTransactions,
          PermissionAction.delete,
        ),
        isFalse,
      );
    });

    test('fetchPermissionMap은 그룹 권한 맵을 반환한다', () async {
      final repository = _MockGroupPermissionRepository();
      final manager = PermissionManager();
      final synchronizer = PermissionSynchronizer(
        repository: repository,
        manager: manager,
        pageSize: 1,
      );

      when(
        () => repository.list(
          page: any(named: 'page'),
          pageSize: any(named: 'pageSize'),
          groupId: any(named: 'groupId'),
          menuId: any(named: 'menuId'),
          isActive: any(named: 'isActive'),
          includeDeleted: any(named: 'includeDeleted'),
        ),
      ).thenAnswer((_) async {
        return PaginatedResult<GroupPermission>(
          items: [
            GroupPermission(
              id: 1,
              group: GroupPermissionGroup(id: 99, groupName: 'Ops'),
              menu: GroupPermissionMenu(
                id: 33,
                menuCode: 'INVENTORY',
                menuName: '재고',
                path: '/inventory/summary',
              ),
              canRead: true,
              canCreate: false,
              canUpdate: false,
              canDelete: false,
            ),
          ],
          page: 1,
          pageSize: 1,
          total: 1,
        );
      });

      final map = await synchronizer.fetchPermissionMap(10);

      expect(
        map[PermissionResources.inventorySummary],
        contains(PermissionAction.view),
      );
    });
  });
}
