import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'dart:math';
import 'dart:convert';
import '../blocs/auth/auth_bloc.dart';
import '../blocs/auth/auth_event.dart';
import '../blocs/auth/auth_state.dart';
import '../blocs/session/session_bloc.dart';
import '../blocs/session/session_event.dart';
import '../theme/app_theme.dart';
import '../theme/modern_glass_button.dart';

class LoginForm extends StatefulWidget {
  final ValueChanged<bool>? onSignupModeChanged;
  final ValueChanged<bool>? onPasswordModeChanged;

  const LoginForm({
    super.key,
    this.onSignupModeChanged,
    this.onPasswordModeChanged,
  });

  @override
  State<LoginForm> createState() => _LoginFormState();
}

class _LoginFormState extends State<LoginForm> {
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  final _displayNameController = TextEditingController();
  bool _usePasskey = true;
  bool _isSignup = false;

  @override
  void dispose() {
    _usernameController.dispose();
    _passwordController.dispose();
    _displayNameController.dispose();
    super.dispose();
  }

  String _generateRandomBase64(int bytes) {
    final random = Random();
    final values = List<int>.generate(bytes, (i) => random.nextInt(256));
    return base64.encode(values);
  }

  Future<void> _handleAuthentication(
    BuildContext context,
    AuthenticationChallengeReceived state,
  ) async {
    try {
      final credentialId = state.credentialIds.isNotEmpty
          ? state.credentialIds.first
          : _generateRandomBase64(64);

      if (context.mounted) {
        context.read<AuthBloc>().add(
          AuthenticationResponseSubmitted(
            username: _usernameController.text,
            challenge: state.challenge,
            credentialId: credentialId,
            authenticatorData: _generateRandomBase64(37),
            clientDataJSON:
                '{"type":"webauthn.get","challenge":"${state.challenge}","origin":"https://b0esche.cloud"}',
            signature: _generateRandomBase64(128),
          ),
        );
      }
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Authentication failed: $e')));
      }
    }
  }

  Future<void> _handleRegistration(
    BuildContext context,
    RegistrationChallengeReceived state,
  ) async {
    try {
      final credentialId = _generateRandomBase64(64);
      final publicKey = _generateRandomBase64(91);

      if (context.mounted) {
        context.read<AuthBloc>().add(
          RegistrationResponseSubmitted(
            userId: state.userId,
            challenge: state.challenge,
            credentialId: credentialId,
            publicKey: publicKey,
            clientDataJSON:
                '{"type":"webauthn.create","challenge":"${state.challenge}","origin":"https://b0esche.cloud"}',
            attestationObject: _generateRandomBase64(128),
          ),
        );
      }
    } catch (e) {
      if (context.mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Registration failed: $e')));
      }
    }
  }

  void _resetForm() {
    _usernameController.clear();
    _passwordController.clear();
    _displayNameController.clear();
    _usePasskey = true;
  }

  void _setSignupMode(bool isSignup) {
    setState(() => _isSignup = isSignup);
    widget.onSignupModeChanged?.call(isSignup);
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener<AuthBloc, AuthState>(
      listener: (context, state) {
        if (state is AuthFailure) {
          ScaffoldMessenger.of(
            context,
          ).showSnackBar(SnackBar(content: Text(state.error)));
        } else if (state is AuthenticationChallengeReceived) {
          _handleAuthentication(context, state);
        } else if (state is RegistrationChallengeReceived) {
          _handleRegistration(context, state);
        } else if (state is AuthAuthenticated) {
          context.read<SessionBloc>().add(SessionStarted(state.token));
          context.go('/');
        }
      },
      child: Center(
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: AnimatedSize(
            duration: const Duration(milliseconds: 300),
            curve: Curves.easeInOut,
            child: AnimatedSwitcher(
              duration: const Duration(milliseconds: 400),
              transitionBuilder: (child, animation) {
                return FadeTransition(opacity: animation, child: child);
              },
              child: SingleChildScrollView(
                key: ValueKey('${_isSignup}_$_usePasskey'),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Text(
                      _isSignup ? 'create account' : 'sign in',
                      style: const TextStyle(
                        fontSize: 24,
                        color: AppTheme.primaryText,
                      ),
                    ),
                    const SizedBox(height: 24),
                    Container(
                      decoration: BoxDecoration(
                        color: AppTheme.primaryBackground.withValues(
                          alpha: 0.5,
                        ),
                        borderRadius: BorderRadius.circular(16),
                        border: Border.all(
                          color: AppTheme.accentColor.withValues(alpha: 0.3),
                        ),
                      ),
                      child: TextField(
                        controller: _usernameController,
                        textInputAction: TextInputAction.next,
                        keyboardType: TextInputType.text,
                        cursorColor: AppTheme.accentColor,
                        decoration: InputDecoration(
                          hintText: 'username',
                          hintStyle: TextStyle(color: AppTheme.secondaryText),
                          contentPadding: const EdgeInsets.all(12),
                          border: InputBorder.none,
                          prefixIcon: Icon(
                            Icons.person_outline,
                            color: AppTheme.primaryText,
                            size: 20,
                          ),
                        ),
                        style: const TextStyle(color: AppTheme.primaryText),
                      ),
                    ),
                    const SizedBox(height: 16),
                    if (!_isSignup && _usePasskey)
                      const SizedBox.shrink()
                    else
                      Container(
                        decoration: BoxDecoration(
                          color: AppTheme.primaryBackground.withValues(
                            alpha: 0.5,
                          ),
                          borderRadius: BorderRadius.circular(16),
                          border: Border.all(
                            color: AppTheme.accentColor.withValues(alpha: 0.3),
                          ),
                        ),
                        child: TextField(
                          controller: _passwordController,
                          textInputAction: TextInputAction.next,
                          keyboardType: TextInputType.visiblePassword,
                          obscureText: true,
                          cursorColor: AppTheme.accentColor,
                          decoration: InputDecoration(
                            hintText: 'password',
                            hintStyle: TextStyle(color: AppTheme.secondaryText),
                            contentPadding: const EdgeInsets.all(12),
                            border: InputBorder.none,
                            prefixIcon: Icon(
                              Icons.lock_outline,
                              color: AppTheme.primaryText,
                              size: 20,
                            ),
                          ),
                          style: const TextStyle(color: AppTheme.primaryText),
                        ),
                      ),
                    if (!_isSignup && _usePasskey)
                      const SizedBox.shrink()
                    else
                      const SizedBox(height: 16),
                    if (_isSignup)
                      Container(
                        decoration: BoxDecoration(
                          color: AppTheme.primaryBackground.withValues(
                            alpha: 0.5,
                          ),
                          borderRadius: BorderRadius.circular(16),
                          border: Border.all(
                            color: AppTheme.accentColor.withValues(alpha: 0.3),
                          ),
                        ),
                        child: TextField(
                          controller: _displayNameController,
                          textInputAction: TextInputAction.done,
                          keyboardType: TextInputType.text,
                          cursorColor: AppTheme.accentColor,
                          decoration: InputDecoration(
                            hintText: 'display name (optional)',
                            hintStyle: TextStyle(color: AppTheme.secondaryText),
                            contentPadding: const EdgeInsets.all(12),
                            border: InputBorder.none,
                            prefixIcon: Icon(
                              Icons.badge_outlined,
                              color: AppTheme.primaryText,
                              size: 20,
                            ),
                          ),
                          style: const TextStyle(color: AppTheme.primaryText),
                        ),
                      )
                    else
                      const SizedBox.shrink(),
                    if (_isSignup)
                      const SizedBox(height: 16)
                    else
                      const SizedBox.shrink(),
                    SizedBox(
                      width: 150,
                      child: BlocBuilder<AuthBloc, AuthState>(
                        builder: (context, state) {
                          return ModernGlassButton(
                            isLoading: state is AuthLoading,
                            onPressed: () {
                              if (_usernameController.text.isEmpty) {
                                ScaffoldMessenger.of(context).showSnackBar(
                                  const SnackBar(
                                    content: Text('Username is required'),
                                  ),
                                );
                                return;
                              }
                              if (_isSignup) {
                                if (_passwordController.text.isEmpty) {
                                  ScaffoldMessenger.of(context).showSnackBar(
                                    const SnackBar(
                                      content: Text('Password is required'),
                                    ),
                                  );
                                  return;
                                }
                                context.read<AuthBloc>().add(
                                  SignupStarted(
                                    username: _usernameController.text,
                                    email: _usernameController.text,
                                    displayName: _displayNameController.text,
                                    password: _passwordController.text,
                                  ),
                                );
                              } else {
                                if (_usePasskey) {
                                  context.read<AuthBloc>().add(
                                    LoginRequested(
                                      username: _usernameController.text,
                                    ),
                                  );
                                } else {
                                  if (_passwordController.text.isEmpty) {
                                    ScaffoldMessenger.of(context).showSnackBar(
                                      const SnackBar(
                                        content: Text('Password is required'),
                                      ),
                                    );
                                    return;
                                  }
                                  context.read<AuthBloc>().add(
                                    PasswordLoginRequested(
                                      username: _usernameController.text,
                                      password: _passwordController.text,
                                    ),
                                  );
                                }
                              }
                            },
                            child: Text(_isSignup ? 'create' : 'sign in'),
                          );
                        },
                      ),
                    ),
                    const SizedBox(height: 16),
                    if (_isSignup)
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text(
                            'already have an account?',
                            style: TextStyle(color: AppTheme.secondaryText),
                          ),
                          const SizedBox(width: 8),
                          GestureDetector(
                            onTap: () {
                              _resetForm();
                              _setSignupMode(false);
                            },
                            child: Text(
                              'sign in',
                              style: TextStyle(
                                color: AppTheme.accentColor,
                                decoration: TextDecoration.underline,
                              ),
                            ),
                          ),
                        ],
                      )
                    else
                      Column(
                        children: [
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              GestureDetector(
                                onTap: () {
                                  setState(() => _usePasskey = !_usePasskey);
                                  widget.onPasswordModeChanged?.call(
                                    !_usePasskey,
                                  );
                                },
                                child: Text(
                                  _usePasskey ? 'use password' : 'use passkey',
                                  style: TextStyle(
                                    color: AppTheme.accentColor,
                                    decoration: TextDecoration.underline,
                                    fontSize: 12,
                                  ),
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 16),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              Text(
                                'don\'t have an account?',
                                style: TextStyle(color: AppTheme.secondaryText),
                              ),
                              const SizedBox(width: 8),
                              GestureDetector(
                                onTap: () {
                                  _resetForm();
                                  _setSignupMode(true);
                                },
                                child: Text(
                                  'create one',
                                  style: TextStyle(
                                    color: AppTheme.accentColor,
                                    decoration: TextDecoration.underline,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
