using FCOMMON;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Project.Dialog
{
    /// <summary>
    /// User info for recipient selection
    /// </summary>
    public class ChatUserInfo
    {
        public string EmployeeId { get; set; }
        public string NickName { get; set; }
        public string UserGroup { get; set; }

        public override string ToString()
        {
            return $"{NickName} ({EmployeeId})";
        }
    }

    public partial class fChat : fBase
    {
        private ChatClientService chatService;
        private string targetEmployeeId;
        private string targetNickName;

        /// <summary>
        /// Constructor for new chat or specific recipient
        /// </summary>
        public fChat(ChatClientService service, string targetEmployeeId = null, string targetNickName = null)
        {
            InitializeComponent();
            this.chatService = service;
            this.targetEmployeeId = targetEmployeeId;
            this.targetNickName = targetNickName;
            this.KeyDown += (s, e) => { if (e.KeyCode == Keys.Escape) this.Close(); };
        }

        private void fChat_Load(object sender, EventArgs e)
        {
            // Subscribe to message received event
            if (chatService != null)
            {
                chatService.MessageReceived += OnMessageReceived;
            }

            // Load user list for recipient selection
            LoadUserList();

            // If target is specified, set it
            if (!string.IsNullOrEmpty(targetEmployeeId))
            {
                SetRecipient(targetEmployeeId, targetNickName);
            }

            // Load recent messages (if any)
            RefreshConnectionStatus();

            // Request user list from server
            if (chatService != null && chatService.IsConnected)
            {
                System.Diagnostics.Debug.WriteLine("[DEBUG] Requesting user list from server...");
                chatService.RequestUserList();
            }
            else
            {
                System.Diagnostics.Debug.WriteLine($"[DEBUG] Cannot request user list - Service: {chatService != null}, Connected: {chatService?.IsConnected}");
            }
        }

        /// <summary>
        /// Load user list into combobox
        /// </summary>
        private void LoadUserList()
        {
            cboRecipient.Items.Clear();

            // Add placeholder
            cboRecipient.Items.Add(new ChatUserInfo
            {
                EmployeeId = "",
                NickName = "Select recipient...",
                UserGroup = ""
            });

            // In a real implementation, this would load from server
            // For now, user will need to type employee ID manually
            // The server's UserListResponse should populate this

            cboRecipient.SelectedIndex = 0;
        }

        /// <summary>
        /// Set specific recipient
        /// </summary>
        private void SetRecipient(string employeeId, string nickName)
        {
            targetEmployeeId = employeeId;
            targetNickName = nickName;

            // Try to find in combobox
            bool found = false;
            for (int i = 0; i < cboRecipient.Items.Count; i++)
            {
                var user = cboRecipient.Items[i] as ChatUserInfo;
                if (user != null && user.EmployeeId == employeeId)
                {
                    cboRecipient.SelectedIndex = i;
                    found = true;
                    break;
                }
            }

            // If not found, add it
            if (!found && !string.IsNullOrEmpty(employeeId))
            {
                var user = new ChatUserInfo
                {
                    EmployeeId = employeeId,
                    NickName = nickName ?? employeeId,
                    UserGroup = ""
                };
                cboRecipient.Items.Add(user);
                cboRecipient.SelectedItem = user;
            }

            // Update form title
            this.Text = $"Chat - {nickName ?? employeeId}";
        }

        private void fChat_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Unsubscribe events
            if (chatService != null)
            {
                chatService.MessageReceived -= OnMessageReceived;
            }
        }

        /// <summary>
        /// Message received event handler
        /// </summary>
        private void OnMessageReceived(object sender, ChatMessage message)
        {
            if (InvokeRequired)
            {
                BeginInvoke(new Action(() => OnMessageReceived(sender, message)));
                return;
            }

            // Get current recipient from combobox
            var selectedUser = cboRecipient.SelectedItem as ChatUserInfo;
            string currentTargetId = selectedUser?.EmployeeId ?? targetEmployeeId;

            // Filter messages - only show messages between current user and target
            string myEmployeeId = chatService.EmployeeId;

            // Show message if:
            // 1. It's from target to me
            // 2. It's from me to target (echo from server)
            // 3. It's a notice (broadcast)
            bool shouldDisplay = false;

            if (message.Type == MessageType.Notice)
            {
                shouldDisplay = true;

                // If it's a join/leave notice, refresh user list
                if (message.Content.Contains("has joined") || message.Content.Contains("has left"))
                {
                    System.Diagnostics.Debug.WriteLine("[DEBUG] User joined/left, refreshing user list...");
                    if (chatService != null && chatService.IsConnected)
                    {
                        chatService.RequestUserList();
                    }
                }
            }
            else if (message.Type == MessageType.UserListResponse)
            {
                // Handle user list response
                HandleUserListResponse(message);
                return;
            }
            else if (!string.IsNullOrEmpty(currentTargetId))
            {
                // From target to me
                if (message.EmployeeId == currentTargetId && message.TargetEmployeeId == myEmployeeId)
                {
                    shouldDisplay = true;
                }
                // From me to target (echo)
                else if (message.EmployeeId == myEmployeeId && message.TargetEmployeeId == currentTargetId)
                {
                    shouldDisplay = true;
                }
            }

            if (shouldDisplay)
            {
                AppendMessage(message);
            }
        }

        /// <summary>
        /// Handle user list response from server
        /// </summary>
        private void HandleUserListResponse(ChatMessage message)
        {
            try
            {
                System.Diagnostics.Debug.WriteLine($"[DEBUG] UserListResponse received: {message.Content}");

                // Parse user list from Content (format: "employeeId1:nickName1:userGroup1,employeeId2:nickName2:userGroup2,...")
                if (string.IsNullOrEmpty(message.Content))
                {
                    System.Diagnostics.Debug.WriteLine("[DEBUG] UserListResponse content is empty");
                    return;
                }

                cboRecipient.Items.Clear();

                // Add placeholder
                cboRecipient.Items.Add(new ChatUserInfo
                {
                    EmployeeId = "",
                    NickName = "Select recipient...",
                    UserGroup = ""
                });

                string[] users = message.Content.Split(',');
                System.Diagnostics.Debug.WriteLine($"[DEBUG] Parsing {users.Length} users");

                foreach (var userStr in users)
                {
                    if (string.IsNullOrWhiteSpace(userStr))
                        continue;

                    string[] parts = userStr.Split(':');
                    System.Diagnostics.Debug.WriteLine($"[DEBUG] User parts: {string.Join(", ", parts)}");

                    if (parts.Length >= 2)
                    {
                        string empId = parts[0].Trim();
                        string nick = parts[1].Trim();

                        System.Diagnostics.Debug.WriteLine($"[DEBUG] Processing user: {empId} - {nick}, My ID: {chatService.EmployeeId}");

                        // Don't add myself
                        if (empId != chatService.EmployeeId)
                        {
                            var user = new ChatUserInfo
                            {
                                EmployeeId = empId,
                                NickName = nick,
                                UserGroup = parts.Length > 2 ? parts[2].Trim() : ""
                            };
                            cboRecipient.Items.Add(user);
                            System.Diagnostics.Debug.WriteLine($"[DEBUG] Added user: {user}");
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine($"[DEBUG] Skipped myself: {empId}");
                        }
                    }
                }

                System.Diagnostics.Debug.WriteLine($"[DEBUG] Total items in combo: {cboRecipient.Items.Count}");

                // Restore previous selection if exists
                if (!string.IsNullOrEmpty(targetEmployeeId))
                {
                    SetRecipient(targetEmployeeId, targetNickName);
                }
                else
                {
                    cboRecipient.SelectedIndex = 0;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"[ERROR] HandleUserListResponse: {ex.Message}");
                MessageBox.Show($"Error loading user list: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Append message to chat display
        /// </summary>
        private void AppendMessage(ChatMessage message)
        {
            string timeStr = message.Timestamp.ToString("HH:mm:ss");
            string displayMsg = "";

            switch (message.Type)
            {
                case MessageType.Chat:
                    displayMsg = $"[{timeStr}] {message.NickName}: {message.Content}";
                    break;

                case MessageType.Notice:
                    displayMsg = $"[{timeStr}] [NOTICE] {message.Content}";
                    break;

                case MessageType.Whisper:
                    displayMsg = $"[{timeStr}] [WHISPER from {message.NickName}] {message.Content}";
                    break;

                default:
                    return;
            }

            txtChatDisplay.AppendText(displayMsg + Environment.NewLine);
            txtChatDisplay.ScrollToCaret();
        }

        /// <summary>
        /// Send button click
        /// </summary>
        private void btnSend_Click(object sender, EventArgs e)
        {
            SendMessage();
        }

        /// <summary>
        /// Input text key down (Enter to send)
        /// </summary>
        private void txtInput_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.SuppressKeyPress = true;
                SendMessage();
            }
        }

        /// <summary>
        /// Send chat message
        /// </summary>
        private void SendMessage()
        {
            string content = txtInput.Text.Trim();
            if (string.IsNullOrEmpty(content))
                return;

            if (chatService == null || !chatService.IsConnected)
            {
                MessageBox.Show("Not connected to chat server.", "Chat", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Get target from combobox
            var selectedUser = cboRecipient.SelectedItem as ChatUserInfo;
            string currentTargetId = selectedUser?.EmployeeId ?? targetEmployeeId;

            if (string.IsNullOrEmpty(currentTargetId))
            {
                MessageBox.Show("Please select a recipient.", "Chat", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            // Create message with target
            var message = new ChatMessage
            {
                Type = MessageType.Chat,
                Content = content,
                TargetEmployeeId = currentTargetId
            };

            bool sent = chatService.SendMessage(message);
            if (sent)
            {
                // Note: Server will echo the message back, so we don't display it here
                // This prevents duplicate messages

                // Clear input
                txtInput.Text = "";
                txtInput.Focus();
            }
            else
            {
                MessageBox.Show("Failed to send message.", "Chat", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Refresh connection status display
        /// </summary>
        private void RefreshConnectionStatus()
        {
            if (chatService != null && chatService.IsConnected)
            {
                lblStatus.Text = $"Connected - {chatService.NickName} ({chatService.UserGroup})";
                lblStatus.ForeColor = Color.Green;
            }
            else
            {
                lblStatus.Text = "Disconnected";
                lblStatus.ForeColor = Color.Red;
            }
        }

        /// <summary>
        /// Timer to update status periodically
        /// </summary>
        private void timerStatus_Tick(object sender, EventArgs e)
        {
            RefreshConnectionStatus();
        }
    }
}
