import 'package:flutter/material.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import '../../../domain/services/contact_service.dart';

class ContactState extends StatefulWidget {
  final Widget child;

  const ContactState({super.key, required this.child});

  static _ContactStateState of(BuildContext context) {
    return context
        .dependOnInheritedWidgetOfExactType<_InheritedContactState>()!
        .data;
  }

  @override
  _ContactStateState createState() => _ContactStateState();
}

class _ContactStateState extends State<ContactState> {
  final ContactService _contactService = ContactService();
  List<Contact> _allContacts = [];
  List<Contact> _favoriteContacts = [];
  bool _loading = true;
  double _scrollOffset = 0.0;
  Contact? _selfContact;

  // Getters for all contacts and favorites
  List<Contact> get contacts => _allContacts;
  List<Contact> get favoriteContacts => _favoriteContacts;
  bool get loading => _loading;
  double get scrollOffset => _scrollOffset;
  Contact? get selfContact => _selfContact;

  @override
  void initState() {
    super.initState();
    _initializeContacts(); // Rename to make it clear this is initialization
    FlutterContacts.addListener(_onContactChange);
  }

  // Private method to initialize contacts without setState during build
  Future<void> _initializeContacts() async {
    try {
      List<Contact> contacts = await _contactService.fetchContacts();
      _processContactsInitial(contacts);
    } catch (e) {
      debugPrint('Error fetching contacts: $e');
    }
  }

  void _onContactChange() async {
    await fetchContacts();
  }

  @override
  void dispose() {
    FlutterContacts.removeListener(_onContactChange);
    super.dispose();
  }

  // Fetch all contacts - public method that can be called after build
  Future<void> fetchContacts() async {
    if (!mounted) return;
    
    setState(() => _loading = true);
    try {
      List<Contact> contacts = await _contactService.fetchContacts();
      if (mounted) {
        _processContacts(contacts);
      }
    } catch (e) {
      debugPrint('Error fetching contacts: $e');
    } finally {
      if (mounted) {
        setState(() => _loading = false);
      }
    }
  }

  // Fetch only favorite contacts
  Future<void> fetchFavoriteContacts() async {
    if (!mounted) return;
    
    setState(() => _loading = true);
    try {
      List<Contact> contacts = await _contactService.fetchFavoriteContacts();
      if (mounted) {
        setState(() => _favoriteContacts = contacts);
      }
    } catch (e) {
      debugPrint('Error fetching favorite contacts: $e');
    } finally {
      if (mounted) {
        setState(() => _loading = false);
      }
    }
  }

  // Process contacts without setState for initial loading
  void _processContactsInitial(List<Contact> contacts) {
    if (!mounted) return;
    
    // Optimize by doing a single pass through contacts instead of multiple iterations
    final filteredContacts = contacts.where((contact) => contact.phones.isNotEmpty).toList()
      ..sort((a, b) => a.displayName.compareTo(b.displayName));
    
    _selfContact = contacts.firstWhere(
      (contact) => contact.displayName.toLowerCase() == "user",
      orElse: () => Contact(),
    );

    if (_selfContact!.phones.isEmpty) {
      _selfContact = null;
    }
    
    _allContacts = filteredContacts;
    _favoriteContacts = filteredContacts.where((contact) => contact.isStarred).toList();
    _loading = false;
    
    // Force a rebuild after initialization is complete
    if (mounted) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        setState(() {});
      });
    }
  }

  void _processContacts(List<Contact> contacts) {
    if (!mounted) return;
    
    // Same optimization as above
    final filteredContacts = contacts.where((contact) => contact.phones.isNotEmpty).toList()
      ..sort((a, b) => a.displayName.compareTo(b.displayName));
    
    _selfContact = contacts.firstWhere(
      (contact) => contact.displayName.toLowerCase() == "user",
      orElse: () => Contact(),
    );

    if (_selfContact!.phones.isEmpty) {
      _selfContact = null;
    }

    setState(() {
      _allContacts = filteredContacts;
      _favoriteContacts = filteredContacts.where((contact) => contact.isStarred).toList();
    });
  }

  Future<void> addNewContact(Contact contact) async {
    await _contactService.addNewContact(contact);
    await fetchContacts();
  }

  void setScrollOffset(double offset) {
    setState(() {
      _scrollOffset = offset;
    });
  }

  @override
  Widget build(BuildContext context) {
    return _InheritedContactState(
      data: this,
      child: widget.child,
    );
  }
}

class _InheritedContactState extends InheritedWidget {
  final _ContactStateState data;

  const _InheritedContactState({required this.data, required super.child});

  @override
  bool updateShouldNotify(_InheritedContactState oldWidget) => true;
}
