import 'package:block_seasons/game/models/season.dart';
import 'package:flutter_test/flutter_test.dart';

const packJson = {
  'schemaVersion': 1,
  'seasonId': 'season_001',
  'version': 2,
  'title': {'en': 'First Bloom', 'ko': '첫 개화'},
  'theme': {'tileSet': 'spring', 'background': 'background.webp'},
  'stages': [
    {
      'id': 's001_001',
      'seed': 101,
      'moveLimit': 18,
      'preset': [
        {'x': 3, 'y': 3, 't': 'gem'},
      ],
      'objectives': [
        {'type': 'clearGems', 'count': 1},
      ],
      'stars': {
        'two': {'movesLeft': 4},
        'three': {'movesLeft': 8},
      },
      'generatorProfile': 'easy',
    },
  ],
};

void main() {
  group('SeasonPack', () {
    test('parses the pack schema', () {
      final pack = SeasonPack.fromJson(packJson);
      expect(pack.schemaVersion, 1);
      expect(pack.seasonId, 'season_001');
      expect(pack.version, 2);
      expect(pack.theme.tileSet, 'spring');
      expect(pack.stages, hasLength(1));
      expect(pack.stages.first.id, 's001_001');
    });

    test('round-trips to JSON', () {
      final pack = SeasonPack.fromJson(packJson);
      // toJson() always emits all SeasonTheme fields (new fields added in
      // Task 1). Compare everything except theme separately so that adding
      // more theme fields in the future only requires updating theme tests.
      final json = pack.toJson();
      expect(json['schemaVersion'], packJson['schemaVersion']);
      expect(json['seasonId'], packJson['seasonId']);
      expect(json['version'], packJson['version']);
      expect(json['title'], packJson['title']);
      expect(json['stages'], packJson['stages']);
      // Theme: legacy fields preserved, new fields present with defaults.
      final theme = json['theme'] as Map<String, dynamic>;
      expect(theme['tileSet'], 'spring');
      expect(theme['background'], 'background.webp');
      expect(theme['backgroundGradient'], SeasonTheme.defaultGradient);
      expect(theme['accentColor'], 0xFFFF7EB3);
      expect(theme['particleType'], 'petals');
      expect(theme.containsKey('tilePalette'), isFalse);
      expect(theme.containsKey('boardTint'), isFalse);
    });

    test('localized title falls back to English', () {
      final pack = SeasonPack.fromJson(packJson);
      expect(pack.titleFor('ko'), '첫 개화');
      expect(pack.titleFor('en'), 'First Bloom');
      expect(pack.titleFor('ja'), 'First Bloom');
    });

    test('rejects unsupported schema versions', () {
      expect(
        () => SeasonPack.fromJson({...packJson, 'schemaVersion': 99}),
        throwsFormatException,
      );
    });
  });

  group('SeasonTheme visuals', () {
    test('legacy theme json (tileSet/background only) gets defaults', () {
      final theme = SeasonTheme.fromJson({
        'tileSet': 'spring',
        'background': 'background.webp',
      });
      expect(theme.backgroundGradient, SeasonTheme.defaultGradient);
      expect(theme.accentColor, 0xFFFF7EB3);
      expect(theme.particleType, 'petals');
      expect(theme.tilePalette, isNull);
      expect(theme.boardTint, isNull);
    });

    test('full theme json round-trips', () {
      final theme = SeasonTheme(
        tileSet: 'summer',
        background: 'bg.webp',
        backgroundGradient: const [0xFF0A2430, 0xFF10394A, 0xFF1E5A66],
        accentColor: 0xFF6FCDF5,
        particleType: 'snow',
        tilePalette: const [0xFF111111, 0xFF222222],
        boardTint: 0xFF041016,
      );
      final decoded = SeasonTheme.fromJson(theme.toJson());
      expect(decoded.backgroundGradient, theme.backgroundGradient);
      expect(decoded.accentColor, theme.accentColor);
      expect(decoded.particleType, theme.particleType);
      expect(decoded.tilePalette, theme.tilePalette);
      expect(decoded.boardTint, theme.boardTint);
    });

    test('fallback constant matches season 1 defaults', () {
      expect(SeasonTheme.fallback.backgroundGradient,
          const [0xFF0E1430, 0xFF16204A, 0xFF2A2E5E]);
      expect(SeasonTheme.fallback.particleType, 'petals');
    });
  });
}
