import 'package:flutter_test/flutter_test.dart';

import 'package:superport_v2/features/approvals/data/dtos/approval_audit_dto.dart';
import 'package:superport_v2/features/approvals/data/dtos/approval_dto.dart';
import 'package:superport_v2/features/approvals/data/dtos/approval_request_dto.dart';

void main() {
  group('ApprovalAuditListDto', () {
    test('fromJson은 감사 로그 목록과 페이지 정보를 생성한다', () {
      final dto = ApprovalAuditListDto.fromJson({
        'items': [
          {
            'id': 1,
            'action': {'id': 10, 'name': '상신'},
            'to_status': {'id': 3, 'name': '진행중'},
            'actor': {'id': 20, 'employee_no': 'EMP20', 'name': '홍길동'},
            'action_at': '2025-01-01T09:00:00Z',
            'note': '테스트',
          },
        ],
        'page': 2,
        'page_size': 50,
        'total': 80,
      });

      expect(dto.page, 2);
      expect(dto.pageSize, 50);
      expect(dto.total, 80);
      expect(dto.items, hasLength(1));
      final item = dto.items.first;
      expect(item.id, 1);
      expect(item.action.id, 10);
      expect(item.toStatus.name, '진행중');
      expect(item.actor.employeeNo, 'EMP20');
      expect(item.actionAt.toUtc(), DateTime.utc(2025, 1, 1, 9));
      expect(item.note, '테스트');
    });

    test('ApprovalAuditDto.fromJson은 액션 이름 누락 시 예외를 발생시킨다', () {
      expect(
        () => ApprovalAuditDto.fromJson({
          'id': 9,
          'action': {'id': 33},
          'to_status': {'id': 2, 'name': '진행'},
          'actor': {'id': 5, 'employee_no': 'EMP5', 'name': '최사용'},
          'action_at': '2025-01-01T09:00:00Z',
        }),
        throwsFormatException,
      );
    });
  });

  group('ApprovalDto', () {
    test('fromJson은 중첩 구조에서도 필드를 추출한다', () {
      final dto = ApprovalDto.fromJson(_approvalJson());
      final entity = dto.toEntity();

      expect(entity.id, 5001);
      expect(entity.approvalNo, 'APP-2025-0001');
      expect(entity.transactionId, 77);
      expect(entity.transactionNo, 'TRX-77');
      expect(entity.transactionUpdatedAt, DateTime.utc(2025, 1, 1, 9, 30));
      expect(entity.status.name, '진행중');
      expect(entity.requester.employeeNo, 'EMP-700');
      expect(entity.currentStep?.approver.name, '김승인');
      expect(entity.steps, hasLength(1));
      expect(entity.histories, hasLength(1));
      expect(entity.histories.first.action.name, '상신');
      expect(entity.createdAt, DateTime.utc(2025, 1, 1, 8));
      expect(entity.updatedAt, DateTime.utc(2025, 1, 1, 9));
    });

    test('parsePaginated는 페이징 결과를 반환한다', () {
      final result = ApprovalDto.parsePaginated({
        'items': [_approvalJson()],
        'page': 3,
        'page_size': 25,
        'total': 40,
      });

      expect(result.page, 3);
      expect(result.pageSize, 25);
      expect(result.total, 40);
      expect(result.items, hasLength(1));
      expect(result.items.first.approvalNo, 'APP-2025-0001');
    });

    test('fromJson은 요청자 요약 누락 시 기본 ID를 보존한다', () {
      final dto = ApprovalDto.fromJson({
        'id': 6001,
        'approval_no': 'APP-2025-06001',
        'status': {'id': 1, 'name': '대기'},
        'requested_at': '2025-01-01T00:00:00Z',
        'requester_id': 77,
        'requested_by_id': 77,
        'requester': const <String, dynamic>{},
      });

      expect(dto.requester.id, 77);
      expect(dto.requester.employeeNo, '-');
      expect(dto.requester.name, '-');
    });
  });
}

Map<String, dynamic> _approvalJson() {
  return {
    'id': 5001,
    'approval': {
      'approval_no': 'APP-2025-0001',
      'requested_at': '2025-01-01T08:00:00Z',
      'status': {'id': 30, 'name': '진행중'},
      'requester': {'id': 700, 'employee_no': 'EMP-700', 'name': '상신자'},
      'transaction': {
        'id': 77,
        'transaction_no': 'TRX-77',
        'updated_at': '2025-01-01T09:30:00Z',
      },
      'steps': [
        {
          'id': 800,
          'step_order': 1,
          'approver': {'id': 910, 'employee_no': 'EMP-910', 'name': '김승인'},
          'status': {'id': 30, 'name': '진행중'},
          'assigned_at': '2025-01-01T08:00:00Z',
        },
      ],
      'histories': [
        {
          'id': 1,
          'action': {'id': 10, 'name': '상신'},
          'to_status': {'id': 30, 'name': '진행중'},
          'actor': {'id': 700, 'employee_no': 'EMP-700', 'name': '상신자'},
          'action_at': '2025-01-01T08:05:00Z',
        },
      ],
      'created_at': '2025-01-01T08:00:00Z',
      'updated_at': '2025-01-01T09:00:00Z',
    },
    'current_step': {
      'id': 800,
      'step_order': 1,
      'approver': {'id': 910, 'employee_no': 'EMP-910', 'name': '김승인'},
      'status': {'id': 30, 'name': '진행중'},
      'assigned_at': '2025-01-01T08:00:00Z',
    },
  };
}
