import 'package:flutter/material.dart';

import '../../../routing/app_routes.dart';
import '../login_controller.dart';
import 'login_error_banner.dart';

/// White Card hosting the login form (heading, two text fields, error
/// banner, submit button). Submitting calls [controller.submit] and signals
/// success via [onSuccess].
class LoginCard extends StatefulWidget {
  final LoginController controller;
  final VoidCallback onSuccess;

  const LoginCard({
    required this.controller,
    required this.onSuccess,
    super.key,
  });

  @override
  State<LoginCard> createState() => _LoginCardState();
}

class _LoginCardState extends State<LoginCard> {
  final _formKey = GlobalKey<FormState>();
  final _usernameController = TextEditingController();
  final _passwordController = TextEditingController();
  final _passwordFocus = FocusNode();

  @override
  void initState() {
    super.initState();
    widget.controller.addListener(_onControllerChange);
  }

  @override
  void dispose() {
    widget.controller.removeListener(_onControllerChange);
    _usernameController.dispose();
    _passwordController.dispose();
    _passwordFocus.dispose();
    super.dispose();
  }

  void _onControllerChange() {
    if (mounted) setState(() {});
  }

  String? _required(String? value) =>
      (value ?? '').trim().isEmpty ? 'Eingabe erforderlich' : null;

  Future<void> _submit() async {
    if (widget.controller.loading) return;
    if (!(_formKey.currentState?.validate() ?? false)) return;
    final result = await widget.controller.submit(
      _usernameController.text,
      _passwordController.text,
    );
    if (!mounted) return;
    switch (result) {
      case LoginResult.success:
        widget.onSuccess();
      case LoginResult.nextcloudLoginRequired:
        // 2FA (oder abweichendes NC-Passwort): Anmeldung im Browser über den
        // Login Flow v2 abschließen; ohne Erfolg wird der Login zurückgerollt.
        final ok = await AppRoutes.openNextcloudLoginFlow(context);
        if (!mounted) return;
        if (ok) {
          widget.onSuccess();
        } else {
          await widget.controller.abortNextcloudLogin();
        }
      case LoginResult.failure:
        break;
    }
  }

  InputDecoration _decoration(ThemeData theme, String label, IconData icon) =>
      InputDecoration(
        labelText: label,
        prefixIcon: Icon(icon),
        filled: true,
        fillColor: theme.colorScheme.surfaceContainerHighest.withValues(
          alpha: 0.4,
        ),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide.none,
        ),
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide.none,
        ),
        focusedBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(12),
          borderSide: BorderSide(color: theme.colorScheme.primary, width: 1.5),
        ),
      );

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final loading = widget.controller.loading;
    return Card(
      elevation: 8,
      shadowColor: Colors.black.withValues(alpha: 0.35),
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
      color: theme.colorScheme.surface,
      child: Padding(
        padding: const EdgeInsets.fromLTRB(24, 24, 24, 20),
        child: Form(
          key: _formKey,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Text(
                'Anmelden',
                style: theme.textTheme.titleLarge?.copyWith(
                  fontWeight: FontWeight.w600,
                ),
              ),
              const SizedBox(height: 6),
              Text(
                'Melde dich mit deinen Marianum-Zugangsdaten an.',
                style: theme.textTheme.bodySmall?.copyWith(
                  color: theme.colorScheme.onSurfaceVariant,
                ),
              ),
              const SizedBox(height: 20),
              TextFormField(
                key: const Key('login-username-field'),
                controller: _usernameController,
                enabled: !loading,
                validator: _required,
                autocorrect: false,
                textInputAction: TextInputAction.next,
                onFieldSubmitted: (_) => _passwordFocus.requestFocus(),
                decoration: _decoration(
                  theme,
                  'Nutzername',
                  Icons.person_outline,
                ),
              ),
              const SizedBox(height: 12),
              TextFormField(
                key: const Key('login-password-field'),
                controller: _passwordController,
                focusNode: _passwordFocus,
                enabled: !loading,
                validator: _required,
                obscureText: true,
                obscuringCharacter: '•',
                autocorrect: false,
                enableSuggestions: false,
                keyboardType: TextInputType.visiblePassword,
                textInputAction: TextInputAction.done,
                onFieldSubmitted: (_) => _submit(),
                decoration: _decoration(theme, 'Passwort', Icons.lock_outline),
              ),
              LoginErrorBanner(
                message: widget.controller.errorMessage,
                details: widget.controller.errorDetails,
              ),
              const SizedBox(height: 20),
              SizedBox(
                height: 50,
                child: FilledButton(
                  key: const Key('login-submit-button'),
                  onPressed: loading ? null : _submit,
                  style: FilledButton.styleFrom(
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(12),
                    ),
                    textStyle: const TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  child: loading
                      ? const SizedBox(
                          height: 22,
                          width: 22,
                          child: CircularProgressIndicator(
                            strokeWidth: 2.5,
                            color: Colors.white,
                          ),
                        )
                      : const Text('Anmelden'),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
