<?php

declare(strict_types=1);

namespace App\Models;

use App\Core\Model;
use PDO;

/**
 * ChatMessage Model
 *
 * Manages individual messages within chat conversations.
 */
class ChatMessage extends Model
{
    protected string $table = 'chat_messages';

    /**
     * Get all messages for a conversation, ordered chronologically.
     */
    public function getByConversation(int $conversationId): array
    {
        $sql = "SELECT * FROM `{$this->table}`
                WHERE `conversation_id` = :cid
                ORDER BY `created_at` ASC";

        $stmt = $this->db->prepare($sql);
        $stmt->execute([':cid' => $conversationId]);

        return $stmt->fetchAll();
    }

    /**
     * Add a message to a conversation.
     */
    public function addMessage(int $conversationId, string $senderType, string $message, ?int $senderId = null): int
    {
        return $this->create([
            'conversation_id' => $conversationId,
            'sender_type'     => $senderType,
            'sender_id'       => $senderId,
            'message'         => $message,
            'is_read'         => 0,
        ]);
    }

    /**
     * Get messages newer than a given ID (for polling/new messages).
     */
    public function getNewerThan(int $conversationId, int $afterId): array
    {
        $sql = "SELECT * FROM `{$this->table}`
                WHERE `conversation_id` = :cid AND `id` > :after_id
                ORDER BY `created_at` ASC";

        $stmt = $this->db->prepare($sql);
        $stmt->execute([':cid' => $conversationId, ':after_id' => $afterId]);

        return $stmt->fetchAll();
    }

    /**
     * Mark all admin messages in a conversation as read by visitor.
     */
    public function markAdminMessagesRead(int $conversationId): int
    {
        $sql = "UPDATE `{$this->table}` SET `is_read` = 1
                WHERE `conversation_id` = :cid AND `sender_type` = 'admin' AND `is_read` = 0";

        $stmt = $this->db->prepare($sql);
        $stmt->execute([':cid' => $conversationId]);

        return $stmt->rowCount();
    }

    /**
     * Mark all visitor messages in a conversation as read by admin.
     */
    public function markVisitorMessagesRead(int $conversationId): int
    {
        $sql = "UPDATE `{$this->table}` SET `is_read` = 1
                WHERE `conversation_id` = :cid AND `sender_type` = 'visitor' AND `is_read` = 0";

        $stmt = $this->db->prepare($sql);
        $stmt->execute([':cid' => $conversationId]);

        return $stmt->rowCount();
    }

    /**
     * Get the count of unread messages for admin across all conversations.
     */
    public function getUnreadCountForAdmin(): int
    {
        $sql = "SELECT COUNT(*) AS total FROM `{$this->table}` m
                INNER JOIN `chat_conversations` c ON m.`conversation_id` = c.`id`
                WHERE m.`sender_type` = 'visitor' AND m.`is_read` = 0
                AND c.`status` IN ('active', 'pending')";

        $stmt = $this->db->prepare($sql);
        $stmt->execute();

        return (int) ($stmt->fetch()['total'] ?? 0);
    }

    /**
     * Get the last message ID for a conversation (for polling).
     */
    public function getLastId(int $conversationId): int
    {
        $sql = "SELECT MAX(`id`) AS last_id FROM `{$this->table}`
                WHERE `conversation_id` = :cid";

        $stmt = $this->db->prepare($sql);
        $stmt->execute([':cid' => $conversationId]);

        return (int) ($stmt->fetch()['last_id'] ?? 0);
    }
}
