import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:krow/features/profile/emergency_contacts/data/models/emergency_contact_model.dart';
import 'package:krow/features/profile/emergency_contacts/domain/bloc/emergency_contacts_bloc.dart';
import 'package:krow/features/profile/emergency_contacts/presentation/widgets/contact_form_widget.dart';

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

  @override
  State<ContactsListSliver> createState() => _ContactsListSliverState();
}

class _ContactsListSliverState extends State<ContactsListSliver> {
  final _listKey = GlobalKey<SliverAnimatedListState>();
  late final _contactsBloc = context.read<EmergencyContactsBloc>();

  int _itemsCount = 0;

  EmergencyContactsState get _contactsState => _contactsBloc.state;

  bool _listenWhenHandler(
    EmergencyContactsState previous,
    EmergencyContactsState current,
  ) =>
      previous.contacts != current.contacts;

  void _addListItem(int index) {
    _listKey.currentState?.insertItem(
      index,
      duration: Durations.short3,
    );

    _itemsCount++;
  }

  void _addSingleListItem({required int index}) => _addListItem(index);

  Future<void> _addMultipleListItems({required int addedItemsLength}) async {
    _listKey.currentState?.insertAllItems(
      _itemsCount,
      addedItemsLength,
      duration: Durations.short3,
    );
    _itemsCount += addedItemsLength;

    await Future<void>.delayed(Durations.short2);
  }

  Future<void> _listenHandler(
    BuildContext context,
    EmergencyContactsState state,
  ) async {
    if (state.contacts.length <= _itemsCount) return;

    if (state.contacts.length - _itemsCount == 1) {
      _addSingleListItem(index: state.contacts.length - 1);
    } else {
      await _addMultipleListItems(
        addedItemsLength: state.contacts.length - _itemsCount,
      );
    }
  }

  void _removeListItem({
    required int index,
    required EmergencyContactModel contactData,
  }) {
    _listKey.currentState?.removeItem(
      index,
      (context, animation) {
        return FadeTransition(
          opacity: CurvedAnimation(
            parent: animation,
            curve: const Interval(0, 0.5),
          ),
          child: ScaleTransition(
            scale: CurvedAnimation(
              parent: animation,
              curve: const Interval(0.1, 0.6),
            ),
            child: SizeTransition(
              sizeFactor: animation,
              child: ContactFormWidget(
                contactModel: contactData,
                index: index,
              ),
            ),
          ),
        );
      },
      duration: Durations.short4,
    );

    _itemsCount--;
  }

  @override
  void initState() {
    super.initState();

    _itemsCount = _contactsState.contacts.length;
  }

  @override
  Widget build(BuildContext context) {
    return BlocListener<EmergencyContactsBloc, EmergencyContactsState>(
      bloc: _contactsBloc,
      listenWhen: _listenWhenHandler,
      listener: _listenHandler,
      child: SliverAnimatedList(
        key: _listKey,
        initialItemCount: _contactsState.contacts.length,
        itemBuilder: (
          BuildContext context,
          int index,
          Animation<double> animation,
        ) {
          return SlideTransition(
            position: Tween<Offset>(
              begin: const Offset(0.3, 0),
              end: Offset.zero,
            ).animate(animation),
            child: ContactFormWidget(
              key: ValueKey(_contactsState.contacts[index]),
              contactModel: _contactsState.contacts[index],
              index: index,
              onContactUpdate: ({
                required String firstName,
                required String lastName,
                required String phoneNumber,
              }) {
                context.read<EmergencyContactsBloc>().add(
                      UpdateContactEvent(
                        index: index,
                        firstName: firstName,
                        lastName: lastName,
                        phoneNumber: phoneNumber,
                      ),
                    );
              },
              onDelete: _contactsState.isListReducible
                  ? () {
                      _removeListItem(
                        index: index,
                        contactData: _contactsState.contacts[index],
                      );

                      context.read<EmergencyContactsBloc>().add(
                            DeleteContactEvent(index: index),
                          );
                    }
                  : null,
            ),
          );
        },
      ),
    );
  }

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