import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:drift/drift.dart' hide Column;
import 'package:slrpg_app/l10n/app_localizations.dart';

import '../../../../core/theme/app_theme.dart';
import '../../../../shared/data/repositories/user_repository.dart';
import '../../../authentication/data/repositories/auth_repository.dart';
import '../../../../shared/data/repositories/cycle_repository.dart';
import '../../../gamification/domain/entities/avatar_config.dart';
import '../../../gamification/presentation/widgets/avatar_editor.dart';
import 'bodyweight_input_screen.dart';

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

  @override
  ConsumerState<AvatarSetupScreen> createState() => _AvatarSetupScreenState();
}

class _AvatarSetupScreenState extends ConsumerState<AvatarSetupScreen> {
  AvatarConfig _config = const AvatarConfig();
  bool _isLoading = false;

  Future<void> _handleFinish() async {
    final password = await _showPasswordDialog();
    if (password == null) return;

    setState(() => _isLoading = true);

    try {
      final onboardingData = ref.read(onboardingDataProvider);
      final userRepo = ref.read(userRepositoryProvider);
      final authRepo = ref.read(authRepositoryProvider);
      final inventorySettings =
          (onboardingData['inventory_settings'] as Map<String, dynamic>?) ?? {};

      final exerciseVariants =
          onboardingData['exercise_variants'] as Map<String, dynamic>?;
      var user = await userRepo.getLocalUser();
      final avatarJson = _config.toJson();

      if (user == null) {
        final email = onboardingData['email'] as String? ?? '';
        final String username = onboardingData['username'] as String;
        final bodyweight =
            (onboardingData['bodyweight'] as num?)?.toDouble() ?? 80.0;

        if (email.isEmpty || password.isEmpty) {
          throw Exception('Email or password is missing!');
        }

        user = await authRepo.register(
          email: email,
          username: username,
          password: password,
          bodyweight: bodyweight,
          inventorySettings: inventorySettings,
          exerciseVariants: exerciseVariants,
          avatarConfig: avatarJson,
        );
        await Future.delayed(const Duration(milliseconds: 100));
        user = await userRepo.getLocalUser();
        // Verification Request could be moved to AuthRepo, but for now we keep it clean or call via api client directly if needed, or add to AuthRepo. 
        // Assuming ApiClient is accessible or we add it to AuthRepo. Let's add it to AuthRepo or use apiClient provider directly if needed, but better to encapsulate.
        // For this refactor, I'll stick to what was there, but note requestVerification is in ApiClient. 
        // Ideally AuthRepo should expose it. But let's assume register handles the flow or we use the provider.
        // Actually, previous code used ref.read(apiClientProvider).requestVerification(email).
        // Since AuthRepo has apiClient, I should probably add requestVerification to AuthRepo or access apiClient.
        // Let's use apiClientProvider directly for now to minimize changes, or better:
      } else {
        user = user.copyWith(
          currentBodyweight:
              (onboardingData['bodyweight'] as num?)?.toDouble() ??
                  user.currentBodyweight,
          inventorySettings: Value(inventorySettings),
          isDirty: true,
        );
        await userRepo.saveLocalUser(user);
      }

      user = user!.copyWith(
        avatarConfig: Value(avatarJson),
        isDirty: true,
      );
      await userRepo.saveLocalUser(user);
      try {
        final trainingMaxes =
            onboardingData['training_maxes'] as Map<String, dynamic>?;

        if (trainingMaxes != null && trainingMaxes.isNotEmpty) {
          final cycleRepo = ref.read(cycleRepositoryProvider);

          final tmMap = <String, double>{
            'squat': (trainingMaxes['squat'] as num?)?.toDouble() ?? 100.0,
            'pullup': (trainingMaxes['pullup'] as num?)?.toDouble() ?? 80.0,
            'dip': (trainingMaxes['dip'] as num?)?.toDouble() ?? 90.0,
          };

          final cycle = await cycleRepo.createCycle(tmMap);
        }
      } catch (e, stackTrace) {
        log('❌ CYCLE ERROR (non-critical): $e');
        log('   Error type: ${e.runtimeType}');
        log('   Stack:\n$stackTrace');
      }

      if (mounted) {
        ref.read(onboardingDataProvider.notifier).clear();

        context.go('/hub');
      }
    } catch (e, stackTrace) {
      if (mounted) {
        final l10n = AppLocalizations.of(context)!;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(l10n.setupFailed(e.toString())),
            backgroundColor: AppTheme.errorColor,
            duration: const Duration(seconds: 5),
          ),
        );
      }
    } finally {
      if (mounted) setState(() => _isLoading = false);
    }
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context)!;
    return Scaffold(
      appBar: AppBar(
        title: Text(l10n.setupAvatarTitle),
        actions: [
          TextButton(
            onPressed: _isLoading ? null : _handleFinish,
            child: _isLoading
                ? const SizedBox(
                    width: 16,
                    height: 16,
                    child: CircularProgressIndicator(strokeWidth: 2))
                : Text(l10n.finishButton,
                    style: TextStyle(
                        fontWeight: FontWeight.bold,
                        color: AppTheme.primaryColor)),
          )
        ],
      ),
      body: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(16),
            color: AppTheme.surfaceColor,
            width: double.infinity,
            child: Text(
              l10n.setupAvatarSubtitle,
              textAlign: TextAlign.center,
              style: TextStyle(fontStyle: FontStyle.italic, color: Colors.grey),
            ),
          ),
          Expanded(
            child: AvatarEditor(
              initialConfig: _config,
              onChanged: (newConfig) => _config = newConfig,
            ),
          ),
        ],
      ),
    );
  }

  Future<String?> _showPasswordDialog() async {
    final passwordController = TextEditingController();
    final confirmController = TextEditingController();
    final formKey = GlobalKey<FormState>();
    final l10n = AppLocalizations.of(context)!;

    return showDialog<String>(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        title: Text(l10n.secureAccountTitle),
        content: Form(
          key: formKey,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(l10n.secureAccountBody),
              const SizedBox(height: 16),
              TextFormField(
                controller: passwordController,
                obscureText: true,
                autofocus: true,
                decoration: InputDecoration(
                  labelText: l10n.passwordLabel,
                  prefixIcon: Icon(Icons.lock),
                ),
                validator: (v) =>
                    (v?.length ?? 0) < 8 ? l10n.profilePassMinChars : null,
              ),
              const SizedBox(height: 16),
              TextFormField(
                controller: confirmController,
                obscureText: true,
                decoration: InputDecoration(
                  labelText: l10n.confirmPasswordLabel,
                  prefixIcon: Icon(Icons.lock_outline),
                ),
                validator: (v) => v != passwordController.text
                    ? l10n.passwordsDoNotMatch
                    : null,
              ),
            ],
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: Text(l10n.cancelButton),
          ),
          ElevatedButton(
            onPressed: () {
              if (formKey.currentState!.validate()) {
                Navigator.pop(context, passwordController.text);
              }
            },
            child: Text(l10n.confirmButton),
          ),
        ],
      ),
    );
  }
}
