import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:dialer/services/call_service.dart';
import 'package:dialer/services/obfuscate_service.dart';
import 'package:dialer/widgets/username_color_generator.dart';
import 'package:flutter/services.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;

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

  @override
  void initState() {
    super.initState();
    _checkInitialCallState();
    _listenToCallState();
    _listenToAudioState();
    _setInitialAudioState();
  }

  @override
  void dispose() {
    _callTimer?.cancel();
    _callStateSubscription?.cancel();
    _audioStateSubscription?.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 && state == "active") {
        setState(() {
          _callStatus = "00:00";
          _startCallTimer();
        });
      }
    } 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";
            _startCallTimer();
          } else if (state == "disconnected" || state == "disconnecting") {
            _callTimer?.cancel();
            _callStatus = "Call Ended";
          } else {
            _callStatus = "Calling...";
          }
        });
      }
    });
  }

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

  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 (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 _toggleIcingProtocol() {
    setState(() {
      icingProtocolOk = !icingProtocolOk;
    });
  }

  void _hangUp() async {
    try {
      print('CallPage: Initiating hangUp');
      final result = await _callService.hangUpCall(context);
      print('CallPage: Hang up result: $result');
    } 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 (updatedContact != null) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Contact added successfully!')),
        );
      }
    } else {
      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"}');
    return PopScope(
      canPop: _callStatus == "Call Ended",
      onPopInvoked: (didPop) {
        if (!didPop) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text('Cannot leave during an active call')),
          );
        }
      },
      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,
                        ),
                      ),
                    ],
                  ),
                ),
                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: () {},
                                        icon: const Icon(
                                          Icons.sim_card,
                                          color: Colors.white,
                                          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: _hangUp,
                    child: Container(
                      padding: const EdgeInsets.all(12),
                      decoration: const BoxDecoration(
                        color: Colors.red,
                        shape: BoxShape.circle,
                      ),
                      child: const Icon(
                        Icons.call_end,
                        color: Colors.white,
                        size: 32,
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
