import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../background/widget_background_task.dart';
import '../../state/app/modules/account/bloc/account_bloc.dart';
import '../../state/app/modules/account/bloc/account_state.dart';
import '../../state/app/modules/settings/bloc/settings_cubit.dart';
import '../../storage/dev_tools_settings.dart';
import '../../storage/settings.dart' as model;
import '../../theming/light_app_theme.dart';
import '../../utils/haptics.dart';
import '../pages/settings/widgets/endpoint_picker.dart';
import 'login_controller.dart';
import 'post_login_splash.dart';
import 'widgets/login_branding.dart';
import 'widgets/login_card.dart';

class Login extends StatefulWidget {
  const Login({super.key});

  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> with SingleTickerProviderStateMixin {
  static const _marianumRed = LightAppTheme.marianumRed;

  final LoginController _controller = LoginController();
  late final AnimationController _fade = AnimationController(
    vsync: this,
    duration: const Duration(milliseconds: 450),
    value: 1,
  );

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    precacheImage(const AssetImage('assets/logo/icon.png'), context);
    unawaited(PostLoginSplash.precache());
  }

  @override
  void dispose() {
    _fade.dispose();
    _controller.dispose();
    super.dispose();
  }

  void _onLoginSuccess() {
    Haptics.heavyAccent();
    // Re-register the periodic refresh (cancelAll runs on logout) and kick
    // off an immediate one-off so the widget populates within seconds
    // instead of waiting up to 30 minutes for the next periodic slot.
    unawaited(WidgetBackgroundTask.initialize());
    unawaited(WidgetBackgroundTask.requestImmediateRefresh());
    // Fade the login content out before handing over to the post-login splash.
    // Both share the red backdrop, so this reads as one continuous transition
    // instead of an abrupt swap.
    _fade.reverse().whenComplete(() {
      if (!mounted) return;
      context.read<AccountBloc>().setStatus(AccountStatus.loggedIn);
    });
  }

  @override
  Widget build(BuildContext context) => Scaffold(
    backgroundColor: _marianumRed,
    body: FadeTransition(
      opacity: _fade,
      child: SafeArea(
        child: LayoutBuilder(
          builder: (context, constraints) => SingleChildScrollView(
            padding: const EdgeInsets.symmetric(horizontal: 24),
            child: Center(
              child: ConstrainedBox(
                constraints: BoxConstraints(
                  minHeight: constraints.maxHeight,
                  maxWidth: 420,
                ),
                // spaceBetween statt Spacer-in-IntrinsicHeight: Letzteres würde
                // die Column bei Inhaltsänderungen im unteren Block auf die
                // intrinsic-Höhe pinnen und ein paar Pixel Overflow erzeugen.
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Column(
                      children: [
                        const LoginHeader(),
                        const SizedBox(height: 28),
                        LoginCard(
                          controller: _controller,
                          onSuccess: _onLoginSuccess,
                        ),
                        const SizedBox(height: 18),
                        const LoginDisclaimer(),
                      ],
                    ),
                    const Column(
                      mainAxisSize: MainAxisSize.min,
                      children: [_EndpointLink(), LoginFooter()],
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    ),
  );
}

/// Subtle text link above the footer that surfaces the currently selected
/// Marianum-Connect endpoint and opens the picker on tap. Always visible so
/// devs can switch the endpoint before the first login without hunting for a
/// long-press easter egg, but understated enough not to draw regular users
/// into the dev menu.
class _EndpointLink extends StatelessWidget {
  const _EndpointLink();

  @override
  Widget build(BuildContext context) =>
      BlocBuilder<SettingsCubit, model.Settings>(
        builder: (context, settings) {
          final dev = settings.devToolsSettings;
          final label = _label(dev);
          return Padding(
            padding: const EdgeInsets.only(bottom: 4),
            child: TextButton(
              style: TextButton.styleFrom(
                foregroundColor: Colors.white.withValues(alpha: 0.85),
                padding: const EdgeInsets.symmetric(
                  horizontal: 12,
                  vertical: 4,
                ),
                minimumSize: const Size(0, 28),
                tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                textStyle: const TextStyle(
                  fontSize: 12,
                  fontWeight: FontWeight.w500,
                  decoration: TextDecoration.underline,
                ),
              ),
              onPressed: () => MarianumConnectEndpointPicker.show(
                context,
                context.read<SettingsCubit>(),
              ),
              child: Text('Server: $label'),
            ),
          );
        },
      );

  static String _label(DevToolsSettings dev) {
    switch (dev.marianumConnectEndpoint) {
      case MarianumConnectEndpoint.live:
        return 'Normal';
      case MarianumConnectEndpoint.beta:
        return 'Beta';
      case MarianumConnectEndpoint.custom:
        final url = DevToolsSettings.sanitizeCustomUrl(
          dev.marianumConnectCustomUrl,
        );
        return url ?? 'Eigener Server (ungültig)';
    }
  }
}
