import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:dialer/domain/services/call_service.dart';
import 'package:dialer/domain/services/obfuscate_service.dart';
import 'package:dialer/presentation/common/widgets/username_color_generator.dart';
import 'package:dialer/presentation/common/widgets/sim_selection_dialog.dart';
import 'package:flutter/services.dart';
import 'package:sim_data_new/sim_data.dart';

class CallPage extends StatefulWidget {
  final String displayName;
  final String phoneNumber;
  final Uint8List? thumbnail;

  const CallPage({
    super.key,
    required this.displayName,
    required this.phoneNumber,
    this.thumbnail,
  });

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

class _CallPageState extends State<CallPage> {
  final ObfuscateService _obfuscateService = ObfuscateService();
  final CallService _callService = CallService();
  bool isMuted = false;
  bool isSpeaker = false;
  bool isKeypadVisible = false;
  bool icingProtocolOk = true;
  String _typedDigits = "";
  Timer? _callTimer;
  int _callSeconds = 0;
  String _callStatus = "Calling...";
  StreamSubscription<String>? _callStateSubscription;
  StreamSubscription<Map<String, dynamic>>? _audioStateSubscription;
  StreamSubscription<int?>? _simStateSubscription;
  bool _isCallActive = true; // Track if call is still active
  String? _simName; // Human-readable SIM card name

  bool get isNumberUnknown => widget.displayName == widget.phoneNumber;

  // Fetch and update human-readable SIM name based on slot
  Future<void> _updateSimName(int? simSlot) async {
    if (!mounted) return;
    if (simSlot != null) {
      try {
        final simData = await SimDataPlugin.getSimData();
        // Find the SIM card matching the slot index, if any
        dynamic card;
        for (var c in simData.cards) {
          if (c.slotIndex == simSlot) {
            card = c;
            break;
          }
        }
        String name;
        if (card != null && card.displayName.isNotEmpty) {
          name = card.displayName;
        } else if (card != null && card.carrierName.isNotEmpty) {
          name = card.carrierName;
        } else {
          name = 'SIM ${simSlot + 1}';
        }
        setState(() {
          _simName = name;
        });
      } catch (e) {
        setState(() {
          _simName = 'SIM ${simSlot + 1}';
        });
      }
    } else {
      setState(() {
        _simName = null;
      });
    }
  }

  @override
  void initState() {
    super.initState();
    _checkInitialCallState();
    _listenToCallState();
    _listenToAudioState();
    _listenToSimState();
    _updateSimName(CallService.getCurrentSimSlot); // Initial SIM name
    _setInitialAudioState();
  }

  @override
  void dispose() {
    _callTimer?.cancel();
    _callStateSubscription?.cancel();
    _audioStateSubscription?.cancel();
    _simStateSubscription?.cancel();
    super.dispose();
  }

  void _setInitialAudioState() {
    final initialAudioState = _callService.currentAudioState;
    if (initialAudioState != null) {
      setState(() {
        isMuted = initialAudioState['muted'] ?? false;
        isSpeaker = initialAudioState['speaker'] ?? false;
      });
    }
  }

  void _checkInitialCallState() async {
    try {
      final state = await _callService.getCallState();
      print('CallPage: Initial call state: $state');
      if (mounted) {
        setState(() {
          if (state == "active") {
            _callStatus = "00:00";
            _isCallActive = true;
            _startCallTimer();
          } else if (state == "disconnected" || state == "disconnecting") {
            _callStatus = "Call Ended";
            _isCallActive = false;
          } else {
            _callStatus = "Calling...";
            _isCallActive = true;
          }
        });
      }
    } catch (e) {
      print('CallPage: Error checking initial state: $e');
    }
  }

  void _listenToCallState() {
    _callStateSubscription = _callService.callStateStream.listen((state) {
      print('CallPage: Call state changed to $state');
      if (mounted) {
        setState(() {
          if (state == "active") {
            _callStatus = "00:00";
            _isCallActive = true;
            _startCallTimer();
          } else if (state == "disconnected" || state == "disconnecting") {
            _callTimer?.cancel();
            _callStatus = "Call Ended";
            _isCallActive = false;
            // Let CallService handle navigation - don't navigate from here
          } else {
            _callStatus = "Calling...";
            _isCallActive = true;
          }
        });
      }
    });
  }

  void _listenToAudioState() {
    _audioStateSubscription = _callService.audioStateStream.listen((state) {
      if (mounted) {
        setState(() {
          isMuted = state['muted'] ?? isMuted;
          isSpeaker = state['speaker'] ?? isSpeaker;
        });
      }
    });
  }

  void _listenToSimState() {
    _simStateSubscription = _callService.simStateStream.listen((simSlot) {
      _updateSimName(simSlot);
    });
  }

  void _startCallTimer() {
    _callTimer?.cancel();
    _callTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (mounted) {
        setState(() {
          _callSeconds++;
          final minutes = (_callSeconds ~/ 60).toString().padLeft(2, '0');
          final seconds = (_callSeconds % 60).toString().padLeft(2, '0');
          _callStatus = '$minutes:$seconds';
        });
      }
    });
  }

  void _addDigit(String digit) async {
    print('CallPage: Tapped digit: $digit');
    setState(() {
      _typedDigits += digit;
    });
    // Send DTMF tone
    const channel = MethodChannel('call_service');
    try {
      final success =
          await channel.invokeMethod<bool>('sendDtmfTone', {'digit': digit});
      if (success != true) {
        print('CallPage: Failed to send DTMF tone for $digit');
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Failed to send DTMF tone')),
          );
        }
      }
    } catch (e) {
      print('CallPage: Error sending DTMF tone: $e');
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Error sending DTMF tone: $e')),
        );
      }
    }
  }

  void _toggleMute() async {
    try {
      print('CallPage: Toggling mute, current state: $isMuted');
      final result = await _callService.muteCall(context, mute: !isMuted);
      print('CallPage: Mute call result: $result');
      if (mounted && result['status'] != 'success') {
        print('CallPage: Failed to toggle mute: ${result['message']}');
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
              content: Text('Failed to toggle mute: ${result['message']}')),
        );
      }
    } catch (e) {
      print('CallPage: Error toggling mute: $e');
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Error toggling mute: $e')),
        );
      }
    }
  }

  Future<void> _toggleSpeaker() async {
    try {
      print('CallPage: Toggling speaker, current state: $isSpeaker');
      final result =
          await _callService.speakerCall(context, speaker: !isSpeaker);
      print('CallPage: Speaker call result: $result');
      if (mounted && result['status'] != 'success') {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
              content: Text('Failed to toggle speaker: ${result['message']}')),
        );
      }
    } catch (e) {
      print('CallPage: Error toggling speaker: $e');
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Error toggling speaker: $e')),
        );
      }
    }
  }

  void _toggleKeypad() {
    setState(() {
      isKeypadVisible = !isKeypadVisible;
    });
  }

  void _showSimSelectionDialog() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return SimSelectionDialog(
          phoneNumber: widget.phoneNumber,
          displayName: widget.displayName,
          onSimSelected: _switchToNewSim,
        );
      },
    );
  }

  void _switchToNewSim(int simSlot) async {
    try {
      print(
          'CallPage: Initiating SIM switch to slot $simSlot for ${widget.phoneNumber}');

      // Use the CallService to handle the SIM switch logic
      await _callService.switchSimAndRedial(
        phoneNumber: widget.phoneNumber,
        displayName: widget.displayName,
        simSlot: simSlot,
        thumbnail: widget.thumbnail,
      );

      print('CallPage: SIM switch initiated successfully');
    } catch (e) {
      print('CallPage: Error initiating SIM switch: $e');

      // Show error feedback if widget is still mounted
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Error switching SIM: $e'),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  void _hangUp() async {
    // Don't try to hang up if call is already ended
    if (!_isCallActive) {
      print('CallPage: Ignoring hangup - call already ended');
      return;
    }

    try {
      print(
          'CallPage: Initiating manual hangUp - canceling any pending SIM switch');

      // Immediately mark call as inactive to prevent further interactions
      setState(() {
        _isCallActive = false;
        _callStatus = "Ending Call...";
      });

      // Cancel any pending SIM switch since user is manually hanging up
      _callService.cancelPendingSimSwitch();

      final result = await _callService.hangUpCall(context);
      print('CallPage: Hang up result: $result');
      
      // If the page is still visible after hangup, try to close it
      if (mounted && ModalRoute.of(context)?.isCurrent == true) {
        print('CallPage: Still visible after hangup, navigating back');
        Navigator.of(context).popUntil((route) => route.isFirst);
      }
    } catch (e) {
      print('CallPage: Error hanging up: $e');
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Error hanging up: $e')),
        );
      }
    }
  }

  void _addContact() async {
    if (await FlutterContacts.requestPermission()) {
      final newContact = Contact()..phones = [Phone(widget.phoneNumber)];
      final updatedContact =
          await FlutterContacts.openExternalInsert(newContact);
      if (mounted && updatedContact != null) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Contact added successfully!')),
        );
      }
    } else {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Permission denied for contacts')),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final double avatarRadius = isKeypadVisible ? 45.0 : 45.0;
    final double nameFontSize = isKeypadVisible ? 24.0 : 24.0;
    final double statusFontSize = isKeypadVisible ? 16.0 : 16.0;

    print(
        'CallPage: Building UI, _callStatus: $_callStatus, route: ${ModalRoute.of(context)?.settings.name ?? "unknown"}');

    // If call is disconnected and we're not actively navigating, force navigation
    if ((_callStatus == "Call Ended" || !_isCallActive) && mounted) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (mounted && ModalRoute.of(context)?.isCurrent == true) {
          print('CallPage: Call ended, forcing navigation back to home');
          Navigator.of(context).popUntil((route) => route.isFirst);
        }
      });
    }

    return PopScope(
      canPop:
          true, // Always allow popping - CallService manages when it's appropriate
      onPopInvoked: (didPop) {
        print(
            'CallPage: PopScope onPopInvoked - didPop: $didPop, _isCallActive: $_isCallActive, _callStatus: $_callStatus');
        // No longer prevent popping during active calls - CallService handles this
      },
      child: Scaffold(
        body: Container(
          color: Colors.black,
          child: SafeArea(
            child: Column(
              children: [
                Container(
                  padding: const EdgeInsets.symmetric(vertical: 8.0),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      const SizedBox(height: 35),
                      ObfuscatedAvatar(
                        imageBytes: widget.thumbnail,
                        radius: avatarRadius,
                        backgroundColor:
                            generateColorFromName(widget.displayName),
                        fallbackInitial: widget.displayName,
                      ),
                      const SizedBox(height: 4),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(
                            icingProtocolOk ? Icons.lock : Icons.lock_open,
                            color: icingProtocolOk ? Colors.green : Colors.red,
                            size: 16,
                          ),
                          const SizedBox(width: 4),
                          Text(
                            'Icing protocol: ${icingProtocolOk ? "ok" : "ko"}',
                            style: TextStyle(
                              color:
                                  icingProtocolOk ? Colors.green : Colors.red,
                              fontSize: 12,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 4),
                      Text(
                        _obfuscateService.obfuscateData(widget.displayName),
                        style: TextStyle(
                          fontSize: nameFontSize,
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      Text(
                        widget.phoneNumber,
                        style: TextStyle(
                          fontSize: statusFontSize,
                          color: Colors.white70,
                        ),
                      ),
                      Text(
                        _callStatus,
                        style: TextStyle(
                          fontSize: statusFontSize,
                          color: Colors.white70,
                        ),
                      ),
                      // Show SIM information if a SIM slot has been set
                      if (_simName != null)
                        Container(
                          margin: const EdgeInsets.only(top: 4.0),
                          padding: const EdgeInsets.symmetric(
                              horizontal: 8.0, vertical: 2.0),
                          decoration: BoxDecoration(
                            color: Colors.blue.withOpacity(0.2),
                            borderRadius: BorderRadius.circular(12),
                            border: Border.all(
                              color: Colors.blue.withOpacity(0.5),
                              width: 1,
                            ),
                          ),
                          child: Text(
                            // Show human-readable SIM name plus slot number
                            '$_simName (SIM ${CallService.getCurrentSimSlot! + 1})',
                            style: TextStyle(
                              fontSize: statusFontSize - 2,
                              color: Colors.lightBlueAccent,
                              fontWeight: FontWeight.w500,
                            ),
                          ),
                        ),
                    ],
                  ),
                ),
                Expanded(
                  child: Column(
                    children: [
                      if (isKeypadVisible) ...[
                        const Spacer(flex: 2),
                        Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 20.0),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Expanded(
                                child: Text(
                                  _typedDigits,
                                  maxLines: 1,
                                  textAlign: TextAlign.right,
                                  overflow: TextOverflow.ellipsis,
                                  style: const TextStyle(
                                    fontSize: 24,
                                    color: Colors.white,
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                              ),
                              IconButton(
                                padding: EdgeInsets.zero,
                                onPressed: _toggleKeypad,
                                icon: const Icon(
                                  Icons.close,
                                  color: Colors.white,
                                ),
                              ),
                            ],
                          ),
                        ),
                        Container(
                          height: MediaQuery.of(context).size.height * 0.4,
                          margin: const EdgeInsets.symmetric(horizontal: 20),
                          padding: const EdgeInsets.all(8),
                          child: GridView.count(
                            shrinkWrap: true,
                            physics: const NeverScrollableScrollPhysics(),
                            crossAxisCount: 3,
                            childAspectRatio: 1.5,
                            mainAxisSpacing: 8,
                            crossAxisSpacing: 8,
                            children: List.generate(12, (index) {
                              String label;
                              if (index < 9) {
                                label = '${index + 1}';
                              } else if (index == 9) {
                                label = '*';
                              } else if (index == 10) {
                                label = '0';
                              } else {
                                label = '#';
                              }
                              return GestureDetector(
                                onTap: () => _addDigit(label),
                                child: Container(
                                  decoration: const BoxDecoration(
                                    shape: BoxShape.circle,
                                    color: Colors.transparent,
                                  ),
                                  child: Center(
                                    child: Text(
                                      label,
                                      style: const TextStyle(
                                        fontSize: 32,
                                        color: Colors.white,
                                      ),
                                    ),
                                  ),
                                ),
                              );
                            }),
                          ),
                        ),
                        const Spacer(flex: 1),
                      ] else ...[
                        const Spacer(),
                        Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 32.0),
                          child: Column(
                            mainAxisSize: MainAxisSize.min,
                            children: [
                              Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                children: [
                                  Column(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      IconButton(
                                        onPressed: _toggleMute,
                                        icon: Icon(
                                          isMuted ? Icons.mic_off : Icons.mic,
                                          color: isMuted
                                              ? Colors.amber
                                              : Colors.white,
                                          size: 32,
                                        ),
                                      ),
                                      Text(
                                        isMuted ? 'Unmute' : 'Mute',
                                        style: const TextStyle(
                                          color: Colors.white,
                                          fontSize: 14,
                                        ),
                                      ),
                                    ],
                                  ),
                                  Column(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      IconButton(
                                        onPressed: _toggleKeypad,
                                        icon: const Icon(
                                          Icons.dialpad,
                                          color: Colors.white,
                                          size: 32,
                                        ),
                                      ),
                                      const Text(
                                        'Keypad',
                                        style: TextStyle(
                                          color: Colors.white,
                                          fontSize: 14,
                                        ),
                                      ),
                                    ],
                                  ),
                                  Column(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      IconButton(
                                        onPressed: _toggleSpeaker,
                                        icon: Icon(
                                          isSpeaker
                                              ? Icons.volume_up
                                              : Icons.volume_off,
                                          color: isSpeaker
                                              ? Colors.amber
                                              : Colors.white,
                                          size: 32,
                                        ),
                                      ),
                                      const Text(
                                        'Speaker',
                                        style: TextStyle(
                                          color: Colors.white,
                                          fontSize: 14,
                                        ),
                                      ),
                                    ],
                                  ),
                                ],
                              ),
                              const SizedBox(height: 20),
                              Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceEvenly,
                                children: [
                                  if (isNumberUnknown)
                                    Column(
                                      mainAxisSize: MainAxisSize.min,
                                      children: [
                                        IconButton(
                                          onPressed: _addContact,
                                          icon: const Icon(
                                            Icons.person_add,
                                            color: Colors.white,
                                            size: 32,
                                          ),
                                        ),
                                        const Text(
                                          'Add Contact',
                                          style: TextStyle(
                                            color: Colors.white,
                                            fontSize: 14,
                                          ),
                                        ),
                                      ],
                                    ),
                                  Column(
                                    mainAxisSize: MainAxisSize.min,
                                    children: [
                                      IconButton(
                                        onPressed: _isCallActive
                                            ? _showSimSelectionDialog
                                            : null,
                                        icon: Icon(
                                          Icons.sim_card,
                                          color: _isCallActive
                                              ? Colors.white
                                              : Colors.grey,
                                          size: 32,
                                        ),
                                      ),
                                      const Text(
                                        'Change SIM',
                                        style: TextStyle(
                                          color: Colors.white,
                                          fontSize: 14,
                                        ),
                                      ),
                                    ],
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ),
                        const Spacer(flex: 3),
                      ],
                    ],
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(bottom: 16.0),
                  child: GestureDetector(
                    onTap: _isCallActive ? _hangUp : null,
                    child: Container(
                      padding: const EdgeInsets.all(12),
                      decoration: BoxDecoration(
                        color: _isCallActive ? Colors.red : Colors.grey,
                        shape: BoxShape.circle,
                      ),
                      child: Icon(
                        _isCallActive ? Icons.call_end : Icons.call_end,
                        color: Colors.white,
                        size: 32,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
