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/battle/stage_ui.dart';
import 'main_menu_screen.dart';

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();
  bool _showLogs = true;

  @override
  void initState() {
    super.initState();
    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) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      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();

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

  void _addFloatingEffect(EffectEvent event) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (!mounted) return;

      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;
      }

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

      // feedbackType이 존재하면 해당 텍스트를 표시하고 기존 이펙트 아이콘은 건너뜜
      if (event.feedbackType != null) {
        String feedbackText;
        Color feedbackColor;
        switch (event.feedbackType) {
          case BattleFeedbackType.miss:
            feedbackText = "MISS";
            feedbackColor = Colors.grey;
            break;
          case BattleFeedbackType.failed:
            feedbackText = "FAILED";
            feedbackColor = Colors.redAccent;
            break;
          default:
            feedbackText = ""; // Should not happen with current enums
            feedbackColor = Colors.white;
        }

        final String id = UniqueKey().toString();
        setState(() {
          _floatingFeedbackTexts.add(
            FeedbackTextData(
              id: 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; // feedbackType이 있으면 아이콘 이펙트는 표시하지 않음
      }

      IconData icon;
      Color color;
      double size;

      if (event.type == ActionType.attack) {
        if (event.risk == RiskLevel.risky) {
          icon = Icons.whatshot;
          color = Colors.redAccent;
          size = 60.0;
        } else if (event.risk == RiskLevel.normal) {
          icon = Icons.flash_on;
          color = Colors.orangeAccent;
          size = 40.0;
        } else {
          icon = Icons.close;
          color = Colors.grey;
          size = 30.0;
        }
      } else {
        icon = Icons.shield;
        if (event.risk == RiskLevel.risky) {
          color = Colors.deepPurpleAccent;
          size = 60.0;
        } else if (event.risk == RiskLevel.normal) {
          color = Colors.blueAccent;
          size = 40.0;
        } else {
          color = Colors.greenAccent;
          size = 30.0;
        }
      }

      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);
                    });
                  }
                },
              ),
            ),
          ),
        );
      });
    });
  }

  void _showRiskLevelSelection(BuildContext context, ActionType actionType) {
    final player = context.read<BattleProvider>().player;
    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 = 0.5;
                infoColor = Colors.green;
                break;
              case RiskLevel.normal:
                efficiency = 1.0;
                infoColor = Colors.blue;
                break;
              case RiskLevel.risky:
                efficiency = 2.0;
                infoColor = Colors.red;
                break;
            }

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

            double baseChance = 0.0;
            switch (risk) {
              case RiskLevel.safe:
                baseChance = 1.0;
                break;
              case RiskLevel.normal:
                baseChance = 0.8;
                break;
              case RiskLevel.risky:
                baseChance = 0.4;
                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) {
    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 Stack(
            key: _stackKey,
            children: [
              // 1. Background (Black)
              Container(color: Colors.black87),

              // 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: Colors.white,
                                fontSize: 18,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        ),
                        Flexible(
                          child: FittedBox(
                            fit: BoxFit.scaleDown,
                            child: Text(
                              "Turn ${battleProvider.turnCount}",
                              style: const TextStyle(
                                color: Colors.white,
                                fontSize: 18,
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),

                  // 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: 0,
                            right: 0,
                            child: CharacterStatusCard(
                              character: battleProvider.enemy,
                              isPlayer: false,
                              isTurn: !battleProvider.isPlayerTurn,
                              key: _enemyKey,
                            ),
                          ),
                          // Player (Bottom Left)
                          Positioned(
                            bottom: 80, // Space for FABs
                            left: 0,
                            child: CharacterStatusCard(
                              character: battleProvider.player,
                              isPlayer: true,
                              isTurn: battleProvider.isPlayerTurn,
                              key: _playerKey,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                ],
              ),

              // 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",
                      Icons.whatshot,
                      Colors.redAccent,
                      ActionType.attack,
                      battleProvider.isPlayerTurn &&
                          !battleProvider.player.isDead &&
                          !battleProvider.enemy.isDead &&
                          !battleProvider.showRewardPopup,
                    ),
                    const SizedBox(height: 16),
                    _buildFloatingActionButton(
                      context,
                      "DEF",
                      Icons.shield,
                      Colors.blueAccent,
                      ActionType.defend,
                      battleProvider.isPlayerTurn &&
                          !battleProvider.player.isDead &&
                          !battleProvider.enemy.isDead &&
                          !battleProvider.showRewardPopup,
                    ),
                  ],
                ),
              ),

              // 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: Colors.white,
                  ),
                ),
              ),

              // Reward Popup
              if (battleProvider.showRewardPopup)
                Container(
                  color: Colors.black54,
                  child: Center(
                    child: SimpleDialog(
                      title: const Text("Victory! Choose a Reward"),
                      children: battleProvider.rewardOptions.map((item) {
                        return SimpleDialogOption(
                          onPressed: () {
                            battleProvider.selectReward(item);
                          },
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Row(
                                children: [
                                  Container(
                                    padding: const EdgeInsets.all(4),
                                    decoration: BoxDecoration(
                                      color: Colors.blueGrey[700],
                                      borderRadius: BorderRadius.circular(4),
                                      border: Border.all(color: Colors.grey),
                                    ),
                                    child: Icon(
                                      ItemUtils.getIcon(item.slot),
                                      color: ItemUtils.getColor(item.slot),
                                      size: 24,
                                    ),
                                  ),
                                  const SizedBox(width: 12),
                                  Text(
                                    item.name,
                                    style: const TextStyle(
                                      fontWeight: FontWeight.bold,
                                      fontSize: 16,
                                    ),
                                  ),
                                ],
                              ),
                              _buildItemStatText(item),
                              Text(
                                item.description,
                                style: const TextStyle(
                                  fontSize: 12,
                                  color: Colors.grey,
                                ),
                              ),
                            ],
                          ),
                        );
                      }).toList(),
                    ),
                  ),
                ),

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

              // Game Over Overlay
              if (battleProvider.player.isDead)
                Container(
                  color: Colors.black87,
                  child: Center(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        const Text(
                          "DEFEAT",
                          style: TextStyle(
                            color: Colors.red,
                            fontSize: 48,
                            fontWeight: FontWeight.bold,
                            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(
                            "Return to Main Menu",
                            style: TextStyle(color: Colors.white, fontSize: 18),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
            ],
          );
        },
      ),
    );
  }

  Widget _buildItemStatText(Item item) {
    List<String> stats = [];
    if (item.atkBonus > 0) stats.add("+${item.atkBonus} ATK");
    if (item.hpBonus > 0) stats.add("+${item.hpBonus} HP");
    if (item.armorBonus > 0) stats.add("+${item.armorBonus} DEF");

    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: 12, color: Colors.blueAccent),
            ),
          ),
        if (effectTexts.isNotEmpty)
          Padding(
            padding: const EdgeInsets.only(bottom: 4.0),
            child: Text(
              effectTexts.join(", "),
              style: const TextStyle(fontSize: 11, color: Colors.orangeAccent),
            ),
          ),
      ],
    );
  }

  Widget _buildFloatingActionButton(
    BuildContext context,
    String label,
    IconData icon,
    Color color,
    ActionType actionType,
    bool isEnabled,
  ) {
    return FloatingActionButton(
      heroTag: label,
      onPressed: isEnabled
          ? () => _showRiskLevelSelection(context, actionType)
          : null,
      backgroundColor: isEnabled ? color : Colors.grey,
      child: Icon(icon),
    );
  }
}
