import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:slrpg_app/l10n/app_localizations.dart';
import 'package:slrpg_app/src/core/utils/error_handler.dart';
import 'package:slrpg_app/src/features/multiplayer/data/repositories/party_repository.dart';

import '../../../../core/constants/app_constants.dart';
import '../../../../core/debug/debug_config_screen.dart';
import '../../../../core/theme/app_theme.dart';
import '../../../../shared/data/local/app_database.dart';
import '../../../../shared/data/repositories/user_repository.dart';
import '../../../../shared/data/repositories/cycle_repository.dart';
import '../../../../shared/data/repositories/workout_repository.dart';
import '../../../../shared/data/remote/sync_service.dart';
import '../../../../shared/domain/logic/xp_calculator.dart';
import '../../../../shared/domain/logic/wendler_calculator.dart';
import '../../../gamification/domain/entities/avatar_config.dart';
import '../../../gamification/domain/entities/item_catalog.dart';
import '../../../gamification/presentation/widgets/avatar_renderer.dart';
import '../../../gamification/presentation/widgets/quest_board.dart';
import '../widgets/xp_bar_widget.dart';
import '../widgets/level_display.dart';
import '../widgets/start_raid_button.dart';
import '../../../gamification/application/quest_service.dart';
import '../../../workout_runner/application/workout_generator_service.dart';
import '../../../../core/utils/connectivity_helper.dart';

class HubScreen extends ConsumerStatefulWidget {
  const HubScreen({super.key});

  @override
  ConsumerState<HubScreen> createState() => _HubScreenState();
}

class _HubScreenState extends ConsumerState<HubScreen> {
  bool _isSyncing = false;

  Future<void> _runSync() async {
    setState(() => _isSyncing = true);
    await ref.read(syncServiceProvider).sync();
    if (mounted) setState(() => _isSyncing = false);
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await _runSync();
      await ref.read(questServiceProvider).checkAndGenerateQuests();
    });
  }

  Future<void> _handleMultiplayerPress() async {
    final hasInternet = await ConnectivityHelper.hasConnection();

    if (!hasInternet) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(
                AppLocalizations.of(context)!.connectivityMultiplayerError),
            backgroundColor: AppTheme.errorColor,
            behavior: SnackBarBehavior.floating,
          ),
        );
      }
      return;
    }

    if (mounted) _showMultiplayerDialog();
  }

  Future<void> _startNextWorkout(
      CycleCollection cycle, UserCollection user) async {
    try {
      final workoutRepo = ref.read(workoutRepositoryProvider);
      final workoutGenerator = ref.read(workoutGeneratorServiceProvider);

      final tmsDynamic = cycle.trainingMaxes;
      final trainingMaxes = Map<String, double>.from(tmsDynamic
          .map((key, value) => MapEntry(key, (value as num).toDouble())));

      int targetWeek = 1;
      int targetDay = 1;
      bool found = false;

      final cycleRefId = cycle.serverId ?? cycle.id.toString();
      final localCycleId = cycle.id.toString();

      for (int w = 1; w <= 4; w++) {
        for (int d = 1; d <= 3; d++) {
          final exists = await workoutRepo.getWorkoutByWeekDay(
              cycleId: cycleRefId, localCycleId: localCycleId, week: w, day: d);

          if (exists == null || exists.completedAt == null) {
            targetWeek = w;
            targetDay = d;
            found = true;
            break;
          }
        }
        if (found) break;
      }

      if (!found) {
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
                content: Text(AppLocalizations.of(context)!.hubCycleComplete)),
          );
        }
        return;
      }
      var workout = await workoutRepo.getWorkoutByWeekDay(
        cycleId: cycleRefId,
        localCycleId: localCycleId,
        week: targetWeek,
        day: targetDay,
      );

      if (workout == null) {
        final activeTemplate = _getTemplateFromUser(user);
        int? conditioningSets;

        if (activeTemplate == AccessoryTemplate.conditioning) {
          conditioningSets = await _showConditioningDialog();
          if (conditioningSets == null) return;
        }

        final exercises = workoutGenerator.generateWorkout(
          week: targetWeek,
          day: targetDay,
          trainingMaxes: trainingMaxes,
          user: user,
          template: activeTemplate,
          conditioningSets: conditioningSets,
        );

        final userId = user.serverId ?? user.id.toString();

        workout = await workoutRepo.createWorkout(
          userId: userId,
          cycleId: cycleRefId,
          week: targetWeek,
          day: targetDay,
          exercises: exercises.map((e) => e.toJson()).toList(),
        );
      }

      if (mounted) {
        context.go('/battle', extra: {
          'week': targetWeek,
          'day': targetDay,
          'workoutId': workout.id,
        });
      }
    } catch (e) {
      log('Failed to start workout: $e');
      if (mounted) {
        if (mounted) ErrorHandler.showErrorSnackBar(context, e);
      }
    }
  }

  AccessoryTemplate _getTemplateFromUser(UserCollection user) {
    final settings = user.inventorySettings ?? {};
    final key = settings['accessory_template'] as String?;
    if (key == 'hypertrophy') return AccessoryTemplate.hypertrophy;
    if (key == 'conditioning') return AccessoryTemplate.conditioning;
    return AccessoryTemplate.none;
  }

  Future<int?> _showConditioningDialog() async {
    int sets = 20;
    final l10n = AppLocalizations.of(context)!;

    return await showDialog<int>(
      context: context,
      barrierDismissible: false,
      builder: (context) {
        return StatefulBuilder(
          builder: (context, setDialogState) {
            final interval = (20 * 60) / sets;

            return AlertDialog(
              title: Text(
                l10n.missionBriefingTitle,
                style: TextStyle(
                  color: AppTheme.textSecondary,
                  fontWeight: FontWeight.bold,
                ),
              ),
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    l10n.missionBriefingBody,
                    textAlign: TextAlign.center,
                  ),
                  const SizedBox(height: 24),
                  Text(
                    l10n.missionBriefingDensity(sets),
                    style: Theme.of(context).textTheme.titleLarge?.copyWith(
                        color: AppTheme.primaryColor,
                        fontWeight: FontWeight.bold),
                  ),
                  Text(
                    l10n.missionBriefingInterval(interval.toStringAsFixed(0)),
                    style: const TextStyle(color: Colors.grey),
                  ),
                  const SizedBox(height: 16),
                  Slider(
                    value: sets.toDouble(),
                    min: 10,
                    max: 30,
                    divisions: 20,
                    activeColor: AppTheme.primaryColor,
                    onChanged: (val) {
                      setDialogState(() => sets = val.toInt());
                    },
                  ),
                  const SizedBox(height: 8),
                  if (sets >= 20)
                    Text(l10n.missionBriefingHardcore,
                        style: const TextStyle(
                            color: AppTheme.errorColor,
                            fontSize: 10,
                            fontWeight: FontWeight.bold)),
                ],
              ),
              actions: [
                TextButton(
                  onPressed: () => Navigator.pop(context, null),
                  child: Text(l10n.abortButton),
                ),
                ElevatedButton(
                  onPressed: () => Navigator.pop(context, sets),
                  child: Text(l10n.engageButton),
                ),
              ],
            );
          },
        );
      },
    );
  }

  void _showMultiplayerDialog() {
    final l10n = AppLocalizations.of(context)!;

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(l10n.multiplayerTitle),
        content: Text(l10n.multiplayerDescription),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context);
              _showJoinCodeDialog();
            },
            child: Text(l10n.multiplayerJoinButton),
          ),
          ElevatedButton(
            style: ElevatedButton.styleFrom(
                backgroundColor: AppTheme.primaryColor),
            onPressed: () async {
              Navigator.pop(context);
              try {
                final party =
                    await ref.read(partyRepositoryProvider).createParty();
                if (mounted) context.go('/lobby/${party.id}');
              } catch (e) {
                if (mounted) {
                  if (mounted) ErrorHandler.showErrorSnackBar(context, e);
                }
              }
            },
            child: Text(l10n.multiplayerCreateButton,
                style: TextStyle(
                    color: Colors.black, fontWeight: FontWeight.bold)),
          ),
        ],
      ),
    );
  }

  void _showJoinCodeDialog() {
    final l10n = AppLocalizations.of(context)!;
    final controller = TextEditingController();
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: Text(l10n.multiplayerEnterCodeTitle),
        content: TextField(
          controller: controller,
          textCapitalization: TextCapitalization.characters,
          decoration: InputDecoration(
            hintText: l10n.multiplayerCodeHint,
            border: OutlineInputBorder(),
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text(l10n.multiplayerCancelAction),
          ),
          ElevatedButton(
            onPressed: () async {
              final code = controller.text.trim().toUpperCase();
              if (code.isNotEmpty) {
                Navigator.pop(context);
                try {
                  final party =
                      await ref.read(partyRepositoryProvider).joinParty(code);
                  if (mounted) context.go('/lobby/${party.id}');
                } catch (e) {
                  if (mounted) {
                    if (mounted) ErrorHandler.showErrorSnackBar(context, e);
                  }
                }
              }
            },
            child: Text(l10n.multiplayerJoinAction),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final userRepo = ref.watch(userRepositoryProvider);
    final cycleRepo = ref.watch(cycleRepositoryProvider);
    final l10n = AppLocalizations.of(context)!;

    return Scaffold(
      body: SafeArea(
        child: FutureBuilder(
          future: Future.wait([
            userRepo.getLocalUser(),
            cycleRepo.getCurrentCycle(),
          ]),
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return const Center(child: CircularProgressIndicator());
            }

            final user = snapshot.data![0] as UserCollection?;
            final cycle = snapshot.data![1] as CycleCollection?;

            final avatarConfig = user?.avatarConfig != null
                ? AvatarConfig.fromJson(user!.avatarConfig!)
                : const AvatarConfig();
            final bgItem =
                ItemCatalog.getBackground(avatarConfig.selectedBackground);

            if (user == null) {
              WidgetsBinding.instance.addPostFrameCallback((_) {
                context.go('/login');
              });
              return const SizedBox();
            }

            final xpProgress = XPCalculator.xpProgressPercentage(
              user.xp,
              user.level,
            );
            final nextLevelXP = XPCalculator.xpForNextLevel(user.level);

            return Stack(
              children: [
                Positioned.fill(
                  child: Image.asset(
                    bgItem.assetPath,
                    fit: BoxFit.cover,
                    key: ValueKey(bgItem.assetPath),
                  ),
                ),
                Positioned.fill(
                  child: Container(
                    decoration: BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.topCenter,
                        end: Alignment.bottomCenter,
                        colors: [
                          Colors.black.withValues(alpha: 0.6),
                          Colors.black.withValues(alpha: 0.85),
                        ],
                      ),
                    ),
                  ),
                ),
                Column(
                  children: [
                    Padding(
                      padding: const EdgeInsets.all(16),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          if (AppConstants.isDevelopment)
                            IconButton(
                              icon: const Icon(Icons.settings),
                              onPressed: () => Navigator.push(
                                context,
                                MaterialPageRoute(
                                  builder: (context) =>
                                      const DebugConfigScreen(),
                                ),
                              ),
                            ),
                          IconButton(
                            icon: const Icon(Icons.person_outline),
                            onPressed: () => context.go('/profile'),
                          ),
                          IconButton(
                            icon: _isSyncing
                                ? const SizedBox(
                                    width: 24,
                                    height: 24,
                                    child: CircularProgressIndicator(
                                        strokeWidth: 2, color: Colors.white))
                                : Icon(
                                    user.isDirty
                                        ? Icons.cloud_upload_outlined
                                        : Icons.cloud_done_outlined,
                                    color: user.isDirty
                                        ? AppTheme.secondaryColor
                                        : AppTheme.successColor,
                                  ),
                            onPressed: _runSync,
                          ),
                          IconButton(
                            icon: const Icon(Icons.leaderboard,
                                color: AppTheme.secondaryColor),
                            onPressed: () => context.go('/leaderboard'),
                          ),
                          IconButton(
                            icon: const Icon(Icons.groups,
                                color: AppTheme.secondaryColor),
                            tooltip: 'Multiplayer Lobby',
                            onPressed: _handleMultiplayerPress,
                          ),
                        ],
                      ),
                    ),
                    const Spacer(flex: 1),
                    AvatarRenderer(
                      config: avatarConfig,
                      size: 160,
                    ),
                    const SizedBox(height: 24),
                    LevelDisplay(level: user.level),
                    const SizedBox(height: 16),
                    Padding(
                      padding: const EdgeInsets.symmetric(horizontal: 32),
                      child: XPBarWidget(
                        currentXP: user.xp,
                        level: user.level,
                        progress: xpProgress,
                        nextLevelXP: nextLevelXP,
                      ),
                    ),
                    const SizedBox(height: 16),
                    // const QuestBoardWidget(),
                    const Spacer(flex: 2),
                    if (cycle != null)
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 32),
                        child: StartRaidButton(
                          onPressed: () => _startNextWorkout(cycle, user),
                        ),
                      )
                    else
                      Padding(
                        padding: const EdgeInsets.all(32),
                        child: Column(
                          children: [
                            Text(
                              l10n.hubNoActiveCycle,
                              style: Theme.of(context).textTheme.bodyLarge,
                            ),
                            const SizedBox(height: 16),
                            ElevatedButton(
                              onPressed: () {
                                context.push('/onboarding/strength-test');
                              },
                              child: Text(l10n.hubCreateCycle),
                            ),
                          ],
                        ),
                      ),
                    const SizedBox(height: 24),
                    const Spacer(flex: 1),
                    Container(
                      padding: const EdgeInsets.symmetric(
                          horizontal: 24, vertical: 16),
                      decoration: BoxDecoration(
                        color: AppTheme.surfaceColor,
                        borderRadius: const BorderRadius.vertical(
                            top: Radius.circular(24)),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withValues(alpha: 0.2),
                            blurRadius: 10,
                            offset: const Offset(0, -5),
                          ),
                        ],
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          _NavButton(
                            icon: Icons.history,
                            label: l10n.navHistory,
                            onTap: () => context.go('/history'),
                          ),
                          _NavButton(
                            icon: Icons.inventory_2_outlined,
                            label: l10n.navInventory,
                            onTap: () => context.go('/inventory'),
                          ),
                          _NavButton(
                            icon: Icons.bar_chart,
                            label: l10n.navStats,
                            onTap: () {
                              context.go('/stats');
                            },
                          ),
                          _NavButton(
                            icon: Icons.auto_stories,
                            label: l10n.navCodex,
                            onTap: () => context.go('/codex'),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}

class _StatBox extends StatelessWidget {
  final String label;
  final String value;

  const _StatBox({
    required this.label,
    required this.value,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
      decoration: BoxDecoration(
        color: AppTheme.surfaceColor,
        borderRadius: BorderRadius.circular(12),
        border: Border.all(
          color: AppTheme.primaryColor.withValues(alpha: 0.3),
        ),
      ),
      child: Column(
        children: [
          Text(
            label,
            style: Theme.of(context).textTheme.bodySmall,
          ),
          const SizedBox(height: 4),
          Text(
            value,
            style: Theme.of(context).textTheme.titleLarge?.copyWith(
                  color: AppTheme.primaryColor,
                  fontWeight: FontWeight.bold,
                ),
          ),
        ],
      ),
    );
  }
}

class _NavButton extends StatelessWidget {
  final IconData icon;
  final String label;
  final VoidCallback onTap;

  const _NavButton({
    required this.icon,
    required this.label,
    required this.onTap,
  });

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onTap,
      borderRadius: BorderRadius.circular(12),
      child: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(icon, color: AppTheme.primaryColor),
            const SizedBox(height: 4),
            Text(
              label,
              style: Theme.of(context).textTheme.bodySmall,
            ),
          ],
        ),
      ),
    );
  }
}
