import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:get/get.dart';
import 'package:audioplayers/audioplayers.dart';
import '../models/message_model.dart';
import '../theme/app_theme.dart';
import '../services/whatsapp_service.dart';

class MessageBubble extends StatelessWidget {
  final MessageModel message;

  const MessageBubble({super.key, required this.message});

  @override
  Widget build(BuildContext context) {
    final isMe = message.fromMe;
    final align = isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start;
    final bg = isMe ? AppTheme.outgoingMsg : AppTheme.incomingMsg;
    final radius = isMe
        ? const BorderRadius.only(
            topLeft: Radius.circular(12),
            topRight: Radius.circular(0),
            bottomLeft: Radius.circular(12),
            bottomRight: Radius.circular(12),
          )
        : const BorderRadius.only(
            topLeft: Radius.circular(0),
            topRight: Radius.circular(12),
            bottomLeft: Radius.circular(12),
            bottomRight: Radius.circular(12),
          );

    return Container(
      margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
      child: Column(
        crossAxisAlignment: align,
        children: [
          Container(
            constraints: BoxConstraints(
              maxWidth: MediaQuery.of(context).size.width * 0.75,
            ),
            padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
            decoration: BoxDecoration(
              color: bg,
              borderRadius: radius,
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                // Show sender name in group chats if not from me
                if (!isMe && message.author != null) ...[
                  Text(
                    message.author!,
                    style: const TextStyle(
                      color: AppTheme.primary,
                      fontSize: 12,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  const SizedBox(height: 4),
                ],

                // Interactive Media widget if message has media
                if (message.hasMedia) ...[
                  InteractiveMediaWidget(message: message),
                  const SizedBox(height: 6),
                ],

                // Message text & time row
                Row(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    Flexible(
                      child: Text(
                        message.body,
                        style: const TextStyle(
                          color: AppTheme.textPrimary,
                          fontSize: 15,
                        ),
                      ),
                    ),
                    const SizedBox(width: 8),
                    Padding(
                      padding: const EdgeInsets.only(top: 4),
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Text(
                            _formatTime(message.timestamp),
                            style: const TextStyle(
                              color: AppTheme.textSecondary,
                              fontSize: 10,
                            ),
                          ),
                          if (isMe) ...[
                            const SizedBox(width: 4),
                            _buildAckIcon(message.ack),
                          ],
                        ],
                      ),
                    ),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildAckIcon(int ack) {
    switch (ack) {
      case 1: // Pending
        return const Icon(Icons.access_time, size: 13, color: AppTheme.textSecondary);
      case 2: // Sent
        return const Icon(Icons.done, size: 15, color: AppTheme.textSecondary);
      case 3: // Delivered
        return const Icon(Icons.done_all, size: 15, color: AppTheme.textSecondary);
      case 4: // Read
        return const Icon(Icons.done_all, size: 15, color: Colors.blue);
      default:
        return const SizedBox.shrink();
    }
  }

  String _formatTime(int timestamp) {
    if (timestamp == 0) return '';
    final dt = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
    return DateFormat('h:mm a').format(dt);
  }
}

class InteractiveMediaWidget extends StatefulWidget {
  final MessageModel message;

  const InteractiveMediaWidget({super.key, required this.message});

  @override
  State<InteractiveMediaWidget> createState() => _InteractiveMediaWidgetState();
}
class _InteractiveMediaWidgetState extends State<InteractiveMediaWidget> {
  final WhatsAppService _svc = Get.find<WhatsAppService>();
  bool _isLoading = false;

  // Audio player state
  final AudioPlayer _player = AudioPlayer();
  StreamSubscription? _posSub;
  StreamSubscription? _durSub;
  StreamSubscription? _stateSub;

  bool _isPlaying = false;
  double _audioProgress = 0.0;
  int _audioDurationSeconds = 1;
  int _audioCurrentSeconds = 0;

  @override
  void initState() {
    super.initState();
    _posSub = _player.onPositionChanged.listen((p) {
      if (mounted) {
        setState(() {
          _audioCurrentSeconds = p.inSeconds;
          if (_audioDurationSeconds > 0) {
            _audioProgress = p.inMilliseconds / (_audioDurationSeconds * 1000);
            if (_audioProgress > 1.0) _audioProgress = 1.0;
          }
        });
      }
    });

    _durSub = _player.onDurationChanged.listen((d) {
      if (mounted) {
        setState(() {
          _audioDurationSeconds = d.inSeconds > 0 ? d.inSeconds : 1;
        });
      }
    });

    _stateSub = _player.onPlayerStateChanged.listen((s) {
      if (mounted) {
        setState(() {
          _isPlaying = s == PlayerState.playing;
          if (s == PlayerState.completed) {
            _audioProgress = 0.0;
            _audioCurrentSeconds = 0;
            _isPlaying = false;
          }
        });
      }
    });
  }

  @override
  void dispose() {
    _posSub?.cancel();
    _durSub?.cancel();
    _stateSub?.cancel();
    _player.dispose();
    super.dispose();
  }

  void _toggleAudioPlayback(String base64Data) async {
    try {
      if (_isPlaying) {
        await _player.pause();
      } else {
        final bytes = base64Decode(base64Data);
        // Clean special characters from ID to construct a safe filename
        final safeId = widget.message.id.replaceAll(RegExp(r'[^a-zA-Z0-9]'), '');
        final tempDir = Directory.systemTemp;
        final tempFile = File('${tempDir.path}/voice_$safeId.mp3');
        
        if (!await tempFile.exists()) {
          await tempFile.writeAsBytes(bytes);
        }
        
        await _player.play(DeviceFileSource(tempFile.path));
      }
    } catch (e) {
      print('[AUDIO PLAYBACK ERROR] $e');
      Get.snackbar(
        'Playback Error',
        'Could not play audio message: $e',
        snackPosition: SnackPosition.BOTTOM,
        backgroundColor: Colors.redAccent.withOpacity(0.8),
        colorText: Colors.white,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      final cachedMedia = _svc.mediaCache[widget.message.id];

      if (cachedMedia != null) {
        return _buildDownloadedMedia(cachedMedia);
      }

      if (_isLoading) {
        return Container(
          padding: const EdgeInsets.all(16),
          width: 140,
          alignment: Alignment.center,
          decoration: BoxDecoration(
            color: Colors.black.withOpacity(0.15),
            borderRadius: BorderRadius.circular(8),
          ),
          child: const SizedBox(
            width: 24,
            height: 24,
            child: CircularProgressIndicator(strokeWidth: 2, color: AppTheme.primary),
          ),
        );
      }

      // Tap to download media placeholder
      return GestureDetector(
        onTap: _downloadMedia,
        child: Container(
          padding: const EdgeInsets.all(12),
          decoration: BoxDecoration(
            color: Colors.black.withOpacity(0.15),
            borderRadius: BorderRadius.circular(8),
          ),
          child: Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(_getIcon(), color: AppTheme.textSecondary, size: 32),
              const SizedBox(width: 12),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                mainAxisSize: MainAxisSize.min,
                children: [
                  Text(
                    _getLabel(),
                    style: const TextStyle(color: AppTheme.textPrimary, fontWeight: FontWeight.w500, fontSize: 13),
                  ),
                  const SizedBox(height: 2),
                  const Text(
                    'Tap to download',
                    style: TextStyle(color: AppTheme.textSecondary, fontSize: 10),
                  ),
                ],
              ),
            ],
          ),
        ),
      );
    });
  }

  Future<void> _downloadMedia() async {
    setState(() => _isLoading = true);
    await _svc.downloadAndCacheMedia(widget.message.id);
    if (mounted) {
      setState(() => _isLoading = false);
    }
  }

  Widget _buildDownloadedMedia(String base64Data) {
    final bytes = base64Decode(base64Data);

    if (widget.message.type == "image" || widget.message.type == "sticker") {
      return ClipRRect(
        borderRadius: BorderRadius.circular(8),
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxHeight: 250),
          child: Image.memory(
            bytes,
            fit: BoxFit.cover,
            width: double.infinity,
          ),
        ),
      );
    }

    if (widget.message.type == "audio") {
      return Container(
        padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
        decoration: BoxDecoration(
          color: Colors.black.withOpacity(0.15),
          borderRadius: BorderRadius.circular(8),
        ),
        child: Row(
          mainAxisSize: MainAxisSize.min,
          children: [
            IconButton(
              icon: Icon(
                _isPlaying ? Icons.pause : Icons.play_arrow,
                color: AppTheme.primary,
                size: 24,
              ),
              onPressed: () => _toggleAudioPlayback(base64Data),
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 8),
                child: LinearProgressIndicator(
                  value: _audioProgress,
                  backgroundColor: AppTheme.surfaceLight,
                  color: AppTheme.primary,
                ),
              ),
            ),
            Text(
              '0:${_audioCurrentSeconds.toString().padLeft(2, '0')}',
              style: const TextStyle(
                color: AppTheme.textPrimary,
                fontFamily: 'monospace',
                fontSize: 11,
              ),
            ),
          ],
        ),
      );
    }

    // Default download complete file placeholder
    return Container(
      padding: const EdgeInsets.all(12),
      decoration: BoxDecoration(
        color: Colors.black.withOpacity(0.15),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          const Icon(Icons.check_circle_outline, color: AppTheme.primary, size: 32),
          const SizedBox(width: 12),
          Text(
            _getLabel(),
            style: const TextStyle(color: AppTheme.textPrimary, fontWeight: FontWeight.w500),
          ),
        ],
      ),
    );
  }

  IconData _getIcon() {
    switch (widget.message.type) {
      case "image": return Icons.photo_outlined;
      case "video": return Icons.videocam_outlined;
      case "audio": return Icons.audiotrack_outlined;
      case "sticker": return Icons.emoji_emotions_outlined;
      default: return Icons.insert_drive_file_outlined;
    }
  }

  String _getLabel() {
    switch (widget.message.type) {
      case "image": return "Image Attachment";
      case "video": return "Video Attachment";
      case "audio": return "Audio / Voice Note";
      case "sticker": return "Sticker Attachment";
      default: return "File Attachment";
    }
  }
}
