import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:votianlt_app/services/developer.dart' as developer;
import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'services/websocket_service.dart';
import 'services/dart_mq.dart';
import 'services/database_service.dart';
import 'app_state.dart';
import 'app_theme.dart';
import 'l10n/app_localizations.dart';

class LoginView extends StatefulWidget {
  const LoginView({super.key, this.suppressConnectionSnack = false});

  // If true, suppress connection-related SnackBars until the user attempts login
  final bool suppressConnectionSnack;

  @override
  State<LoginView> createState() => _LoginViewState();
}

class _LoginViewState extends State<LoginView> {
  final _formKey = GlobalKey<FormState>();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();
  bool _isPasswordVisible = false;
  bool _isLoggingIn = false;
  final StompService _stompService = StompService();
  final AppState _appState = AppState();

  // DartMQ subscriptions for proper cleanup
  DartMQSubscription? _connectionStatusSubscription;
  DartMQSubscription? _authResponseSubscription;
  bool _logoutNoticeShown = false;
  bool _hasNavigatedToJobs = false;
  String _appVersion = '';
  String? _pendingLoginEmail;
  String? _pendingLoginPassword;

  @override
  void initState() {
    super.initState();
    // Pre-populate with test data
    if (kDebugMode) {
      _emailController.text = 'mail@svencarstensen.de';
      _passwordController.text = 'test123';
    }

    _loadAppVersion();
    _initializeStompService();

    // If we came here due to logout, show only a success message and suppress other connection snacks
    if (widget.suppressConnectionSnack && !_logoutNoticeShown) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (!mounted) return;
        _logoutNoticeShown = true;
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(AppLocalizations.of(context).loginSuccess),
            backgroundColor: AppColors.success,
            duration: const Duration(seconds: 1),
          ),
        );
      });
    }
  }

  @override
  void dispose() {
    // Cancel all stream subscriptions to prevent setState() after dispose
    _connectionStatusSubscription?.cancel();
    _authResponseSubscription?.cancel();
    _emailController.dispose();
    _passwordController.dispose();

    // Don't dispose the singleton StompService as it may be used elsewhere
    // _stompService.dispose();

    super.dispose();
  }

  Future<void> _loadAppVersion() async {
    try {
      final PackageInfo packageInfo = await PackageInfo.fromPlatform();
      setState(() {
        _appVersion = packageInfo.version;
      });
    } catch (e) {
      developer.log('Error loading app version: $e', name: 'LoginView');
    }
  }

  void _initializeStompService() {
    // Listen to connection status changes via dart_mq
    // Note: Don't reset _isLoggingIn here - the login flow in _handleLogin
    // manages button state through its own error/success handling.
    _connectionStatusSubscription = DartMQ().subscribe<bool>(
      MQTopics.connectionStatus,
      (isConnected) {
        if (mounted) {
          setState(() {});
        }
      },
    );

    // Listen to authentication responses via dart_mq
    _authResponseSubscription = DartMQ().subscribe<Map<String, dynamic>>(
      MQTopics.authResponse,
      (response) {
        final responseTime = DateTime.now();
        developer.log(
          '=== AUTHENTICATION RESPONSE RECEIVED ===',
          name: 'LoginView',
        );
        developer.log(
          'Timestamp: ${responseTime.toIso8601String()}',
          name: 'LoginView',
        );
        developer.log('Response data: $response', name: 'LoginView');

        if (mounted) {
          WidgetsBinding.instance.addPostFrameCallback((_) {
            _handleAuthResponse(response);
          });
        } else {
          developer.log(
            'Widget not mounted - skipping UI updates for auth response',
            name: 'LoginView',
          );
        }

        developer.log(
          'Authentication response processing completed',
          name: 'LoginView',
        );
      },
    );
  }

  void _clearPendingLoginCredentials() {
    _pendingLoginEmail = null;
    _pendingLoginPassword = null;
  }

  Future<void> _handleAuthResponse(Map<String, dynamic> response) async {
    if (!mounted) return;

    final pendingEmail = _pendingLoginEmail?.trim();
    final pendingPassword = _pendingLoginPassword;
    final hadPendingLogin =
        pendingEmail != null &&
        pendingEmail.isNotEmpty &&
        pendingPassword != null &&
        pendingPassword.isNotEmpty;
    _clearPendingLoginCredentials();

    setState(() {
      _isLoggingIn = false;
    });

    if (response['success'] == true) {
      // Prevent duplicate navigation from multiple auth responses
      if (_hasNavigatedToJobs) {
        developer.log(
          'Already navigated to jobs view - ignoring duplicate auth response',
          name: 'LoginView',
        );
        return;
      }

      final message = response['message'] ?? 'Anmeldung erfolgreich';
      final savedCredentials = await DatabaseService().loadCredentials();
      final effectiveEmail =
          (pendingEmail != null && pendingEmail.isNotEmpty)
              ? pendingEmail
              : (savedCredentials?.email ??
                  _appState.loggedInEmail ??
                  _emailController.text.trim());
      final effectivePassword =
          (pendingPassword != null && pendingPassword.isNotEmpty)
              ? pendingPassword
              : (savedCredentials?.password ?? _passwordController.text);

      developer.log('=== LOGIN SUCCESS ===', name: 'LoginView');
      developer.log('Email: $effectiveEmail', name: 'LoginView');
      developer.log('Message: $message', name: 'LoginView');

      if (effectiveEmail.isNotEmpty) {
        _appState.setLoggedInEmail(effectiveEmail);
      }
      if (effectiveEmail.isNotEmpty && effectivePassword.isNotEmpty) {
        await DatabaseService().saveCredentials(
          effectiveEmail,
          effectivePassword,
        );
      }

      if (!mounted) return;
      _hasNavigatedToJobs = true;

      // Navigate directly to jobs view - jobs will be loaded there
      developer.log(
        'Navigating to jobs view - jobs will be loaded there...',
        name: 'LoginView',
      );
      Navigator.of(context).pushReplacementNamed('/jobs');
      return;
    }

    final errorMessage = response['message'] ?? 'Unbekannter Fehler';
    final errorCode = response['code'] ?? 'No code';

    developer.log('=== LOGIN FAILURE ===', name: 'LoginView');
    developer.log('Error message: $errorMessage', name: 'LoginView');
    developer.log('Error code: $errorCode', name: 'LoginView');
    developer.log('Full error response: $response', name: 'LoginView');

    if (!hadPendingLogin || !mounted) {
      developer.log(
        'Ignoring auth failure in LoginView because no manual login attempt is pending',
        name: 'LoginView',
      );
      return;
    }

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(
          '${AppLocalizations.of(context).loginFailed}: $errorMessage',
        ),
        backgroundColor: AppColors.danger,
        duration: const Duration(seconds: 1),
      ),
    );
  }

  Future<void> _handleLogin() async {
    final loginStartTime = DateTime.now();
    final sessionId = loginStartTime.millisecondsSinceEpoch.toString();

    developer.log('=== LOGIN ATTEMPT STARTED ===', name: 'LoginView');
    developer.log('Session ID: $sessionId', name: 'LoginView');
    developer.log(
      'Timestamp: ${loginStartTime.toIso8601String()}',
      name: 'LoginView',
    );

    if (!_formKey.currentState!.validate()) {
      developer.log(
        'Login validation failed - form is invalid',
        name: 'LoginView',
      );
      return;
    }

    if (_isLoggingIn) {
      developer.log(
        'Login already in progress - ignoring duplicate request',
        name: 'LoginView',
      );
      return;
    }

    String email = _emailController.text.trim();
    String password = _passwordController.text;
    _pendingLoginEmail = email;
    _pendingLoginPassword = password;

    developer.log('Login attempt for email: $email', name: 'LoginView');
    developer.log(
      'Password length: ${_passwordController.text.length} characters',
      name: 'LoginView',
    );

    // Capture ScaffoldMessenger and localizations before any async operations
    final scaffoldMessenger = ScaffoldMessenger.of(context);
    final localizations = AppLocalizations.of(context);

    if (!_stompService.isConnected) {
      developer.log(
        'Not connected to STOMP server - establishing connection first',
        name: 'LoginView',
      );
      developer.log(
        'STOMP service connection state: ${_stompService.isConnected}',
        name: 'LoginView',
      );

      // Always attempt connection to fixed STOMP endpoint (no discovery gating)
      // Show connecting message
      if (!widget.suppressConnectionSnack) {
        scaffoldMessenger.showSnackBar(
          SnackBar(
            content: Text(localizations.connecting),
            backgroundColor: AppColors.primary,
            duration: const Duration(seconds: 1),
          ),
        );
      }

      // Set loading state
      setState(() {
        _isLoggingIn = true;
      });

      try {
        // Start connection to STOMP server
        await _stompService.connect();

        // Check if already connected after connect returns
        if (!_stompService.isConnected) {
          // Wait for connection to be established with a timeout
          try {
            final completer = Completer<bool>();
            final subscription = DartMQ().subscribe<bool>(
              MQTopics.connectionStatus,
              (isConnected) {
                if (isConnected && !completer.isCompleted) {
                  completer.complete(true);
                }
              },
            );

            await completer.future.timeout(const Duration(seconds: 12));
            subscription.cancel();
            developer.log(
              'STOMP connection established - proceeding with login',
              name: 'LoginView',
            );
          } on TimeoutException {
            developer.log('STOMP connection timed out', name: 'LoginView');
          }
        } else {
          developer.log(
            'STOMP already connected after connect - proceeding with login',
            name: 'LoginView',
          );
        }

        // Check if connection was successful
        if (!_stompService.isConnected) {
          setState(() {
            _isLoggingIn = false;
          });
          scaffoldMessenger.showSnackBar(
            SnackBar(
              content: Text(localizations.connectionTimeout),
              backgroundColor: AppColors.danger,
              duration: const Duration(seconds: 2),
            ),
          );
          _clearPendingLoginCredentials();
          return;
        }
      } catch (e, stackTrace) {
        setState(() {
          _isLoggingIn = false;
        });
        developer.log(
          'Error connecting to STOMP server: $e',
          name: 'LoginView',
        );
        developer.log('Stack trace: $stackTrace', name: 'LoginView');
        scaffoldMessenger.showSnackBar(
          SnackBar(
            content: Text('${localizations.connectionError}: $e'),
            backgroundColor: AppColors.danger,
            duration: const Duration(seconds: 1),
          ),
        );
        _clearPendingLoginCredentials();
        return;
      }
    }

    developer.log(
      'Pre-login checks passed - initiating login request',
      name: 'LoginView',
    );
    developer.log(
      'Connection status: connected=${_stompService.isConnected}',
      name: 'LoginView',
    );

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

    developer.log(
      'Sending login request via STOMP service...',
      name: 'LoginView',
    );

    try {
      // Send login request via STOMP
      await _stompService.login(email, password);

      final requestSentTime = DateTime.now();
      final requestDuration =
          requestSentTime.difference(loginStartTime).inMilliseconds;
      developer.log(
        'Login request sent successfully after ${requestDuration}ms',
        name: 'LoginView',
      );
    } catch (e, stackTrace) {
      final errorTime = DateTime.now();
      final errorDuration = errorTime.difference(loginStartTime).inMilliseconds;

      developer.log(
        'LOGIN ERROR: Exception during login request after ${errorDuration}ms',
        name: 'LoginView',
      );
      developer.log('Error: $e', name: 'LoginView');
      developer.log('Stack trace: $stackTrace', name: 'LoginView');

      setState(() {
        _isLoggingIn = false;
      });

      scaffoldMessenger.showSnackBar(
        SnackBar(
          content: Text('${localizations.loginError}: $e'),
          backgroundColor: AppColors.danger,
          duration: const Duration(seconds: 1),
        ),
      );
      _clearPendingLoginCredentials();
    }

    // The auth response will be handled by the stream listener
    // _isLoggingIn will be set to false in the listener
    developer.log(
      'Login request phase completed - waiting for auth response',
      name: 'LoginView',
    );
  }

  @override
  Widget build(BuildContext context) {
    final l10n = AppLocalizations.of(context);

    return Scaffold(
      body: DecoratedBox(
        decoration: const BoxDecoration(gradient: AppGradients.shellBackground),
        child: Column(
          children: [
            Expanded(
              child: SafeArea(
                child: Center(
                  child: SingleChildScrollView(
                    padding: const EdgeInsets.all(24.0),
                    child: Form(
                      key: _formKey,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        crossAxisAlignment: CrossAxisAlignment.stretch,
                        children: [
                          Icon(
                            Icons.account_circle,
                            size: 100,
                            color: AppColors.primary,
                          ),
                          const SizedBox(height: 32),

                          Text(
                            l10n.welcomeBack,
                            style: Theme.of(
                              context,
                            ).textTheme.headlineMedium?.copyWith(
                              fontWeight: FontWeight.bold,
                              color: AppColors.textStrong,
                            ),
                            textAlign: TextAlign.center,
                          ),
                          const SizedBox(height: 8),

                          Text(
                            l10n.loginSubtitle,
                            style: Theme.of(context).textTheme.bodyLarge
                                ?.copyWith(color: AppColors.textMuted),
                            textAlign: TextAlign.center,
                          ),
                          const SizedBox(height: 32),
                          // E-Mail-Feld
                          TextFormField(
                            controller: _emailController,
                            keyboardType: TextInputType.emailAddress,
                            decoration: InputDecoration(
                              labelText: l10n.emailAddress,
                              hintText: l10n.emailAddressHint,
                              prefixIcon: const Icon(Icons.email_outlined),
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                              filled: true,
                              fillColor: AppColors.surface,
                            ),
                            validator: (value) {
                              if (value == null || value.isEmpty) {
                                return l10n.emailAddressRequired;
                              }
                              if (!RegExp(
                                r'^[A-Za-z0-9_.+-]+@[A-Za-z0-9-]+\.[A-Za-z0-9.-]+$',
                              ).hasMatch(value)) {
                                return l10n.emailAddressInvalid;
                              }
                              return null;
                            },
                          ),
                          const SizedBox(height: 16),

                          // Passwort-Feld
                          TextFormField(
                            controller: _passwordController,
                            obscureText: !_isPasswordVisible,
                            decoration: InputDecoration(
                              labelText: l10n.password,
                              hintText: l10n.passwordHint,
                              prefixIcon: const Icon(Icons.lock_outlined),
                              suffixIcon: IconButton(
                                icon: Icon(
                                  _isPasswordVisible
                                      ? Icons.visibility
                                      : Icons.visibility_off,
                                ),
                                onPressed: () {
                                  setState(() {
                                    _isPasswordVisible = !_isPasswordVisible;
                                  });
                                },
                              ),
                              border: OutlineInputBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                              filled: true,
                              fillColor: AppColors.surface,
                            ),
                            validator: (value) {
                              if (value == null || value.isEmpty) {
                                return l10n.passwordRequired;
                              }
                              if (value.length < 6) {
                                return l10n.passwordMinLength;
                              }
                              return null;
                            },
                          ),
                          const SizedBox(height: 24),

                          // Passwort vergessen Link
                          Align(
                            alignment: Alignment.centerRight,
                            child: TextButton(
                              onPressed: () {
                                // Hier würde die "Passwort vergessen" Funktionalität implementiert werden
                                ScaffoldMessenger.of(context).showSnackBar(
                                  SnackBar(
                                    content: Text(l10n.forgotPasswordMessage),
                                    duration: const Duration(seconds: 1),
                                  ),
                                );
                              },
                              child: Text(
                                l10n.forgotPassword,
                                style: const TextStyle(
                                  color: AppColors.primaryStrong,
                                  fontWeight: FontWeight.w500,
                                ),
                              ),
                            ),
                          ),
                          const SizedBox(height: 24),

                          // Verbindungsstatus
                          // Anmelden Button
                          ElevatedButton(
                            onPressed: _isLoggingIn ? null : _handleLogin,
                            style: ElevatedButton.styleFrom(
                              backgroundColor: AppColors.primary,
                              foregroundColor: Colors.white,
                              padding: const EdgeInsets.symmetric(vertical: 16),
                              shape: RoundedRectangleBorder(
                                borderRadius: BorderRadius.circular(12),
                              ),
                              elevation: 0,
                            ),
                            child:
                                _isLoggingIn
                                    ? Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      children: [
                                        const SizedBox(
                                          width: 18,
                                          height: 18,
                                          child: CircularProgressIndicator(
                                            strokeWidth: 2.5,
                                            valueColor:
                                                AlwaysStoppedAnimation<Color>(
                                                  Colors.white,
                                                ),
                                          ),
                                        ),
                                        const SizedBox(width: 12),
                                        Text(
                                          l10n.loggingIn,
                                          style: const TextStyle(
                                            fontSize: 16,
                                            fontWeight: FontWeight.w600,
                                          ),
                                        ),
                                      ],
                                    )
                                    : Text(
                                      l10n.login,
                                      style: const TextStyle(
                                        fontSize: 16,
                                        fontWeight: FontWeight.w600,
                                      ),
                                    ),
                          ),
                          const SizedBox(height: 24),
                        ],
                      ),
                    ),
                  ),
                ),
              ),
            ),
            if (_appVersion.isNotEmpty)
              Padding(
                padding: const EdgeInsets.only(bottom: 16.0),
                child: Text(
                  'Version $_appVersion',
                  style: const TextStyle(
                    fontSize: 12,
                    color: AppColors.textMuted,
                  ),
                  textAlign: TextAlign.center,
                ),
              ),
          ],
        ),
      ),
    );
  }
}
