import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../blocs/auth_event.dart';
import '../../../blocs/auth_bloc.dart';

/// A widget that displays a 6-digit OTP input field.
///
/// This widget handles its own internal [TextEditingController]s and focus nodes.
/// It dispatches [AuthOtpUpdated] to the [AuthBloc] on every change.
class OtpInputField extends StatefulWidget {
  /// Callback for when the OTP code is fully entered (6 digits).
  final ValueChanged<String> onCompleted;

  /// The error message to display, if any.
  final String error;

  /// Creates an [OtpInputField].
  const OtpInputField({
    super.key,
    required this.onCompleted,
    required this.error,
  });

  @override
  State<OtpInputField> createState() => _OtpInputFieldState();
}

class _OtpInputFieldState extends State<OtpInputField> {
  final List<TextEditingController> _controllers = List.generate(
    6,
    (_) => TextEditingController(),
  );
  final List<FocusNode> _focusNodes = List.generate(6, (_) => FocusNode());

  @override
  void dispose() {
    for (final TextEditingController controller in _controllers) {
      controller.dispose();
    }
    for (final FocusNode node in _focusNodes) {
      node.dispose();
    }
    super.dispose();
  }

  /// Helper getter to compute the current OTP code from all controllers.
  String get _otpCode => _controllers.map((TextEditingController c) => c.text).join();

  /// Handles changes to the OTP input fields.
  void _onChanged({
    required BuildContext context,
    required int index,
    required String value,
  }) {
    if (value.length == 1 && index < 5) {
      _focusNodes[index + 1].requestFocus();
    }

    // Notify the Bloc of the change
    BlocProvider.of<AuthBloc>(context).add(AuthOtpUpdated(_otpCode));

    if (_otpCode.length == 6) {
      widget.onCompleted(_otpCode);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: List.generate(6, (int index) {
            return SizedBox(
              width: 56,
              height: 56,
              child: TextField(
                controller: _controllers[index],
                focusNode: _focusNodes[index],
                keyboardType: TextInputType.number,
                inputFormatters: <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly],
                textAlign: TextAlign.center,
                maxLength: 1,
                style: UiTypography.headline3m,
                decoration: InputDecoration(
                  counterText: '',
                  border: OutlineInputBorder(
                    borderSide: BorderSide(
                      color: widget.error.isNotEmpty
                          ? UiColors.textError
                          : (_controllers[index].text.isNotEmpty
                                ? UiColors.primary
                                : UiColors.border),
                      width: 2,
                    ),
                  ),
                  enabledBorder: OutlineInputBorder(
                    borderRadius: UiConstants.radiusMd,
                    borderSide: BorderSide(
                      color: widget.error.isNotEmpty
                          ? UiColors.textError
                          : (_controllers[index].text.isNotEmpty
                                ? UiColors.primary
                                : UiColors.border),
                      width: 2,
                    ),
                  ),
                ),
                onChanged: (String value) =>
                    _onChanged(context: context, index: index, value: value),
              ),
            );
          }),
        ),
        if (widget.error.isNotEmpty)
          Padding(
            padding: const EdgeInsets.only(top: UiConstants.space4),
            child: Center(
              child: Text(widget.error, style: UiTypography.body2r.textError),
            ),
          ),
      ],
    );
  }
}
