import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;

import 'shared_preferences_provider.dart';

class StatusPage extends StatefulWidget {
  final VoidCallback toggleProfile;

  const StatusPage({super.key, required this.toggleProfile});

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

class StatusPageState extends State<StatusPage> with WidgetsBindingObserver {
  WebSocketChannel? channel;
  late final Stream<dynamic> broadcastStream;
  late StreamController<dynamic> controller;
  List<Map<String, dynamic>> messages = [];
  final Map<String, ImageProvider> _imageCache = {};
  static const wsBaseUrl = String.fromEnvironment('WS_BASE_URL',
      defaultValue: 'ws://localhost:8080');
  static const restBaseUrl = String.fromEnvironment('REST_BASE_URL',
      defaultValue: 'http://localhost:8080');

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _initializeWebSocket();
  }

  void _initializeWebSocket() {
    channel = WebSocketChannel.connect(
      Uri.parse('$wsBaseUrl/ws'),
    );

    controller = StreamController<dynamic>.broadcast();
    controller.addStream(channel!.stream);
    broadcastStream = channel!.stream.asBroadcastStream();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    channel?.sink.close();
    controller.close();
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      _reconnectWebSocket();
    }
  }

  void _reconnectWebSocket() {
    if (channel != null) {
      channel!.sink.close();
    }
    _initializeWebSocket();
  }

  List<Map<String, dynamic>> _getMessagesByStatus(String status) {
    return messages.where((message) => message['Status'] == status).toList();
  }

  void _sendStatus(String id, String name, String? image, String status) async {
    final prefsProvider =
        Provider.of<SharedPreferencesProvider>(context, listen: false);

    if (!mounted) return;

    final isStatusActive = prefsProvider.getCurrentStatus() == status;
    final newStatus = isStatusActive ? 'none' : status;

    await prefsProvider.setCurrentStatus(newStatus);

    final message = {
      'Id': id,
      'Name': name,
      'Image': image,
      'Status': newStatus.isEmpty ? 'none' : newStatus,
      'Timestamp': DateTime.now().toIso8601String(),
    };

    //final url = Uri.parse('http://localhost:8080/set');
    final url = Uri.parse('$restBaseUrl/set');
    try {
      final response = await http.post(
        url,
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode(message),
      );

      if (!mounted) return; // Check if widget is still in the tree

      if (response.statusCode == 200) {
        Fluttertoast.showToast(
          msg: 'Status "${newStatus == 'none' ? 'cleared' : newStatus}" sent!',
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.BOTTOM,
          backgroundColor: Colors.blueAccent,
          webBgColor: "#0000FF",
          textColor: Colors.white,
          fontSize: 16.0,
          timeInSecForIosWeb: 1,
        );
      } else {
        Fluttertoast.showToast(
          msg: 'Failed to send status. Please try again.',
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.BOTTOM,
          backgroundColor: Colors.redAccent,
          webBgColor: "#FF0000",
          textColor: Colors.white,
          fontSize: 16.0,
          timeInSecForIosWeb: 1,
        );
      }
    } catch (e) {
      if (!mounted) return;

      Fluttertoast.showToast(
        msg: 'Error sending status. Please check your connection.',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.BOTTOM,
        backgroundColor: Colors.redAccent,
        webBgColor: "#FF0000",
        textColor: Colors.white,
        fontSize: 16.0,
        timeInSecForIosWeb: 1,
      );
      debugPrint("Error in _sendStatus: $e");
    }
  }

  void _handleIncomingMessage(Map<String, dynamic> message) async {
    final prefsProvider =
        Provider.of<SharedPreferencesProvider>(context, listen: false);

    final status = message['Status'];
    final incomingId = message['Id'];
    final image = message['Image'];

    messages.removeWhere((msg) => msg['Id'] == incomingId);

    if (status == 'expired' && incomingId == prefsProvider.getUserId()) {
      await prefsProvider.setCurrentStatus('none');
    } else {
      messages.add(message);
      _cacheImage(incomingId, image);
    }
  }

  void _cacheImage(String id, String? base64Image) {
    if (base64Image != null) {
      _imageCache[id] = Image.memory(base64Decode(base64Image)).image;
    }
  }

  void _showImageDialog(BuildContext context, ImageProvider imageProvider) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return Dialog(
          backgroundColor: Colors.transparent,
          child: GestureDetector(
            onTap: () => Navigator.of(context).pop(),
            child: Container(
              decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(12),
                color: Colors.black87,
              ),
              padding: const EdgeInsets.all(8.0),
              child: Image(image: imageProvider, fit: BoxFit.contain),
            ),
          ),
        );
      },
    );
  }

  Widget _buildMessageItem(Map<String, dynamic> message) {
    final imageId = message['Id'];
    final imageProvider = _imageCache[imageId] ??
        const AssetImage('assets/default_profile_image.png');

    return GestureDetector(
      onTap: () {
        if (_imageCache.containsKey(imageId)) {
          _showImageDialog(context, imageProvider);
        }
      },
      child: Padding(
        padding: const EdgeInsets.symmetric(vertical: 4.0),
        child: Align(
          alignment: Alignment.centerLeft,
          child: Container(
            padding: const EdgeInsets.all(10),
            decoration: BoxDecoration(
              color: Colors.blue.shade50,
              borderRadius: BorderRadius.circular(12),
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  children: [
                    CircleAvatar(
                      radius: 20,
                      backgroundImage: imageProvider,
                    ),
                    const SizedBox(width: 8),
                    Text(
                      "${message['Name']}",
                      style: const TextStyle(
                          fontSize: 16, fontWeight: FontWeight.bold),
                    ),
                  ],
                ),
                const SizedBox(height: 4),
                Text(
                  "Received at: ${message['Timestamp']}",
                  style: const TextStyle(fontSize: 12, color: Colors.grey),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Color getButtonColor(String buttonStatus) {
    final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
    final currentStatus = prefsProvider.getCurrentStatus();
    return currentStatus == buttonStatus ? Colors.blueAccent : Colors.grey;
  }

  Color getButtonTextColor(String buttonStatus) {
    final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
    final currentStatus = prefsProvider.getCurrentStatus();
    return currentStatus == buttonStatus ? Colors.white : Colors.black;
  }

  @override
  Widget build(BuildContext context) {
    final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
    final userName = prefsProvider.getUserName();
    final userLogo = prefsProvider.getUserLogo();
    final userId = prefsProvider.getUserId();

    return Scaffold(
      appBar: AppBar(
        title: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            Image.asset(
              'assets/pogdark_logo.png',
              height: 40,
            ),
          ],
        ),
        backgroundColor: Colors.blueAccent,
      ),
      body: StreamBuilder(
        stream: controller.stream,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            final newMessage =
                jsonDecode(snapshot.data as String) as Map<String, dynamic>;
            _handleIncomingMessage(newMessage);
          }
          var status = prefsProvider.getCurrentStatus();
          final onTheWayMessages = _getMessagesByStatus('otw');
          final arrivedMessages = _getMessagesByStatus('here');

          return Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              children: [
                Expanded(
                  child: Row(
                    children: [
                      Expanded(
                        child: Column(
                          children: [
                            const Text(
                              'On the Way',
                              style: TextStyle(
                                  fontSize: 18, fontWeight: FontWeight.bold),
                            ),
                            Expanded(
                              child: ListView.builder(
                                itemCount: onTheWayMessages.length,
                                itemBuilder: (context, index) {
                                  return _buildMessageItem(
                                      onTheWayMessages[index]);
                                },
                              ),
                            ),
                          ],
                        ),
                      ),
                      Expanded(
                        child: Column(
                          children: [
                            const Text(
                              'At the Pogdark',
                              style: TextStyle(
                                  fontSize: 18, fontWeight: FontWeight.bold),
                            ),
                            Expanded(
                              child: ListView.builder(
                                itemCount: arrivedMessages.length,
                                itemBuilder: (context, index) {
                                  return _buildMessageItem(
                                      arrivedMessages[index]);
                                },
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: getButtonColor('otw'),
                      ),
                      onPressed: () =>
                          _sendStatus(userId, userName, userLogo, 'otw'),
                      child: Text(
                        'On the Way',
                        style: TextStyle(color: getButtonTextColor('otw')),
                      ),
                    ),
                    ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        backgroundColor: getButtonColor('here'),
                      ),
                      onPressed: () =>
                          _sendStatus(userId, userName, userLogo, 'here'),
                      child: Text(
                        'Arrived',
                        style: TextStyle(color: getButtonTextColor('here')),
                      ),
                    ),
                    IconButton(
                      icon: const Icon(Icons.edit, color: Colors.blueAccent),
                      onPressed: widget.toggleProfile,
                      tooltip: 'Edit Profile',
                    ),
                    if (kDebugMode) ...[
                      const SizedBox(height: 20),
                      Text(
                        status,
                        style: TextStyle(color: Colors.red),
                      ),
                    ],
                  ],
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}
