import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

import 'package:doormile/core/theme/app_colors.dart';
import 'package:doormile/core/theme/app_theme.dart';

enum _ConnStatus { connecting, connected, disconnected }

class _ChatMessage {
  final String text;
  final bool fromCustomer;
  _ChatMessage(this.text, {required this.fromCustomer});
}

class ChatScreen extends StatefulWidget {
  final String riderName;
  final String bookingId;
  final String? authToken;

  const ChatScreen({
    super.key,
    required this.riderName,
    required this.bookingId,
    this.authToken,
  });

  @override
  State<ChatScreen> createState() => _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {
  final TextEditingController _messageController = TextEditingController();
  final ScrollController _scrollController = ScrollController();
  final List<_ChatMessage> _messages = [];

  WebSocketChannel? _channel;
  _ConnStatus _status = _ConnStatus.connecting;

  @override
  void initState() {
    super.initState();
    _connectWebSocket();
  }

  void _connectWebSocket() {
    if (widget.bookingId.isEmpty) {
      setState(() => _status = _ConnStatus.disconnected);
      return;
    }

    setState(() => _status = _ConnStatus.connecting);

    try {
      String wsUrl = 'ws://api.doormile.com/ws/bookings/${widget.bookingId}/chat?role=customer';
      if (widget.authToken != null && widget.authToken!.isNotEmpty) {
        wsUrl += '&token=${widget.authToken}';
      }

      _channel = WebSocketChannel.connect(
        Uri.parse(wsUrl),
      );

      // Trigger connected status on first successful frame after connect
      _channel!.ready.then((_) {
        if (mounted) setState(() => _status = _ConnStatus.connected);
      }).catchError((e) {
        debugPrint('WS ready error: $e');
        if (mounted) setState(() => _status = _ConnStatus.disconnected);
      });

      _channel!.stream.listen(
        _onMessage,
        onError: (e) {
          debugPrint('WS error: $e');
          if (mounted) setState(() => _status = _ConnStatus.disconnected);
        },
        onDone: () {
          if (mounted) setState(() => _status = _ConnStatus.disconnected);
        },
        cancelOnError: false,
      );
    } catch (e) {
      debugPrint('WS connect error: $e');
      if (mounted) setState(() => _status = _ConnStatus.disconnected);
    }
  }

  void _onMessage(dynamic raw) {
    try {
      final data = jsonDecode(raw as String) as Map<String, dynamic>;
      final text = data['text'] as String? ?? '';
      final sender = data['sender'] as String? ?? '';
      if (text.isEmpty) return;

      if (mounted) {
        setState(() {
          _messages.add(_ChatMessage(text, fromCustomer: sender == 'customer'));
        });
        _scrollToBottom();
      }
    } catch (e) {
      debugPrint('WS parse error: $e');
    }
  }

  void _sendMessage() {
    final text = _messageController.text.trim();
    if (text.isEmpty) return;

    final payload = jsonEncode({'text': text, 'sender': 'customer'});

    if (_channel != null && _status == _ConnStatus.connected) {
      _channel!.sink.add(payload);
    }

    // Optimistically show the message regardless of WS state
    setState(() {
      _messages.add(_ChatMessage(text, fromCustomer: true));
      _messageController.clear();
    });
    _scrollToBottom();
  }

  void _scrollToBottom() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_scrollController.hasClients) {
        _scrollController.animateTo(
          _scrollController.position.maxScrollExtent,
          duration: const Duration(milliseconds: 200),
          curve: Curves.easeOut,
        );
      }
    });
  }

  @override
  void dispose() {
    _messageController.dispose();
    _scrollController.dispose();
    _channel?.sink.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColors.surface,
      appBar: AppBar(
        backgroundColor: AppColors.primary,
        foregroundColor: Colors.white,
        title: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(widget.riderName,
                style: AppTheme.headlineSm.copyWith(color: Colors.white, fontSize: 18)),
            Row(
              children: [
                Container(
                  width: 8,
                  height: 8,
                  margin: const EdgeInsets.only(right: 6),
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    color: switch (_status) {
                      _ConnStatus.connected => const Color(0xFF4CAF50),
                      _ConnStatus.connecting => const Color(0xFFFF9800),
                      _ConnStatus.disconnected => const Color(0xFFEF5350),
                    },
                  ),
                ),
                Text(
                  switch (_status) {
                    _ConnStatus.connected => 'Connected',
                    _ConnStatus.connecting => 'Connecting...',
                    _ConnStatus.disconnected => 'Disconnected',
                  },
                  style: AppTheme.caption.copyWith(color: Colors.white70),
                ),
              ],
            ),
          ],
        ),
        actions: [
          if (_status == _ConnStatus.disconnected)
            IconButton(
              icon: const Icon(Icons.refresh_rounded),
              tooltip: 'Reconnect',
              onPressed: () {
                _channel?.sink.close();
                _connectWebSocket();
              },
            ),
        ],
      ),
      body: Column(
        children: [
          Expanded(
            child: _messages.isEmpty
                ? Center(
                    child: Text(
                      _status == _ConnStatus.connecting
                          ? 'Connecting to chat...'
                          : 'No messages yet. Say hi!',
                      style: AppTheme.bodyMd.copyWith(color: AppColors.onSurfaceVariant),
                    ),
                  )
                : ListView.builder(
                    controller: _scrollController,
                    padding: const EdgeInsets.all(16),
                    itemCount: _messages.length,
                    itemBuilder: (context, index) {
                      final msg = _messages[index];
                      return Align(
                        alignment: msg.fromCustomer
                            ? Alignment.centerRight
                            : Alignment.centerLeft,
                        child: Container(
                          margin: const EdgeInsets.only(bottom: 12),
                          constraints: const BoxConstraints(maxWidth: 280),
                          padding: const EdgeInsets.all(14),
                          decoration: BoxDecoration(
                            color: msg.fromCustomer
                                ? AppColors.primary
                                : AppColors.surfaceContainerHigh,
                            borderRadius: BorderRadius.circular(16).copyWith(
                              bottomLeft: msg.fromCustomer
                                  ? const Radius.circular(16)
                                  : Radius.zero,
                              bottomRight: msg.fromCustomer
                                  ? Radius.zero
                                  : const Radius.circular(16),
                            ),
                          ),
                          child: Text(
                            msg.text,
                            style: AppTheme.bodyMd.copyWith(
                              color: msg.fromCustomer
                                  ? Colors.white
                                  : AppColors.onSurface,
                            ),
                          ),
                        ),
                      );
                    },
                  ),
          ),
          Container(
            padding: EdgeInsets.only(
              left: 16,
              right: 16,
              top: 16,
              bottom: MediaQuery.of(context).padding.bottom + 16,
            ),
            decoration: const BoxDecoration(
              color: Colors.white,
              border: Border(top: BorderSide(color: AppColors.surfaceContainer)),
            ),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _messageController,
                    textInputAction: TextInputAction.send,
                    onSubmitted: (_) => _sendMessage(),
                    decoration: InputDecoration(
                      hintText: 'Message ${widget.riderName}...',
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(999),
                        borderSide: BorderSide.none,
                      ),
                      filled: true,
                      fillColor: AppColors.surfaceContainerLowest,
                      contentPadding:
                          const EdgeInsets.symmetric(horizontal: 20, vertical: 14),
                    ),
                  ),
                ),
                const SizedBox(width: 12),
                InkWell(
                  onTap: _sendMessage,
                  borderRadius: BorderRadius.circular(999),
                  child: Container(
                    padding: const EdgeInsets.all(14),
                    decoration: const BoxDecoration(
                      color: AppColors.primary,
                      shape: BoxShape.circle,
                    ),
                    child: const Icon(Icons.send_rounded, color: Colors.white, size: 20),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
