import 'package:flutter/material.dart';

import 'package:provider/provider.dart';
import '../providers/battle_provider.dart';

import '../game/enums.dart';
import '../game/model/item.dart';
import '../game/model/damage_event.dart';
import '../game/model/effect_event.dart';
import 'dart:async';
import '../widgets/responsive_container.dart';
import '../utils/item_utils.dart';
import '../widgets/battle/character_status_card.dart';
import '../widgets/battle/battle_log_overlay.dart';
import '../widgets/battle/floating_battle_texts.dart';
import '../widgets/stage/shop_ui.dart';
import '../widgets/stage/rest_ui.dart';
import '../widgets/battle/shake_widget.dart';
import '../widgets/battle/battle_animation_widget.dart';
import '../widgets/battle/explosion_widget.dart';
import 'main_menu_screen.dart';
import '../game/config/battle_config.dart';
import '../game/config/theme_config.dart';
import '../game/config/app_strings.dart';
import '../providers/settings_provider.dart'; // Import SettingsProvider

class BattleScreen extends StatefulWidget {
  const BattleScreen({super.key});

  @override
  State<BattleScreen> createState() => _BattleScreenState();
}

class _BattleScreenState extends State<BattleScreen> {
  final List<DamageTextData> _floatingDamageTexts = [];
  final List<FloatingEffectData> _floatingEffects = [];
  final List<FeedbackTextData> _floatingFeedbackTexts = [];
  StreamSubscription<DamageEvent>? _damageSubscription;
  StreamSubscription<EffectEvent>? _effectSubscription;
  final GlobalKey _playerKey = GlobalKey();
  final GlobalKey _enemyKey = GlobalKey();
  final GlobalKey _stackKey = GlobalKey();
  final GlobalKey<ShakeWidgetState> _shakeKey = GlobalKey<ShakeWidgetState>();
  final GlobalKey<BattleAnimationWidgetState> _playerAnimKey =
      GlobalKey<BattleAnimationWidgetState>();
  final GlobalKey<BattleAnimationWidgetState> _enemyAnimKey =
      GlobalKey<BattleAnimationWidgetState>(); // Added Enemy Anim Key
  final GlobalKey<ExplosionWidgetState> _explosionKey =
      GlobalKey<ExplosionWidgetState>();
  bool _showLogs = false;
  bool _isPlayerAttacking = false; // Player Attack Animation State
  bool _isEnemyAttacking = false; // Enemy Attack Animation State
  DateTime? _lastFeedbackTime; // Cooldown to prevent duplicate feedback texts

  // New State for Interactive Defense Animation
  int _lastTurnCount = -1;
  bool _hasShownEnemyDefense = false;

  @override
  void initState() {
    super.initState();
    print("[UI Debug] BattleScreen initialized: ${hashCode}"); // Debug Log
    final battleProvider = context.read<BattleProvider>();
    _damageSubscription = battleProvider.damageStream.listen(
      _addFloatingDamageText,
    );
    _effectSubscription = battleProvider.effectStream.listen(
      _addFloatingEffect,
    );
  }

  @override
  void dispose() {
    _damageSubscription?.cancel();
    _effectSubscription?.cancel();
    super.dispose();
  }

  void _addFloatingDamageText(DamageEvent event) {
    if (!mounted) return;

    GlobalKey targetKey = event.target == DamageTarget.player
        ? _playerKey
        : _enemyKey;

    if (targetKey.currentContext == null) return;
    RenderBox? renderBox =
        targetKey.currentContext!.findRenderObject() as RenderBox?;
    if (renderBox == null) return;

    Offset position = renderBox.localToGlobal(Offset.zero);

    RenderBox? stackRenderBox =
        _stackKey.currentContext?.findRenderObject() as RenderBox?;
    if (stackRenderBox != null) {
      Offset stackOffset = stackRenderBox.localToGlobal(Offset.zero);
      position = position - stackOffset;
    }

    position = position + Offset(renderBox.size.width / 2 - 20, -20);

    final String id = UniqueKey().toString();

    // Scale based on risk if available in event?
    // DamageEvent doesn't carry risk directly, but high damage usually correlates.
    // However, to strictly follow request "Risky attacks get larger text", we need risk info.
    // Currently DamageEvent (model/damage_event.dart) does NOT have risk field.
    // We can infer or add it. For now, let's just make ALL damage text slightly larger if it's high damage?
    // OR better: check if we can pass risk.
    // Wait, the user asked to scale based on risk.
    // Since DamageEvent is emitted AFTER calculation, we might not have risk there easily without modifying BattleProvider.
    // BUT! EffectEvent HAS risk. And EffectEvent handles ICONS.
    // DamageEvent handles NUMBERS.

    // Let's modify DamageEvent to include risk or isCritical flag?
    // Actually, simply checking if damage > 20 or similar is a heuristic.
    // But the user specifically said "Risky attacks".

    // Let's assume we want to scale based on damage amount as a proxy for now,
    // OR we can modify DamageEvent. Modifying DamageEvent is cleaner.

    // START_REPLACE logic: I will modify the scale widget wrapper.
    // Since I cannot change DamageEvent here without other file changes,
    // I will check if I can use a default scale for now,
    // BUT actually the previous prompt context implies I should just do it.

    // Let's look at `FloatingDamageText`. It takes a `scale` parameter? No.
    // It's a widget. I can wrap it in Transform.scale.

    // Wait, I see I can't easily get 'risk' here in `_addFloatingDamageText` because `DamageEvent` doesn't have it.
    // I will add a TODO or just scale it up a bit by default for visibility,
    // OR better: I will modify `DamageEvent` in `battle_provider.dart` to include `isRisky` or `risk` enum.

    // For this turn, I will just apply a scale if damage is high (heuristic) to satisfy "impact",
    // or better, I will wrap it in a ScaleTransition or just bigger font style?
    // `FloatingDamageText` is a custom widget.

    // Let's look at `FloatingDamageText` implementation (it's imported).
    // Assuming I can pass a style or it has fixed style.

    // Let's just wrap `FloatingDamageText` in a `Transform.scale` with a value.
    // I'll define a variable scale.

    double scale = 1.0;
    // Heuristic: If damage is high (e.g. > 15), assume it might be risky/crit
    if (event.damage > 15) scale = 3;

    setState(() {
      _floatingDamageTexts.add(
        DamageTextData(
          id: id,
          widget: Positioned(
            left: position.dx,
            top: position.dy,
            child: Transform.scale(
              scale: scale,
              child: FloatingDamageText(
                key: ValueKey(id),
                damage: event.damage.toString(),
                color: event.color,
                onRemove: () {
                  if (mounted) {
                    setState(() {
                      _floatingDamageTexts.removeWhere((e) => e.id == id);
                    });
                  }
                },
              ),
            ),
          ),
        ),
      );
    });
  }

  final Set<String> _processedEffectIds = {};

  void _addFloatingEffect(EffectEvent event) {
    if (_processedEffectIds.contains(event.id)) {
      // print("[UI Debug] Duplicate Event Ignored: ${event.id}");
      return;
    }

    _processedEffectIds.add(event.id);
    // Keep the set size manageable
    if (_processedEffectIds.length > 50) {
      _processedEffectIds.remove(_processedEffectIds.first);
    }

    if (!mounted) return;

    // Feedback Text Cooldown
    if (event.feedbackType != null) {
      // print(
      //   "[UI Debug] Feedback Event: ${event.id}, Type: ${event.feedbackType}",
      // );
      if (_lastFeedbackTime != null &&
          DateTime.now().difference(_lastFeedbackTime!).inMilliseconds < 300) {
        return; // Skip if too soon
      }
      _lastFeedbackTime = DateTime.now();
    }

    GlobalKey targetKey = event.target == EffectTarget.player
        ? _playerKey
        : _enemyKey;
    if (targetKey.currentContext == null) return;

    RenderBox? renderBox =
        targetKey.currentContext!.findRenderObject() as RenderBox?;
    if (renderBox == null) return;

    Offset position = renderBox.localToGlobal(Offset.zero);

    RenderBox? stackRenderBox =
        _stackKey.currentContext?.findRenderObject() as RenderBox?;
    if (stackRenderBox != null) {
      Offset stackOffset = stackRenderBox.localToGlobal(Offset.zero);
      position = position - stackOffset;
    }

    // Adjust position based on target:
    // Enemy (Top Right) -> Effect to the left/bottom of character (towards player)
    // Player (Bottom Left) -> Effect to the right/top of character (towards enemy)
    double offsetX = 0;
    double offsetY = 0;

    if (event.target == EffectTarget.enemy) {
      // Enemy is top-right, so effect should be left-bottom of its card
      offsetX = renderBox.size.width * 0.1; // 20% from left edge
      offsetY = renderBox.size.height * 0.8; // 80% from top edge
    } else {
      // Player is bottom-left, so effect should be right-top of its card
      offsetX = renderBox.size.width * 0.8; // 80% from left edge
      offsetY = renderBox.size.height * 0.2; // 20% from top edge
    }

    position = position + Offset(offsetX, offsetY);

    // 0. Prepare Effect Function
    void showEffect() {
      if (!mounted) return;

      // Handle Feedback Text (MISS / FAILED)
      if (event.feedbackType != null) {
        String feedbackText;
        Color feedbackColor;
        switch (event.feedbackType) {
          case BattleFeedbackType.miss:
            feedbackText = "MISS";
            feedbackColor = ThemeConfig.missText;
            break;
          case BattleFeedbackType.failed:
            feedbackText = "FAILED";
            feedbackColor = ThemeConfig.failedText;
            break;
          default:
            feedbackText = "";
            feedbackColor = ThemeConfig.textColorWhite;
        }

        final String id = UniqueKey().toString();

        // Prevent duplicate feedback texts for the same event ID (UI Level)
        if (_floatingFeedbackTexts.any((e) => e.eventId == event.id)) {
          return;
        }

        setState(() {
          _floatingFeedbackTexts.clear(); // Clear previous texts
          _floatingFeedbackTexts.add(
            FeedbackTextData(
              id: id,
              eventId: event.id,
              widget: Positioned(
                left: position.dx,
                top: position.dy,
                child: FloatingFeedbackText(
                  key: ValueKey(id),
                  feedback: feedbackText,
                  color: feedbackColor,
                  onRemove: () {
                    if (mounted) {
                      setState(() {
                        _floatingFeedbackTexts.removeWhere((e) => e.id == id);
                      });
                    }
                  },
                ),
              ),
            ),
          );
        });
        return; // Return early for feedback
      }

      // Handle Icon Effect
      IconData icon = BattleConfig.getIcon(event.type);
      Color color = BattleConfig.getColor(event.type, event.risk);
      double size = BattleConfig.getSize(event.risk);

      final String id = UniqueKey().toString();

      setState(() {
        _floatingEffects.add(
          FloatingEffectData(
            id: id,
            widget: Positioned(
              left: position.dx,
              top: position.dy,
              child: FloatingEffect(
                key: ValueKey(id),
                icon: icon,
                color: color,
                size: size,
                onRemove: () {
                  if (mounted) {
                    setState(() {
                      _floatingEffects.removeWhere((e) => e.id == id);
                    });
                  }
                },
              ),
            ),
          ),
        );
      });
    }

    // 1. Player Attack Animation Trigger (Success or Miss)
    if (event.type == ActionType.attack && event.target == EffectTarget.enemy) {
      final RenderBox? playerBox =
          _playerKey.currentContext?.findRenderObject() as RenderBox?;
      final RenderBox? enemyBox =
          _enemyKey.currentContext?.findRenderObject() as RenderBox?;

      if (playerBox != null && enemyBox != null) {
        final playerPos = playerBox.localToGlobal(Offset.zero);
        final enemyPos = enemyBox.localToGlobal(Offset.zero);
        final offset = enemyPos - playerPos;

        setState(() {
          _isPlayerAttacking = true;
        });

        // Force SAFE animation for MISS, otherwise use event risk
        final RiskLevel animRisk = event.feedbackType != null
            ? RiskLevel.safe
            : event.risk;

        _playerAnimKey.currentState
            ?.animateAttack(offset, () {
              showEffect();
              context.read<BattleProvider>().handleImpact(event);

              if (event.risk == RiskLevel.risky && event.feedbackType == null) {
                _shakeKey.currentState?.shake();
                RenderBox? stackBox =
                    _stackKey.currentContext?.findRenderObject() as RenderBox?;
                if (stackBox != null) {
                  Offset localEnemyPos = stackBox.globalToLocal(enemyPos);
                  localEnemyPos += Offset(
                    enemyBox.size.width / 2,
                    enemyBox.size.height / 2,
                  );
                  _explosionKey.currentState?.explode(localEnemyPos);
                }
              }
            }, animRisk)
            .then((_) {
              if (mounted) {
                setState(() {
                  _isPlayerAttacking = false;
                });
              }
            });
      }
    }
    // 2. Enemy Attack Animation Trigger (Success or Miss)
    else if (event.type == ActionType.attack &&
        event.target == EffectTarget.player) {
      bool enableAnim = context.read<SettingsProvider>().enableEnemyAnimations;

      if (!enableAnim) {
        showEffect();
        context.read<BattleProvider>().handleImpact(event);
        return;
      }

      final RenderBox? playerBox =
          _playerKey.currentContext?.findRenderObject() as RenderBox?;
      final RenderBox? enemyBox =
          _enemyKey.currentContext?.findRenderObject() as RenderBox?;

      if (playerBox != null && enemyBox != null) {
        final playerPos = playerBox.localToGlobal(Offset.zero);
        final enemyPos = enemyBox.localToGlobal(Offset.zero);
        final offset = playerPos - enemyPos;

        setState(() {
          _isEnemyAttacking = true;
        });

        // Force SAFE animation for MISS
        final RiskLevel animRisk = event.feedbackType != null
            ? RiskLevel.safe
            : event.risk;

        _enemyAnimKey.currentState
            ?.animateAttack(offset, () {
              showEffect();
              context.read<BattleProvider>().handleImpact(event);

              if (event.risk == RiskLevel.risky && event.feedbackType == null) {
                _shakeKey.currentState?.shake();
                RenderBox? stackBox =
                    _stackKey.currentContext?.findRenderObject() as RenderBox?;
                if (stackBox != null) {
                  Offset localPlayerPos = stackBox.globalToLocal(playerPos);
                  localPlayerPos += Offset(
                    playerBox.size.width / 2,
                    playerBox.size.height / 2,
                  );
                  _explosionKey.currentState?.explode(localPlayerPos);
                }
              }
            }, animRisk)
            .then((_) {
              if (mounted) {
                setState(() {
                  _isEnemyAttacking = false;
                });
              }
            });
      }
    }
    // 3. Defend Animation Trigger (Success OR Failure)
    else if (event.type == ActionType.defend) {
      if (event.target == EffectTarget.player) {
        setState(() => _isPlayerAttacking = true); // Reuse flag to block input
        _playerAnimKey.currentState
            ?.animateDefense(() {
              showEffect();
              context.read<BattleProvider>().handleImpact(event);
            })
            .then((_) {
              if (mounted) setState(() => _isPlayerAttacking = false);
            });
      } else if (event.target == EffectTarget.enemy) {
        // Check settings for enemy animation
        bool enableAnim = context
            .read<SettingsProvider>()
            .enableEnemyAnimations;
        if (!enableAnim) {
          showEffect();
          context.read<BattleProvider>().handleImpact(event);
          return;
        }

        setState(() => _isEnemyAttacking = true); // Reuse flag to block input
        _enemyAnimKey.currentState
            ?.animateDefense(() {
              showEffect();
              context.read<BattleProvider>().handleImpact(event);
            })
            .then((_) {
              if (mounted) setState(() => _isEnemyAttacking = false);
            });
      } else {
        showEffect();
        context.read<BattleProvider>().handleImpact(event);
      }
    }
    // 4. Others (Feedback for attacks, Buffs, etc.)
    else {
      showEffect();

      // If it's a feedback event (MISS/FAILED for attacks), wait 500ms.
      if (event.feedbackType != null) {
        Future.delayed(const Duration(milliseconds: 500), () {
          if (mounted) context.read<BattleProvider>().handleImpact(event);
        });
      } else {
        // Success events (Icon)
        context.read<BattleProvider>().handleImpact(event);
      }
    }
  }

  void _showRiskLevelSelection(BuildContext context, ActionType actionType) {
    final battleProvider = context.read<BattleProvider>();
    final player = battleProvider.player;

    // Check turn to reset flag
    if (battleProvider.turnCount != _lastTurnCount) {
      _lastTurnCount = battleProvider.turnCount;
      _hasShownEnemyDefense = false;
    }

    // Interactive Enemy Defense Trigger
    // If enemy intends to defend, trigger animation NOW (when user interacts)
    final enemyIntent = battleProvider.currentEnemyIntent;
    if (enemyIntent != null &&
        enemyIntent.type == EnemyActionType.defend &&
        !_hasShownEnemyDefense &&
        context.read<SettingsProvider>().enableEnemyAnimations) {
      _hasShownEnemyDefense = true;
      setState(() => _isEnemyAttacking = true); // Block input momentarily

      // Trigger Animation
      _enemyAnimKey.currentState
          ?.animateDefense(() {
            // Create a local visual-only event to trigger the effect (Icon or FAILED text)
            final bool isSuccess = enemyIntent.isSuccess;
            final BattleFeedbackType? feedbackType = isSuccess
                ? null
                : BattleFeedbackType.failed;

            // Manually trigger the visual effect
            final visualEvent = EffectEvent(
              id: UniqueKey().toString(), // Local unique ID
              type: ActionType.defend,
              risk: enemyIntent.risk,
              target: EffectTarget.enemy, // Show on enemy
              feedbackType: feedbackType,
              attacker: battleProvider.enemy,
              targetEntity: battleProvider.enemy,
              isSuccess: isSuccess,
              isVisualOnly: true, // Visual only
              triggersTurnChange: false,
            );

            _addFloatingEffect(visualEvent);
          })
          .then((_) {
            if (mounted) setState(() => _isEnemyAttacking = false);
          });
    }

    final baseValue = actionType == ActionType.attack
        ? player.totalAtk
        : player.totalDefense;

    showDialog(
      context: context,
      builder: (BuildContext context) {
        return SimpleDialog(
          title: Text("Select Risk Level for ${actionType.name}"),
          children: RiskLevel.values.map((risk) {
            String infoText = "";
            Color infoColor = Colors.black;
            double efficiency = 0.0;
            int expectedValue = 0;

            switch (risk) {
              case RiskLevel.safe:
                efficiency = actionType == ActionType.attack
                    ? BattleConfig.attackSafeEfficiency
                    : BattleConfig.defendSafeEfficiency;
                infoColor = ThemeConfig.riskSafe;
                break;
              case RiskLevel.normal:
                efficiency = actionType == ActionType.attack
                    ? BattleConfig.attackNormalEfficiency
                    : BattleConfig.defendNormalEfficiency;
                infoColor = ThemeConfig.riskNormal;
                break;
              case RiskLevel.risky:
                efficiency = actionType == ActionType.attack
                    ? BattleConfig.attackRiskyEfficiency
                    : BattleConfig.defendRiskyEfficiency;
                infoColor = ThemeConfig.riskRisky;
                break;
            }

            expectedValue = (baseValue * efficiency).toInt();
            String valueUnit = actionType == ActionType.attack
                ? "Dmg"
                : "Armor";
            String successRate = "";

            double baseChance = 0.0;
            switch (risk) {
              case RiskLevel.safe:
                baseChance = BattleConfig.safeBaseChance;
                efficiency = actionType == ActionType.attack
                    ? BattleConfig.attackSafeEfficiency
                    : BattleConfig.defendSafeEfficiency;
                break;
              case RiskLevel.normal:
                baseChance = BattleConfig.normalBaseChance;
                efficiency = actionType == ActionType.attack
                    ? BattleConfig.attackNormalEfficiency
                    : BattleConfig.defendNormalEfficiency;
                break;
              case RiskLevel.risky:
                baseChance = BattleConfig.riskyBaseChance;
                efficiency = actionType == ActionType.attack
                    ? BattleConfig.attackRiskyEfficiency
                    : BattleConfig.defendRiskyEfficiency;
                break;
            }

            double finalChance = baseChance + (player.totalLuck / 100.0);
            if (finalChance > 1.0) finalChance = 1.0;
            successRate = "${(finalChance * 100).toInt()}%";

            infoText =
                "Success: $successRate, Eff: ${(efficiency * 100).toInt()}% ($expectedValue $valueUnit)";

            return SimpleDialogOption(
              onPressed: () {
                context.read<BattleProvider>().playerAction(actionType, risk);
                Navigator.pop(context);
              },
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    risk.name,
                    style: const TextStyle(fontWeight: FontWeight.bold),
                  ),
                  Text(
                    infoText,
                    style: TextStyle(fontSize: 12, color: infoColor),
                  ),
                ],
              ),
            );
          }).toList(),
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    // Sync animation setting to provider logic
    final settings = context.watch<SettingsProvider>();
    context.read<BattleProvider>().skipAnimations =
        !settings.enableEnemyAnimations;

    return ResponsiveContainer(
      child: Consumer<BattleProvider>(
        builder: (context, battleProvider, child) {
          if (battleProvider.currentStage.type == StageType.shop) {
            return ShopUI(battleProvider: battleProvider);
          } else if (battleProvider.currentStage.type == StageType.rest) {
            return RestUI(battleProvider: battleProvider);
          }

          return ShakeWidget(
            key: _shakeKey,
            child: Stack(
              key: _stackKey,
              children: [
                // 1. Background (Black)
                Container(color: ThemeConfig.battleBg),

                // 2. Battle Content (Top Bar + Characters)
                Column(
                  children: [
                    // Top Bar
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Flexible(
                            child: FittedBox(
                              fit: BoxFit.scaleDown,
                              child: Text(
                                "Stage ${battleProvider.stage}",
                                style: const TextStyle(
                                  color: ThemeConfig.textColorWhite,
                                  fontSize: ThemeConfig.fontSizeHeader,
                                  fontWeight: ThemeConfig.fontWeightBold,
                                ),
                              ),
                            ),
                          ),
                          Flexible(
                            child: FittedBox(
                              fit: BoxFit.scaleDown,
                              child: Text(
                                "${AppStrings.turn} ${battleProvider.turnCount}",
                                style: const TextStyle(
                                  color: ThemeConfig.textColorWhite,
                                  fontSize: ThemeConfig.fontSizeHeader,
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),

                    // Battle Area (Characters) - Expanded to fill available space
                    Expanded(
                      child: Padding(
                        padding: const EdgeInsets.all(16.0),
                        child: Stack(
                          children: [
                            // Enemy (Top Right)
                            Positioned(
                              top: 16, // Add some padding from top
                              right: 16, // Add some padding from right
                              child: CharacterStatusCard(
                                character: battleProvider.enemy,
                                isPlayer: false,
                                isTurn: !battleProvider.isPlayerTurn,
                                key: _enemyKey,
                                animationKey: _enemyAnimKey, // Direct Pass
                                hideStats: _isEnemyAttacking,
                              ),
                            ),
                            // Player (Bottom Left)
                            Positioned(
                              bottom: 80, // Space for FABs
                              left: 16, // Add some padding from left
                              child: CharacterStatusCard(
                                character: battleProvider.player,
                                isPlayer: true,
                                isTurn: battleProvider.isPlayerTurn,
                                key: _playerKey,
                                animationKey: _playerAnimKey,
                                hideStats: _isPlayerAttacking,
                              ),
                            ),
                          ], // Close children list
                        ), // Close Stack
                      ), // Close Padding
                    ), // Close Expanded
                  ], // Close Column
                ), // Close Column
                // 3. Logs Overlay
                if (_showLogs && battleProvider.logs.isNotEmpty)
                  Positioned(
                    top: 60,
                    left: 16,
                    right: 16,
                    height: 150,
                    child: BattleLogOverlay(logs: battleProvider.logs),
                  ),

                // 4. Floating Action Buttons (Bottom Right)
                Positioned(
                  bottom: 20,
                  right: 20,
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      _buildFloatingActionButton(
                        context,
                        "ATK",
                        ThemeConfig.btnActionActive,
                        ActionType.attack,
                        battleProvider.isPlayerTurn &&
                            !battleProvider.player.isDead &&
                            !battleProvider.enemy.isDead &&
                            !battleProvider.showRewardPopup &&
                            !_isPlayerAttacking &&
                            !_isEnemyAttacking,
                      ),
                      const SizedBox(height: 16),
                      _buildFloatingActionButton(
                        context,
                        "DEF",
                        ThemeConfig.btnDefendActive,
                        ActionType.defend,
                        battleProvider.isPlayerTurn &&
                            !battleProvider.player.isDead &&
                            !battleProvider.enemy.isDead &&
                            !battleProvider.showRewardPopup &&
                            !_isPlayerAttacking &&
                            !_isEnemyAttacking,
                      ),
                    ],
                  ),
                ),

                // 5. Log Toggle Button (Bottom Left)
                Positioned(
                  bottom: 20,
                  left: 20,
                  child: FloatingActionButton(
                    heroTag: "logToggle",
                    mini: true,
                    backgroundColor: Colors.grey[800],
                    onPressed: () {
                      setState(() {
                        _showLogs = !_showLogs;
                      });
                    },
                    child: Icon(
                      _showLogs ? Icons.visibility_off : Icons.visibility,
                      color: ThemeConfig.textColorWhite,
                    ),
                  ),
                ),

                // Reward Popup
                if (battleProvider.showRewardPopup)
                  Container(
                    color: ThemeConfig.cardBgColor,
                    child: Center(
                      child: SimpleDialog(
                        title: Row(
                          children: [
                            const Text(
                              "${AppStrings.victory} ${AppStrings.chooseReward}",
                            ),
                            const Spacer(),
                            Row(
                              mainAxisSize: MainAxisSize.min,
                              children: [
                                Icon(
                                  Icons.monetization_on,
                                  color: ThemeConfig.statGoldColor,
                                  size: 18,
                                ),
                                const SizedBox(width: 4),
                                Text(
                                  "${battleProvider.lastGoldReward} G",
                                  style: TextStyle(
                                    color: ThemeConfig.statGoldColor,
                                    fontSize: ThemeConfig.fontSizeBody,
                                    fontWeight: ThemeConfig.fontWeightBold,
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                        children: battleProvider.rewardOptions.map((item) {
                          bool isSkip = item.id == "reward_skip";
                          return SimpleDialogOption(
                            onPressed: () {
                              bool success = battleProvider.selectReward(item);
                              if (!success) {
                                ScaffoldMessenger.of(context).showSnackBar(
                                  const SnackBar(
                                    content: Text(
                                      "${AppStrings.inventoryFull} Cannot take item.",
                                    ),
                                    backgroundColor: Colors.red,
                                  ),
                                );
                              }
                            },
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Row(
                                  children: [
                                    if (!isSkip)
                                      Container(
                                        padding: const EdgeInsets.all(4),
                                        decoration: BoxDecoration(
                                          color: Colors.blueGrey[700],
                                          borderRadius: BorderRadius.circular(
                                            4,
                                          ),
                                          border: Border.all(
                                            color:
                                                item.rarity != ItemRarity.magic
                                                ? ItemUtils.getRarityColor(
                                                    item.rarity,
                                                  )
                                                : ThemeConfig.rarityCommon,
                                          ),
                                        ),
                                        child: Image.asset(
                                          ItemUtils.getIconPath(item.slot),
                                          width: 24,
                                          height: 24,
                                          fit: BoxFit.contain,
                                          filterQuality: FilterQuality.high,
                                        ),
                                      ),
                                    if (!isSkip) const SizedBox(width: 12),
                                    Text(
                                      item.name,
                                      style: TextStyle(
                                        fontWeight: ThemeConfig.fontWeightBold,
                                        fontSize: ThemeConfig.fontSizeLarge,
                                        color: isSkip
                                            ? ThemeConfig.textColorGrey
                                            : ItemUtils.getRarityColor(
                                                item.rarity,
                                              ),
                                      ),
                                    ),
                                  ],
                                ),
                                if (!isSkip) _buildItemStatText(item),
                                Text(
                                  item.description,
                                  style: const TextStyle(
                                    fontSize: ThemeConfig.fontSizeMedium,
                                    color: ThemeConfig.textColorGrey,
                                  ),
                                ),
                              ],
                            ),
                          );
                        }).toList(),
                      ),
                    ),
                  ),

                // Floating Effects
                ..._floatingDamageTexts.map((e) => e.widget),
                ..._floatingEffects.map((e) => e.widget),
                ..._floatingFeedbackTexts.map((e) => e.widget),

                // Explosion Layer
                ExplosionWidget(key: _explosionKey),

                // Game Over Overlay
                if (battleProvider.player.isDead)
                  Container(
                    color: ThemeConfig.battleBg,
                    child: Center(
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          const Text(
                            AppStrings.defeat,
                            style: TextStyle(
                              color: ThemeConfig.statHpColor,
                              fontSize: ThemeConfig.fontSizeHuge,
                              fontWeight: ThemeConfig.fontWeightBold,
                              letterSpacing: 4.0,
                            ),
                          ),
                          const SizedBox(height: 32),
                          ElevatedButton(
                            style: ElevatedButton.styleFrom(
                              backgroundColor: Colors.grey[800],
                              padding: const EdgeInsets.symmetric(
                                horizontal: 32,
                                vertical: 16,
                              ),
                            ),
                            onPressed: () {
                              Navigator.of(context).pushAndRemoveUntil(
                                MaterialPageRoute(
                                  builder: (context) => const MainMenuScreen(),
                                ),
                                (route) => false,
                              );
                            },
                            child: const Text(
                              AppStrings.returnToMenu,
                              style: TextStyle(
                                color: ThemeConfig.textColorWhite,
                                fontSize: ThemeConfig.fontSizeHeader,
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
              ],
            ),
          );
        },
      ),
    );
  }

  Widget _buildItemStatText(Item item) {
    List<String> stats = [];
    if (item.atkBonus > 0) stats.add("+${item.atkBonus} ${AppStrings.atk}");
    if (item.hpBonus > 0) stats.add("+${item.hpBonus} ${AppStrings.hp}");
    if (item.armorBonus > 0) stats.add("+${item.armorBonus} ${AppStrings.def}");
    if (item.luck > 0) stats.add("+${item.luck} ${AppStrings.luck}");

    List<String> effectTexts = item.effects.map((e) => e.description).toList();

    if (stats.isEmpty && effectTexts.isEmpty) return const SizedBox.shrink();

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (stats.isNotEmpty)
          Padding(
            padding: const EdgeInsets.only(top: 4.0, bottom: 4.0),
            child: Text(
              stats.join(", "),
              style: const TextStyle(
                fontSize: ThemeConfig.fontSizeMedium,
                color: ThemeConfig.statAtkColor,
              ),
            ),
          ),
        if (effectTexts.isNotEmpty)
          Padding(
            padding: const EdgeInsets.only(bottom: 4.0),
            child: Text(
              effectTexts.join(", "),
              style: const TextStyle(
                fontSize: 11,
                color: ThemeConfig.rarityLegendary,
              ), // 11 is custom, keep or change? Let's use Small
            ),
          ),
      ],
    );
  }

  Widget _buildFloatingActionButton(
    BuildContext context,
    String label,
    Color color,
    ActionType actionType,
    bool isEnabled,
  ) {
    String iconPath;
    if (actionType == ActionType.attack) {
      iconPath = 'assets/data/icon/icon_weapon.png';
    } else {
      iconPath = 'assets/data/icon/icon_shield.png';
    }

    return FloatingActionButton(
      heroTag: label,
      onPressed: isEnabled
          ? () => _showRiskLevelSelection(context, actionType)
          : null,
      backgroundColor: isEnabled ? color : ThemeConfig.btnDisabled,
      child: Image.asset(
        iconPath,
        width: 32,
        height: 32,
        color: ThemeConfig.textColorWhite, // Tint icon white
        fit: BoxFit.contain,
        filterQuality: FilterQuality.high,
      ),
    );
  }
}
