import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart';
import 'package:lba/gen/assets.gen.dart';
import 'package:lba/widgets/button.dart';
import 'package:lba/res/colors.dart';

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

  @override
  State<AddCardBottomSheet> createState() => _AddCardBottomSheetState();
}

class _AddCardBottomSheetState extends State<AddCardBottomSheet> {
  final TextEditingController _cardNumberController = TextEditingController();
  final TextEditingController _expiryDateController = TextEditingController();

  bool _isCardNumberValid = false;
  bool _isExpiryDateValid = false;
  final FocusNode _cardNumberFocus = FocusNode();
  final FocusNode _expiryDateFocus = FocusNode();
  Color _borderColor = AppColors.greyBorder;

  @override
  void initState() {
    super.initState();
    _cardNumberController.addListener(_validateCardNumber);
    _expiryDateController.addListener(_validateExpiryDate);

    _cardNumberFocus.addListener(() {
      setState(() {
        _borderColor = _cardNumberFocus.hasFocus || _expiryDateFocus.hasFocus
            ? Theme.of(context).primaryColor
            : AppColors.greyBorder;
      });
    });
    _expiryDateFocus.addListener(() {
      setState(() {
        _borderColor = _cardNumberFocus.hasFocus || _expiryDateFocus.hasFocus
            ? Theme.of(context).primaryColor
            : AppColors.greyBorder;
      });
    });
  }

  @override
  void dispose() {
    _cardNumberController.removeListener(_validateCardNumber);
    _expiryDateController.removeListener(_validateExpiryDate);
    _cardNumberController.dispose();
    _expiryDateController.dispose();
    _cardNumberFocus.dispose();
    _expiryDateFocus.dispose();
    super.dispose();
  }

  void _validateCardNumber() {
    final text = _cardNumberController.text.replaceAll('-', '');
    setState(() {
      _isCardNumberValid = text.length == 16;
    });
  }

  void _validateExpiryDate() {
    final text = _expiryDateController.text;
    if (text.length == 5) {
      final parts = text.split('/');
      if (parts.length == 2) {
        final month = int.tryParse(parts[0]);
        final year = int.tryParse(parts[1]);
        if (month != null && year != null) {
          final now = DateTime.now();
          final currentYear = now.year % 100;
          final currentMonth = now.month;
          if (month >= 1 &&
              month <= 12 &&
              (year > currentYear ||
                  (year == currentYear && month >= currentMonth))) {
            setState(() {
              _isExpiryDateValid = true;
            });
            return;
          }
        }
      }
    }
    setState(() {
      _isExpiryDateValid = false;
    });
  }

  bool get _isFormValid => _isCardNumberValid && _isExpiryDateValid;

  void _addCard() {
    if (_isFormValid) {
      Navigator.pop(context, _cardNumberController.text);
    }
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      padding: EdgeInsets.only(
        bottom: MediaQuery.of(context).viewInsets.bottom,
      ),
      child: Container(
        padding: const EdgeInsets.all(24.0),
        decoration: BoxDecoration(
          color: AppColors.surface,
          borderRadius: BorderRadius.vertical(top: Radius.circular(20.0)),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Add card',
              style: TextStyle(
                fontSize: 22,
                fontWeight: FontWeight.bold,
                color: AppColors.textPrice,
              ),
            ),
            const SizedBox(height: 8),
            const Divider(),
            const SizedBox(height: 24),
            AnimatedContainer(
              duration: const Duration(milliseconds: 200),
              height: 55,
              decoration: BoxDecoration(
                border: Border.all(color: _borderColor, width: 1.5),
                borderRadius: BorderRadius.circular(12),
              ),
              child: Row(
                children: [
                  Padding(
                    padding: EdgeInsets.symmetric(horizontal: 12.0),
                    child: SvgPicture.asset(Assets.icons.card.path, width: 24, height: 24),
                  ),
                  Expanded(
                    child: TextFormField(
                      controller: _cardNumberController,
                      focusNode: _cardNumberFocus,
                      keyboardType: TextInputType.number,
                      inputFormatters: [
                        FilteringTextInputFormatter.digitsOnly,
                        LengthLimitingTextInputFormatter(16),
                        _CardNumberInputFormatter(),
                      ],
                      decoration: const InputDecoration(
                        hintText: '1234-5678-1234-5678',
                        border: InputBorder.none,
                        focusedBorder: InputBorder.none,
                        enabledBorder: InputBorder.none,
                        errorBorder: InputBorder.none,
                        disabledBorder: InputBorder.none,
                        contentPadding: EdgeInsets.symmetric(vertical: 15),
                      ),
                    ),
                  ),
                  SizedBox(
                    width: 80,
                    child: TextFormField(
                      controller: _expiryDateController,
                      focusNode: _expiryDateFocus,
                      textAlign: TextAlign.center,
                      keyboardType: TextInputType.number,
                      inputFormatters: [
                        FilteringTextInputFormatter.digitsOnly,
                        LengthLimitingTextInputFormatter(4),
                        _ExpiryDateInputFormatter(),
                      ],
                      decoration: const InputDecoration(
                        hintText: 'MM/YY',
                        border: InputBorder.none,
                        focusedBorder: InputBorder.none,
                        enabledBorder: InputBorder.none,
                        errorBorder: InputBorder.none,
                        disabledBorder: InputBorder.none,
                      ),
                    ),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 32),
            SizedBox(
              width: double.infinity,
              height: 50,
              child: Button(
                text: 'Add card',
                onPressed: _isFormValid ? _addCard : () {},
                color: _isFormValid
                    ? AppColors.errorColor
                    : AppColors.errorColor.withOpacity(0.5),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _CardNumberInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    var text = newValue.text;

    if (newValue.selection.baseOffset == 0) {
      return newValue;
    }

    var buffer = StringBuffer();
    for (int i = 0; i < text.length; i++) {
      buffer.write(text[i]);
      var nonZeroIndex = i + 1;
      if (nonZeroIndex % 4 == 0 && nonZeroIndex != text.length) {
        buffer.write('-');
      }
    }

    var string = buffer.toString();
    return newValue.copyWith(
        text: string,
        selection: TextSelection.collapsed(offset: string.length));
  }
}

class _ExpiryDateInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    var newText = newValue.text;

    if (newValue.selection.baseOffset == 0) {
      return newValue;
    }

    if (oldValue.text.endsWith('/') &&
        oldValue.text.length > newValue.text.length) {
      newText = newText.substring(0, newText.length - 1);
    }

    var buffer = StringBuffer();
    for (int i = 0; i < newText.length; i++) {
      buffer.write(newText[i]);
      if (i == 1 && newText.length > 2 && !newText.contains('/')) {
        buffer.write('/');
      }
    }

    var string = buffer.toString();
    return newValue.copyWith(
      text: string.substring(0, string.length > 5 ? 5 : string.length),
      selection: TextSelection.collapsed(
        offset: string.length > 5 ? 5 : string.length,
      ),
    );
  }
}