<?php
// Chat API for ERP system
require_once '_master/apiHandler.php'; // الكلاس الأساسي
require_once '_helper/client.php'; // الكلاس الأساسي

class pageClass extends apiHandler
{
    public function __construct()
    {
        parent::__construct();
        $this->checkERPAccess();
        if($this->clientSource !== 'web'){
            $checkTokenClient = $this->checkTokenClient();
            $this->getrequest->clientid = isset($checkTokenClient->clientid) ? (int)$checkTokenClient->clientid : 0;
            if (empty($this->getrequest->branch_id)) {
                $this->getrequest->branch_id = isset($checkTokenClient->branchId) ? (int)$checkTokenClient->branchId : 0;
            }
        }else if($this->clientSource == 'web' && $this->getrequest->clientid){
            $this->getrequest->clientid = $this->getrequest->clientid;
        }
    }

    //Get all conversations for a client
    function index()
    {
        try {
            $clientId = $this->getrequest->clientid;
            $response = array();
            
            if ($clientId > 0) {
                // Get chat conversations for this client
                $conversations = R::getAll('SELECT * FROM chat_conversations WHERE client_id = ? ORDER BY last_message_time DESC', [$clientId]);
                
                $response = array(
                    "conversations" => array(),
                    "total_conversations" => count($conversations)
                );
                
                foreach ($conversations as $conversation) {
                    // Get last message for each conversation
                    $lastMessage = R::getRow('SELECT * FROM chat_messages WHERE conversation_id = ? ORDER BY created_at DESC LIMIT 1', [$conversation['id']]);
                    
                    // Get unread count
                    $unreadCount = R::getCell('SELECT COUNT(*) FROM chat_messages WHERE conversation_id = ? AND is_read = 0 AND sender_id != ?', [$conversation['id'], $clientId]);
                    
                    $response['conversations'][] = array(
                        "id" => $conversation['id'],
                        "subject" => $conversation['subject'],
                        "type" => $conversation['type'],
                        "status" => $conversation['status'],
                        "last_message" => $lastMessage ? array(
                            "content" => $lastMessage['content'],
                            "created_at" => $lastMessage['created_at'],
                            "sender_id" => $lastMessage['sender_id']
                        ) : null,
                        "unread_count" => (int)$unreadCount,
                        "created_at" => $conversation['created_at'],
                        "updated_at" => $conversation['updated_at']
                    );
                }
            }

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    //Get messages in a conversation with pagination
    function messages()
    {
        try {
            $conversationId = isset($this->getrequest->conversation_id) ? (int) $this->getrequest->conversation_id : 0;
            $clientId = $this->getrequest->clientid;
            $limit = isset($this->getrequest->limit) ? (int) $this->getrequest->limit : 50;
            $offset = isset($this->getrequest->offset) ? (int) $this->getrequest->offset : 0;

            if ($conversationId <= 0) {
                $this->respond(400, false, 'Conversation ID is required', null, ['conversation_id' => 'Conversation ID is required']);
            }

            // Verify client has access to this conversation
            $conversation = R::getRow('SELECT * FROM chat_conversations WHERE id = ? AND client_id = ?', [$conversationId, $clientId]);
            if (!$conversation) {
                $this->respond(404, false, 'Conversation not found', null, ['conversation_id' => 'Conversation not found']);
            }

            // Get messages
            $messages = R::getAll('SELECT * FROM chat_messages WHERE conversation_id = ? ORDER BY created_at DESC LIMIT ? OFFSET ?', [$conversationId, $limit, $offset]);
            
            // Mark messages as read
            R::exec('UPDATE chat_messages SET is_read = 1 WHERE conversation_id = ? AND sender_id != ?', [$conversationId, $clientId]);

            $response = array(
                "conversation" => array(
                    "id" => $conversation['id'],
                    "subject" => $conversation['subject'],
                    "type" => $conversation['type'],
                    "status" => $conversation['status']
                ),
                "messages" => array(),
                "total_messages" => R::getCell('SELECT COUNT(*) FROM chat_messages WHERE conversation_id = ?', [$conversationId])
            );

            foreach ($messages as $message) {
                $sender = R::getRow('SELECT clientname, logo FROM client WHERE clientid = ?', [$message['sender_id']]);
                
                $response['messages'][] = array(
                    "id" => $message['id'],
                    "content" => $message['content'],
                    "message_type" => $message['message_type'],
                    "sender" => array(
                        "id" => $message['sender_id'],
                        "name" => $sender ? $sender['clientname'] : 'Unknown',
                        "avatar" => $sender && $sender['logo'] ? $this->hosturl . '/views/default/images/client_image/' . $sender['logo'] : null
                    ),
                    "attachment" => $message['attachment'] ? $this->hosturl . '/views/default/images/chat_attachments/' . $message['attachment'] : null,
                    "attachment_type" => $message['attachment_type'],
                    "is_read" => (bool)$message['is_read'],
                    "created_at" => $message['created_at'],
                    "updated_at" => $message['updated_at']
                );
            }

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    //Send a message (creates conversation if needed)
    function send()
    {
        try {
            $conversationId = isset($this->getrequest->conversation_id) ? (int) $this->getrequest->conversation_id : 0;
            $clientId = $this->getrequest->clientid;
            $content = isset($this->getrequest->content) ? trim($this->getrequest->content) : '';
            $messageType = isset($this->getrequest->message_type) ? $this->getrequest->message_type : 'text';
            $subject = isset($this->getrequest->subject) ? trim($this->getrequest->subject) : '';
            $attachment = isset($this->getrequest->attachment) ? $this->getrequest->attachment : null;
            $attachmentType = isset($this->getrequest->attachment_type) ? $this->getrequest->attachment_type : '';

            if (empty($content) && empty($attachment)) {
                $this->respond(400, false, 'Message content or attachment is required', null, ['content' => 'Message content or attachment is required']);
            }

            // Create new conversation if not exists
            if ($conversationId <= 0) {
                if (empty($subject)) {
                    $this->respond(400, false, 'Subject is required for new conversation', null, ['subject' => 'Subject is required for new conversation']);
                }

                $conversation = R::dispense('chat_conversations');
                $conversation->client_id = $clientId;
                $conversation->subject = $subject;
                $conversation->type = 'support';
                $conversation->status = 'active';
                $conversation->last_message_time = date('Y-m-d H:i:s');
                $conversation->created_at = date('Y-m-d H:i:s');
                $conversation->updated_at = date('Y-m-d H:i:s');
                $conversationId = R::store($conversation);
            } else {
                // Verify conversation exists and client has access
                $conversation = R::load('chat_conversations', $conversationId);
                if (!$conversation || $conversation->client_id != $clientId) {
                    $this->respond(404, false, 'Conversation not found', null, ['conversation_id' => 'Conversation not found']);
                }
            }

            // Handle base64 image attachment
            $attachmentPath = null;
            if ($attachment && $attachmentType) {
                $attachmentPath = $this->saveBase64Attachment($attachment, $attachmentType, $clientId, $conversationId);
                if (!$attachmentPath) {
                    $this->respond(400, false, 'Failed to save attachment', null, ['attachment' => 'Invalid attachment data']);
                }
            }

            // Create message
            $message = R::dispense('chat_messages');
            $message->conversation_id = $conversationId;
            $message->sender_id = $clientId;
            $message->content = $content;
            $message->message_type = $messageType;
            $message->attachment = $attachmentPath;
            $message->attachment_type = $attachmentType;
            $message->is_read = 0;
            $message->created_at = date('Y-m-d H:i:s');
            $message->updated_at = date('Y-m-d H:i:s');
            $messageId = R::store($message);

            // Update conversation last message time
            $conversation->last_message_time = date('Y-m-d H:i:s');
            $conversation->updated_at = date('Y-m-d H:i:s');
            R::store($conversation);

            $response = array(
                "message" => array(
                    "id" => $messageId,
                    "conversation_id" => $conversationId,
                    "content" => $content,
                    "message_type" => $messageType,
                    "sender_id" => $clientId,
                    "attachment" => $attachmentPath ? $this->hosturl . '/views/default/images/chat_attachments/' . $attachmentPath : null,
                    "attachment_type" => $attachmentType,
                    "is_read" => false,
                    "created_at" => $message->created_at
                )
            );

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    private function saveBase64Attachment($base64Data, $mimeType, $clientId, $conversationId)
    {
        try {
            // Validate base64 data
            if (preg_match('/^data:image\/(\w+);base64,/', $base64Data, $matches)) {
                $imageType = $matches[1];
                $base64Data = preg_replace('/^data:image\/\w+;base64,/', '', $base64Data);
                $base64Data = str_replace(' ', '+', $base64Data);
                
                // Create directory if it doesn't exist
                $uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/views/default/images/chat_attachments/';
                if (!file_exists($uploadDir)) {
                    mkdir($uploadDir, 0777, true);
                }
                
                // Generate unique filename
                $filename = 'client_' . $clientId . '_conv_' . $conversationId . '_' . time() . '.' . $imageType;
                $filepath = $uploadDir . $filename;
                
                // Decode and save image
                $imageData = base64_decode($base64Data);
                if ($imageData === false) {
                    return false;
                }
                
                $result = file_put_contents($filepath, $imageData);
                if ($result === false) {
                    return false;
                }
                
                return $filename;
            }
            
            return false;
        } catch (Exception $e) {
            return false;
        }
    }

    //Create new conversation with initial message
    function create()
    {
        try {
            $clientId = $this->getrequest->clientid;
            $subject = isset($this->getrequest->subject) ? trim($this->getrequest->subject) : '';
            $type = isset($this->getrequest->type) ? $this->getrequest->type : 'support';
            $content = isset($this->getrequest->content) ? trim($this->getrequest->content) : '';
            $messageType = isset($this->getrequest->message_type) ? $this->getrequest->message_type : 'text';
            $attachment = isset($this->getrequest->attachment) ? $this->getrequest->attachment : null;
            $attachmentType = isset($this->getrequest->attachment_type) ? $this->getrequest->attachment_type : '';

            if (empty($subject)) {
                $this->respond(400, false, 'Subject is required', null, ['subject' => 'Subject is required']);
            }

            if (empty($content) && empty($attachment)) {
                $this->respond(400, false, 'Initial message content or attachment is required', null, ['content' => 'Initial message content or attachment is required']);
            }

            // Create conversation
            $conversation = R::dispense('chat_conversations');
            $conversation->client_id = $clientId;
            $conversation->subject = $subject;
            $conversation->type = $type;
            $conversation->status = 'active';
            $conversation->last_message_time = date('Y-m-d H:i:s');
            $conversation->created_at = date('Y-m-d H:i:s');
            $conversation->updated_at = date('Y-m-d H:i:s');
            $conversationId = R::store($conversation);

            // Handle base64 image attachment
            $attachmentPath = null;
            if ($attachment && $attachmentType) {
                $attachmentPath = $this->saveBase64Attachment($attachment, $attachmentType, $clientId, $conversationId);
                if (!$attachmentPath) {
                    $this->respond(400, false, 'Failed to save attachment', null, ['attachment' => 'Invalid attachment data']);
                }
            }

            // Create initial message
            $message = R::dispense('chat_messages');
            $message->conversation_id = $conversationId;
            $message->sender_id = $clientId;
            $message->content = $content;
            $message->message_type = $messageType;
            $message->attachment = $attachmentPath;
            $message->attachment_type = $attachmentType;
            $message->is_read = 0;
            $message->created_at = date('Y-m-d H:i:s');
            $message->updated_at = date('Y-m-d H:i:s');
            $messageId = R::store($message);

            $response = array(
                "conversation" => array(
                    "id" => $conversationId,
                    "subject" => $subject,
                    "type" => $type,
                    "status" => 'active',
                    "created_at" => $conversation->created_at
                ),
                "message" => array(
                    "id" => $messageId,
                    "content" => $content,
                    "message_type" => $messageType,
                    "attachment" => $attachmentPath ? $this->hosturl . '/views/default/images/chat_attachments/' . $attachmentPath : null,
                    "attachment_type" => $attachmentType,
                    "created_at" => $message->created_at
                )
            );

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    //Delete entire conversation
    function delete()
    {
        try {
            $conversationId = isset($this->getrequest->conversation_id) ? (int) $this->getrequest->conversation_id : 0;
            $clientId = $this->getrequest->clientid;

            if ($conversationId <= 0) {
                $this->respond(400, false, 'Conversation ID is required', null, ['conversation_id' => 'Conversation ID is required']);
            }

            // Verify conversation exists and client has access
            $conversation = R::getRow('SELECT * FROM chat_conversations WHERE id = ? AND client_id = ?', [$conversationId, $clientId]);
            if (!$conversation) {
                $this->respond(404, false, 'Conversation not found', null, ['conversation_id' => 'Conversation not found']);
            }

            // Delete all messages in conversation
            R::exec('DELETE FROM chat_messages WHERE conversation_id = ?', [$conversationId]);

            // Delete conversation
            R::exec('DELETE FROM chat_conversations WHERE id = ?', [$conversationId]);

            $response = array();
            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    //Mark messages as read
    function markRead()
    {
        try {
            $conversationId = isset($this->getrequest->conversation_id) ? (int) $this->getrequest->conversation_id : 0;
            $messageId = isset($this->getrequest->message_id) ? (int) $this->getrequest->message_id : 0;
            $clientId = $this->getrequest->clientid;

            if ($conversationId <= 0 && $messageId <= 0) {
                $this->respond(400, false, 'Conversation ID or Message ID is required', null, ['conversation_id' => 'Conversation ID or Message ID is required']);
            }

            // Verify access
            if ($conversationId > 0) {
                $conversation = R::getRow('SELECT * FROM chat_conversations WHERE id = ? AND client_id = ?', [$conversationId, $clientId]);
                if (!$conversation) {
                    $this->respond(404, false, 'Conversation not found', null, ['conversation_id' => 'Conversation not found']);
                }
                // Mark all messages in conversation as read
                R::exec('UPDATE chat_messages SET is_read = 1 WHERE conversation_id = ? AND sender_id != ?', [$conversationId, $clientId]);
            } else if ($messageId > 0) {
                $message = R::getRow('SELECT cm.*, cc.client_id FROM chat_messages cm JOIN chat_conversations cc ON cm.conversation_id = cc.id WHERE cm.id = ? AND cc.client_id = ?', [$messageId, $clientId]);
                if (!$message) {
                    $this->respond(404, false, 'Message not found', null, ['message_id' => 'Message not found']);
                }
                // Mark specific message as read
                R::exec('UPDATE chat_messages SET is_read = 1 WHERE id = ?', [$messageId]);
            }

            $response = array();
            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }

    //Get unread message count
    function unreadCount()
    {
        try {
            $clientId = $this->getrequest->clientid;
            
            $unreadCount = R::getCell('SELECT COUNT(*) FROM chat_messages cm JOIN chat_conversations cc ON cm.conversation_id = cc.id WHERE cc.client_id = ? AND cm.is_read = 0 AND cm.sender_id != ?', [$clientId, $clientId]);

            $response = array(
                "unread_count" => (int)$unreadCount
            );

            $this->respond(200, true, $this->trans['httpStatusCodes']['200'], null, [], $response);
        } catch (Exception $exception) {
            $this->respond(500, false, $this->trans['httpStatusCodes']['500'], $exception->getMessage(), []);
        }
    }
}
