import 'package:asciineverdie/src/core/model/monetization_state.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('MonetizationState', () {
    // =========================================================================
    // initial 팩토리(factory) 테스트
    // =========================================================================

    group('initial', () {
      test('무료 사용자(free user) 기본 상태', () {
        final state = MonetizationState.initial();

        expect(state.undoRemaining, equals(1));
        expect(state.adRemovalPurchased, isFalse);
        expect(state.rollsRemaining, equals(5));
        expect(state.pendingChests, equals(0));
        expect(state.rollHistory, isNull);
      });

      test('유료 사용자(paid user) 기본 상태', () {
        final state = MonetizationState.initial(isPaidUser: true);

        expect(state.undoRemaining, equals(3));
        expect(state.adRemovalPurchased, isTrue);
        expect(state.rollsRemaining, equals(5));
        expect(state.pendingChests, equals(0));
      });
    });

    // =========================================================================
    // isPaidUser / isFreeUser 게터(getter) 테스트
    // =========================================================================

    group('isPaidUser / isFreeUser', () {
      test('광고 제거 구매 시 isPaidUser true', () {
        final state = MonetizationState.initial(isPaidUser: true);

        expect(state.isPaidUser, isTrue);
        expect(state.isFreeUser, isFalse);
      });

      test('광고 제거 미구매 시 isFreeUser true', () {
        final state = MonetizationState.initial();

        expect(state.isPaidUser, isFalse);
        expect(state.isFreeUser, isTrue);
      });
    });

    // =========================================================================
    // isAutoReviveActive 테스트
    // =========================================================================

    group('isAutoReviveActive', () {
      test('autoReviveEndMs가 null이면 false 반환', () {
        final state = MonetizationState.initial();

        expect(state.isAutoReviveActive(1000), isFalse);
      });

      test('elapsedMs가 종료 시점 이내면 true 반환', () {
        final state = MonetizationState.initial().copyWith(
          autoReviveEndMs: 5000,
        );

        expect(state.isAutoReviveActive(3000), isTrue);
      });

      test('elapsedMs가 종료 시점을 초과하면 false 반환', () {
        final state = MonetizationState.initial().copyWith(
          autoReviveEndMs: 5000,
        );

        expect(state.isAutoReviveActive(6000), isFalse);
      });

      test('elapsedMs가 종료 시점과 정확히 같으면 false 반환 (경계값)', () {
        final state = MonetizationState.initial().copyWith(
          autoReviveEndMs: 5000,
        );

        expect(state.isAutoReviveActive(5000), isFalse);
      });
    });

    // =========================================================================
    // isSpeedBoostActive 테스트
    // =========================================================================

    group('isSpeedBoostActive', () {
      test('유료 사용자는 항상 true 반환', () {
        final state = MonetizationState.initial(isPaidUser: true);

        // speedBoostEndMs가 null이어도 유료 사용자는 항상 활성
        expect(state.isSpeedBoostActive(0), isTrue);
        expect(state.isSpeedBoostActive(999999), isTrue);
      });

      test('무료 사용자 - 종료 시점 이내면 true 반환', () {
        final state = MonetizationState.initial().copyWith(
          speedBoostEndMs: 10000,
        );

        expect(state.isSpeedBoostActive(5000), isTrue);
      });

      test('무료 사용자 - 종료 시점 초과 시 false 반환', () {
        final state = MonetizationState.initial().copyWith(
          speedBoostEndMs: 10000,
        );

        expect(state.isSpeedBoostActive(15000), isFalse);
      });

      test('무료 사용자 - speedBoostEndMs가 null이면 false 반환', () {
        final state = MonetizationState.initial();

        expect(state.isSpeedBoostActive(1000), isFalse);
      });
    });

    // =========================================================================
    // isLuckyCharmActive 테스트
    // =========================================================================

    group('isLuckyCharmActive', () {
      test('종료 시점 이내면 true 반환', () {
        final state = MonetizationState.initial().copyWith(
          luckyCharmEndMs: 8000,
        );

        expect(state.isLuckyCharmActive(4000), isTrue);
      });

      test('종료 시점 초과 시 false 반환', () {
        final state = MonetizationState.initial().copyWith(
          luckyCharmEndMs: 8000,
        );

        expect(state.isLuckyCharmActive(9000), isFalse);
      });

      test('luckyCharmEndMs가 null이면 false 반환', () {
        final state = MonetizationState.initial();

        expect(state.isLuckyCharmActive(1000), isFalse);
      });
    });

    // =========================================================================
    // canRoll 테스트
    // =========================================================================

    group('canRoll', () {
      test('rollsRemaining > 0이면 true 반환', () {
        final state = MonetizationState.initial(); // rollsRemaining=5

        expect(state.canRoll, isTrue);
      });

      test('rollsRemaining == 0이면 false 반환', () {
        final state = MonetizationState.initial().copyWith(rollsRemaining: 0);

        expect(state.canRoll, isFalse);
      });
    });

    // =========================================================================
    // maxChests 테스트
    // =========================================================================

    group('maxChests', () {
      test('유료 사용자는 최대 10개', () {
        final state = MonetizationState.initial(isPaidUser: true);

        expect(state.maxChests, equals(10));
      });

      test('무료 사용자는 최대 5개', () {
        final state = MonetizationState.initial();

        expect(state.maxChests, equals(5));
      });
    });

    // =========================================================================
    // isChestsFull 테스트
    // =========================================================================

    group('isChestsFull', () {
      test('무료 사용자 - pendingChests가 maxChests 이상이면 true', () {
        final state = MonetizationState.initial().copyWith(pendingChests: 5);

        expect(state.isChestsFull, isTrue);
      });

      test('무료 사용자 - pendingChests가 maxChests 미만이면 false', () {
        final state = MonetizationState.initial().copyWith(pendingChests: 3);

        expect(state.isChestsFull, isFalse);
      });

      test('유료 사용자 - pendingChests가 maxChests 이상이면 true', () {
        final state = MonetizationState.initial(
          isPaidUser: true,
        ).copyWith(pendingChests: 10);

        expect(state.isChestsFull, isTrue);
      });

      test('유료 사용자 - pendingChests가 maxChests 초과해도 true', () {
        final state = MonetizationState.initial(
          isPaidUser: true,
        ).copyWith(pendingChests: 12);

        expect(state.isChestsFull, isTrue);
      });
    });
  });
}
