import 'package:flutter_test/flutter_test.dart';
import 'package:lanebow/models/event_model.dart';

void main() {
  group('Event 모델 테스트', () {
    test('fromJson 메서드가 JSON 데이터를 올바르게 변환해야 함', () {
      // given
      final json = {
        'id': 'event_id_1',
        'clubId': 'club_id_1',
        'title': '볼링 대회',
        'description': '연례 볼링 대회',
        'startDate': '2023-01-01T10:00:00.000Z',
        'endDate': '2023-01-01T18:00:00.000Z',
        'location': '서울 볼링장',
        'type': '대회',
        'status': '예정됨',
        'maxParticipants': 20,
        'currentParticipants': 10,
        'gameCount': 3,
        'participantFee': 15000,
        'registrationDeadline': '2022-12-25T23:59:59.000Z',
        'publicHash': 'abc123',
        'accessPassword': 'pass123',
        'isActive': true,
        'createdBy': 'admin_id',
        'createdAt': '2022-12-01T09:00:00.000Z',
        'updatedAt': '2022-12-10T15:30:00.000Z',
      };

      // when
      final event = Event.fromJson(json);

      // then
      expect(event.id, 'event_id_1');
      expect(event.clubId, 'club_id_1');
      expect(event.title, '볼링 대회');
      expect(event.description, '연례 볼링 대회');
      expect(event.startDate, DateTime.parse('2023-01-01T10:00:00.000Z'));
      expect(event.endDate, DateTime.parse('2023-01-01T18:00:00.000Z'));
      expect(event.location, '서울 볼링장');
      expect(event.type, '대회');
      expect(event.status, '예정됨');
      expect(event.maxParticipants, 20);
      expect(event.currentParticipants, 10);
      expect(event.gameCount, 3);
      expect(event.participantFee, 15000.0);
      expect(event.registrationDeadline, DateTime.parse('2022-12-25T23:59:59.000Z'));
      expect(event.publicHash, 'abc123');
      expect(event.accessPassword, 'pass123');
      expect(event.isActive, true);
      expect(event.createdBy, 'admin_id');
      expect(event.createdAt, DateTime.parse('2022-12-01T09:00:00.000Z'));
      expect(event.updatedAt, DateTime.parse('2022-12-10T15:30:00.000Z'));
    });

    test('fromJson 메서드가 일부 필드가 null인 JSON 데이터를 처리해야 함', () {
      // given
      final json = {
        'id': 'event_id_1',
        'clubId': 'club_id_1',
        'title': '볼링 대회',
        'startDate': '2023-01-01T10:00:00.000Z',
        'isActive': true,
        // 나머지 필드는 null 또는 생략
      };

      // when
      final event = Event.fromJson(json);

      // then
      expect(event.id, 'event_id_1');
      expect(event.clubId, 'club_id_1');
      expect(event.title, '볼링 대회');
      expect(event.description, null);
      expect(event.startDate, DateTime.parse('2023-01-01T10:00:00.000Z'));
      expect(event.endDate, null);
      expect(event.location, null);
      expect(event.type, null);
      expect(event.status, null);
      expect(event.maxParticipants, null);
      expect(event.currentParticipants, null);
      expect(event.gameCount, null);
      expect(event.participantFee, null);
      expect(event.registrationDeadline, null);
      expect(event.publicHash, null);
      expect(event.accessPassword, null);
      expect(event.isActive, true);
      expect(event.createdBy, null);
      expect(event.createdAt, null);
      expect(event.updatedAt, null);
    });

    test('fromJson 메서드가 필수 필드가 null인 경우 기본값을 설정해야 함', () {
      // given
      final json = {
        // 필수 필드가 null이거나 누락된 경우
        'id': null,
        'clubId': null,
        'title': null,
        'startDate': null,
        'isActive': null,
      };

      // when
      final event = Event.fromJson(json);

      // then
      expect(event.id, '');
      expect(event.clubId, '');
      expect(event.title, '');
      expect(event.startDate.year, DateTime.now().year); // 현재 날짜로 설정되었는지 확인
      expect(event.isActive, true); // 기본값이 true로 설정되어야 함
    });

    test('participantFee가 문자열로 제공될 때 double로 변환되어야 함', () {
      // given
      final json = {
        'id': 'event_id_1',
        'clubId': 'club_id_1',
        'title': '볼링 대회',
        'startDate': '2023-01-01T10:00:00.000Z',
        'participantFee': '15000.50', // 문자열로 제공
        'isActive': true,
      };

      // when
      final event = Event.fromJson(json);

      // then
      expect(event.participantFee, 15000.50);
    });

    test('toJson 메서드가 Event 객체를 JSON으로 올바르게 변환해야 함', () {
      // given
      final event = Event(
        id: 'event_id_1',
        clubId: 'club_id_1',
        title: '볼링 대회',
        description: '연례 볼링 대회',
        startDate: DateTime.parse('2023-01-01T10:00:00.000Z'),
        endDate: DateTime.parse('2023-01-01T18:00:00.000Z'),
        location: '서울 볼링장',
        type: '대회',
        status: '예정됨',
        maxParticipants: 20,
        currentParticipants: 10,
        gameCount: 3,
        participantFee: 15000.0,
        registrationDeadline: DateTime.parse('2022-12-25T23:59:59.000Z'),
        publicHash: 'abc123',
        accessPassword: 'pass123',
        isActive: true,
        createdBy: 'admin_id',
        createdAt: DateTime.parse('2022-12-01T09:00:00.000Z'),
        updatedAt: DateTime.parse('2022-12-10T15:30:00.000Z'),
      );

      // when
      final json = event.toJson();

      // then
      expect(json['id'], 'event_id_1');
      expect(json['clubId'], 'club_id_1');
      expect(json['title'], '볼링 대회');
      expect(json['description'], '연례 볼링 대회');
      expect(json['startDate'], '2023-01-01T10:00:00.000Z');
      expect(json['endDate'], '2023-01-01T18:00:00.000Z');
      expect(json['location'], '서울 볼링장');
      expect(json['type'], '대회');
      expect(json['status'], '예정됨');
      expect(json['maxParticipants'], 20);
      expect(json['currentParticipants'], 10);
      expect(json['gameCount'], 3);
      expect(json['participantFee'], 15000.0);
      expect(json['registrationDeadline'], '2022-12-25T23:59:59.000Z');
      expect(json['publicHash'], 'abc123');
      expect(json['accessPassword'], 'pass123');
      expect(json['isActive'], true);
      expect(json['createdBy'], 'admin_id');
      expect(json['createdAt'], '2022-12-01T09:00:00.000Z');
      expect(json['updatedAt'], '2022-12-10T15:30:00.000Z');
    });

    test('toJson 메서드가 null 필드를 포함하여 JSON으로 변환해야 함', () {
      // given
      final event = Event(
        id: 'event_id_1',
        clubId: 'club_id_1',
        title: '볼링 대회',
        startDate: DateTime.parse('2023-01-01T10:00:00.000Z'),
        isActive: true,
        // 나머지 필드는 null
      );

      // when
      final json = event.toJson();

      // then
      expect(json['id'], 'event_id_1');
      expect(json['clubId'], 'club_id_1');
      expect(json['title'], '볼링 대회');
      expect(json['description'], null);
      expect(json['startDate'], '2023-01-01T10:00:00.000Z');
      expect(json['endDate'], null);
      expect(json['location'], null);
      expect(json['type'], null);
      expect(json['status'], null);
      expect(json['maxParticipants'], null);
      expect(json['currentParticipants'], null);
      expect(json['gameCount'], null);
      expect(json['participantFee'], null);
      expect(json['registrationDeadline'], null);
      expect(json['publicHash'], null);
      expect(json['accessPassword'], null);
      expect(json['isActive'], true);
      expect(json['createdBy'], null);
      expect(json['createdAt'], null);
      expect(json['updatedAt'], null);
    });
  });
}
