import 'package:flutter/material.dart'; // For BuildContext in testWidgets
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart'; // For MultiProvider and ChangeNotifierProvider
import 'package:game_test/providers/battle_provider.dart';
import 'package:game_test/providers/shop_provider.dart'; // Required for BattleProvider's context
import 'package:game_test/game/data/enemy_table.dart';
import 'package:game_test/game/data/item_table.dart';
import 'package:game_test/game/enums.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  setUpAll(() async {
    SharedPreferences.setMockInitialValues({});
    await ItemTable.load();
    await EnemyTable.load();
  });

  // Helper widget to provide the necessary providers in the widget tree
  Widget createTestApp() {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ShopProvider()),
        ChangeNotifierProxyProvider<ShopProvider, BattleProvider>(
          create: (context) => BattleProvider(
            shopProvider: Provider.of<ShopProvider>(context, listen: false),
          ),
          update: (context, shopProvider, battleProvider) =>
              battleProvider ?? BattleProvider(shopProvider: shopProvider),
        ),
      ],
      child: const MaterialApp(
        home: Scaffold(
          body: Text('Test App'),
        ),
      ),
    );
  }

  testWidgets('Enemy generates intent on spawn', (WidgetTester tester) async {
    await tester.pumpWidget(createTestApp());
    await tester.pumpAndSettle(); // Ensure providers are built and available

    // Retrieve the BattleProvider instance from the context of the widget tree
    final battleProvider = Provider.of<BattleProvider>(
      tester.element(find.byType(MaterialApp)),
      listen: false,
    );
    
    battleProvider.initializeBattle();
    await tester.pumpAndSettle(); // Allow async operations in initializeBattle to complete

    // Should have an enemy and an intent
    expect(battleProvider.enemy, isNotNull);
    expect(battleProvider.currentEnemyIntent, isNotNull);
    print('Initial Intent: ${battleProvider.currentEnemyIntent!.description}');
  });

  testWidgets('Enemy executes intent and generates new one', (WidgetTester tester) async {
    await tester.pumpWidget(createTestApp());
    await tester.pumpAndSettle(); // Ensure providers are built and available

    // Retrieve the BattleProvider instance from the context of the widget tree
    final battleProvider = Provider.of<BattleProvider>(
      tester.element(find.byType(MaterialApp)),
      listen: false,
    );
    
    battleProvider.initializeBattle();
    await tester.pumpAndSettle();

    // Let's verify the intent structure
    final intent = battleProvider.currentEnemyIntent!;
    expect(intent.value, greaterThan(0));
    expect(intent.type, anyOf(EnemyActionType.attack, EnemyActionType.defend));
    expect(
      intent.risk,
      anyOf(RiskLevel.safe, RiskLevel.normal, RiskLevel.risky),
    );
  });
}
