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

import 'package:superport_v2/features/approvals/domain/entities/approval.dart';
import 'package:superport_v2/features/approvals/request/presentation/controllers/approval_request_controller.dart';
import 'package:superport_v2/features/approvals/request/presentation/utils/approval_form_initializer.dart';
import 'package:superport_v2/features/approvals/shared/domain/entities/approval_approver_candidate.dart';
import 'package:superport_v2/features/approvals/shared/domain/repositories/approval_approver_repository.dart';
import 'package:superport_v2/features/inventory/transactions/domain/entities/stock_transaction_input.dart';

void main() {
  final getIt = GetIt.I;

  setUp(() {
    if (getIt.isRegistered<ApprovalApproverRepository>()) {
      getIt.unregister<ApprovalApproverRepository>();
    }
  });

  tearDown(() async {
    if (getIt.isRegistered<ApprovalApproverRepository>()) {
      getIt.unregister<ApprovalApproverRepository>();
    }
  });

  group('ApprovalFormInitializer.populate', () {
    test('초안 저장본이 있으면 상신자와 단계를 복구한다', () async {
      final controller = ApprovalRequestController();
      final draft = StockTransactionApprovalInput(
        requestedById: 101,
        steps: [
          ApprovalStepAssignmentItem(stepOrder: 1, approverId: 104),
          ApprovalStepAssignmentItem(stepOrder: 2, approverId: 201),
        ],
      );

      getIt.registerSingleton<ApprovalApproverRepository>(
        _FakeApproverRepository({
          101: _candidate(id: 101, name: '요청자'),
          104: _candidate(id: 104, name: '1단계 승인자'),
          201: _candidate(id: 201, name: '최종 승인자'),
        }),
      );

      await ApprovalFormInitializer.populate(
        controller: controller,
        draft: draft,
      );

      expect(controller.requester?.id, equals(101));
      expect(controller.steps.length, equals(2));
      expect(controller.steps.first.approver.id, equals(104));
      expect(controller.steps.last.approver.id, equals(201));
    });

    test('조회 실패 시 해당 승인자는 복구 대상에서 제외한다', () async {
      final controller = ApprovalRequestController();
      final draft = StockTransactionApprovalInput(
        requestedById: 101,
        steps: [
          ApprovalStepAssignmentItem(stepOrder: 1, approverId: 104),
          ApprovalStepAssignmentItem(stepOrder: 2, approverId: 9999),
        ],
      );

      getIt.registerSingleton<ApprovalApproverRepository>(
        _FakeApproverRepository({
          101: _candidate(id: 101, name: '요청자'),
          104: _candidate(id: 104, name: '1단계 승인자'),
        }),
      );

      await ApprovalFormInitializer.populate(
        controller: controller,
        draft: draft,
      );

      expect(controller.steps.length, equals(1));
      expect(controller.steps.first.approver.id, equals(104));
    });
  });
}

ApprovalApproverCandidate _candidate({required int id, required String name}) {
  return ApprovalApproverCandidate(
    id: id,
    employeeNo: 'EMP$id',
    name: name,
    team: '팀',
  );
}

class _FakeApproverRepository implements ApprovalApproverRepository {
  _FakeApproverRepository(this._candidates);

  final Map<int, ApprovalApproverCandidate> _candidates;

  @override
  Future<ApprovalApproverCandidate?> fetchById(int id) async {
    return _candidates[id];
  }

  @override
  Future<List<ApprovalApproverCandidate>> search({
    required String keyword,
    int limit = 20,
  }) async {
    return _candidates.values.toList(growable: false);
  }

  @override
  Future<List<ApprovalApproverCandidate>> listInitial({int limit = 20}) async {
    return _candidates.values.take(limit).toList(growable: false);
  }
}
