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

void main() {
  group('Member 모델 테스트', () {
    test('fromJson 메서드가 JSON 데이터를 올바르게 변환해야 함', () {
      // given
      final json = {
        'id': 'member_id_1',
        'userId': 'user_id_1',
        'clubId': 'club_id_1',
        'name': '홍길동',
        'email': 'hong@example.com',
        'role': '회원',
        'profileImage': 'https://example.com/profile.jpg',
        'phone': '010-1234-5678',
        'address': '서울시 강남구',
        'joinDate': '2022-01-01T09:00:00.000Z',
        'isActive': true,
        'gender': '남성',
        'memberType': '정회원',
        'handicap': 10,
        'status': '활동중',
        'createdAt': '2022-01-01T09:00:00.000Z',
        'updatedAt': '2022-02-01T15:30:00.000Z',
      };

      // when
      final member = Member.fromJson(json);

      // then
      expect(member.id, 'member_id_1');
      expect(member.userId, 'user_id_1');
      expect(member.clubId, 'club_id_1');
      expect(member.name, '홍길동');
      expect(member.email, 'hong@example.com');
      expect(member.role, '회원');
      expect(member.profileImage, 'https://example.com/profile.jpg');
      expect(member.phone, '010-1234-5678');
      expect(member.address, '서울시 강남구');
      expect(member.joinDate, DateTime.parse('2022-01-01T09:00:00.000Z'));
      expect(member.isActive, true);
      expect(member.gender, '남성');
      expect(member.memberType, '정회원');
      expect(member.handicap, 10);
      expect(member.status, '활동중');
      expect(member.createdAt, DateTime.parse('2022-01-01T09:00:00.000Z'));
      expect(member.updatedAt, DateTime.parse('2022-02-01T15:30:00.000Z'));
    });

    test('fromJson 메서드가 일부 필드가 null인 JSON 데이터를 처리해야 함', () {
      // given
      final json = {
        'id': 'member_id_1',
        'userId': 'user_id_1',
        'clubId': 'club_id_1',
        'name': '홍길동',
        'email': 'hong@example.com',
        'isActive': true,
        // 나머지 필드는 null 또는 생략
      };

      // when
      final member = Member.fromJson(json);

      // then
      expect(member.id, 'member_id_1');
      expect(member.userId, 'user_id_1');
      expect(member.clubId, 'club_id_1');
      expect(member.name, '홍길동');
      expect(member.email, 'hong@example.com');
      expect(member.role, null);
      expect(member.profileImage, null);
      expect(member.phone, null);
      expect(member.address, null);
      expect(member.joinDate, null);
      expect(member.isActive, true);
      expect(member.gender, null);
      expect(member.memberType, null);
      expect(member.handicap, null);
      expect(member.status, null);
      expect(member.createdAt, null);
      expect(member.updatedAt, null);
    });

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

      // when
      final member = Member.fromJson(json);

      // then
      expect(member.id, '');
      expect(member.userId, '');
      expect(member.clubId, '');
      expect(member.name, '');
      expect(member.email, '');
      expect(member.isActive, true); // 기본값이 true로 설정되어야 함
    });

    test('handicap이 문자열로 제공될 때 int로 변환되어야 함', () {
      // given
      final json = {
        'id': 'member_id_1',
        'userId': 'user_id_1',
        'clubId': 'club_id_1',
        'name': '홍길동',
        'email': 'hong@example.com',
        'isActive': true,
        'handicap': '15', // 문자열로 제공
      };

      // when
      final member = Member.fromJson(json);

      // then
      expect(member.handicap, 15);
    });

    test('toJson 메서드가 Member 객체를 JSON으로 올바르게 변환해야 함', () {
      // given
      final member = Member(
        id: 'member_id_1',
        userId: 'user_id_1',
        clubId: 'club_id_1',
        name: '홍길동',
        email: 'hong@example.com',
        role: '회원',
        profileImage: 'https://example.com/profile.jpg',
        phone: '010-1234-5678',
        address: '서울시 강남구',
        joinDate: DateTime.parse('2022-01-01T09:00:00.000Z'),
        isActive: true,
        gender: '남성',
        memberType: '정회원',
        handicap: 10,
        status: '활동중',
        createdAt: DateTime.parse('2022-01-01T09:00:00.000Z'),
        updatedAt: DateTime.parse('2022-02-01T15:30:00.000Z'),
      );

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

      // then
      expect(json['id'], 'member_id_1');
      expect(json['userId'], 'user_id_1');
      expect(json['clubId'], 'club_id_1');
      expect(json['name'], '홍길동');
      expect(json['email'], 'hong@example.com');
      expect(json['role'], '회원');
      expect(json['profileImage'], 'https://example.com/profile.jpg');
      expect(json['phone'], '010-1234-5678');
      expect(json['address'], '서울시 강남구');
      expect(json['joinDate'], '2022-01-01T09:00:00.000Z');
      expect(json['isActive'], true);
      expect(json['gender'], '남성');
      expect(json['memberType'], '정회원');
      expect(json['handicap'], 10);
      expect(json['status'], '활동중');
      expect(json['createdAt'], '2022-01-01T09:00:00.000Z');
      expect(json['updatedAt'], '2022-02-01T15:30:00.000Z');
    });

    test('toJson 메서드가 null 필드를 포함하여 JSON으로 변환해야 함', () {
      // given
      final member = Member(
        id: 'member_id_1',
        userId: 'user_id_1',
        clubId: 'club_id_1',
        name: '홍길동',
        email: 'hong@example.com',
        isActive: true,
        // 나머지 필드는 null
      );

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

      // then
      expect(json['id'], 'member_id_1');
      expect(json['userId'], 'user_id_1');
      expect(json['clubId'], 'club_id_1');
      expect(json['name'], '홍길동');
      expect(json['email'], 'hong@example.com');
      expect(json['role'], null);
      expect(json['profileImage'], null);
      expect(json['phone'], null);
      expect(json['address'], null);
      expect(json['joinDate'], null);
      expect(json['isActive'], true);
      expect(json['gender'], null);
      expect(json['memberType'], null);
      expect(json['handicap'], null);
      expect(json['status'], null);
      expect(json['createdAt'], null);
      expect(json['updatedAt'], null);
    });

    test('copyWith 메서드가 특정 필드만 업데이트된 새 객체를 반환해야 함', () {
      // given
      final member = Member(
        id: 'member_id_1',
        userId: 'user_id_1',
        clubId: 'club_id_1',
        name: '홍길동',
        email: 'hong@example.com',
        isActive: true,
      );

      // when
      final updatedMember = member.copyWith(
        name: '김철수',
        email: 'kim@example.com',
        role: '관리자',
      );

      // then
      expect(updatedMember.id, 'member_id_1'); // 변경되지 않음
      expect(updatedMember.userId, 'user_id_1'); // 변경되지 않음
      expect(updatedMember.clubId, 'club_id_1'); // 변경되지 않음
      expect(updatedMember.name, '김철수'); // 변경됨
      expect(updatedMember.email, 'kim@example.com'); // 변경됨
      expect(updatedMember.role, '관리자'); // 변경됨
      expect(updatedMember.isActive, true); // 변경되지 않음
    });
  });
}
