<?php

namespace App\Controllers\Chat;

use App\Controllers\BaseController;
use App\Models\Chat\ChatDeparmentModel;
use App\Models\Chat\ChatDeparmentUserModel;
use App\Models\Chat\ChatMessageModel;
use App\Models\Chat\ChatModel;
use App\Models\ChatNotification;
use App\Models\ChatUser;
use App\Models\Clientes\ClienteModel;
use App\Models\Facturas\FacturaModel;
use App\Models\Pedidos\PedidoModel;
use App\Models\Presupuestos\PresupuestoModel;
use App\Models\Usuarios\UserModel;
use App\Services\MessageService;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\Log\Logger;
use Psr\Log\LoggerInterface;
use Hermawan\DataTables\DataTable;
use CodeIgniter\I18n\Time;

class ChatController extends BaseController
{
    protected ChatDeparmentModel $chatDeparmentModel;
    protected ChatDeparmentUserModel $chatDeparmentUserModel;
    protected ChatModel $chatModel;
    protected ChatMessageModel $chatMessageModel;
    protected UserModel $userModel;
    protected ClienteModel $clienteModel;
    protected ChatUser $chatUserModel;
    protected ChatNotification $chatNotificationModel;
    protected array $viewData;
    protected static $viewPath = 'themes/vuexy/form/mensajes/';


    public function initController(
        RequestInterface $request,
        ResponseInterface $response,
        LoggerInterface $logger
    ) {
        parent::initController($request, $response, $logger);

        // Add your code here.
        $this->chatDeparmentModel = model(ChatDeparmentModel::class);
        $this->chatDeparmentUserModel = model(ChatDeparmentUserModel::class);
        $this->chatModel = model(ChatModel::class);
        $this->chatMessageModel = model(ChatMessageModel::class);
        $this->userModel = model(UserModel::class);
        $this->clienteModel = model(ClienteModel::class);
        $this->chatUserModel = model(ChatUser::class);
        $this->chatNotificationModel = model(ChatNotification::class);
    }
    public function index() {}
    public function get_chat_departments()
    {

        $data = $this->chatDeparmentModel->getChatDepartments();
        return $this->response->setJSON($data);
    }
    public function get_chat_department_select(){
        $query = $this->chatDeparmentModel->getChatDepartmentSelect($this->request->getGet("q"));
        return $this->response->setJSON($query->get()->getResultObject());
    }
    public function get_chat_presupuesto(int $chat_department_id, int $presupuesto_id)
    {

        $data = [
            "chat" => null,
            "messages" => null,
            "count" => 0,
        ];
        $chat = $this->chatModel->getChatPresupuesto($chat_department_id, $presupuesto_id);
        if ($chat) {
            $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id);
            $this->chatMessageModel->set_chat_department_messages_as_read($chat->id);
            $data["count"] = count($data["messages"]);
        }
        $data["chat"] = $chat;
        return $this->response->setJSON($data);
    }
    public function get_chat_pedido(int $chat_department_id, int $pedido_id)
    {

        $data = [
            "chat" => null,
            "messages" => null,
            "count" => 0,
        ];
        $chat = $this->chatModel->getChatPedido($chat_department_id, $pedido_id);
        if ($chat) {
            $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id);
            $this->chatMessageModel->set_chat_department_messages_as_read($chat->id);
            $data["count"] = count($data["messages"]);
        }
        $data["chat"] = $chat;
        return $this->response->setJSON($data);
    }
    public function get_chat_factura(int $chat_department_id, int $factura_id)
    {

        $data = [
            "chat" => null,
            "messages" => null,
            "count" => 0,
        ];
        $chat = $this->chatModel->getChatFactura($chat_department_id, $factura_id);
        if ($chat) {
            $data["messages"] = $this->chatMessageModel->get_chat_messages($chat->id);
            $this->chatMessageModel->set_chat_department_messages_as_read($chat->id);
            $data["count"] = count($data["messages"]);
        }
        $data["chat"] = $chat;
        return $this->response->setJSON($data);
    }
    public function get_chat_direct_view($chat_id)
    {
        $chat = $this->chatModel->find($chat_id);
        $this->viewData['breadcrumb'] = [
            ['title' => lang("Chat.chat"), 'route' => route_to("mensajeriaView"), 'active' => false],
            ['title' => $chat->title, 'route' => 'javascript:void(0);', 'active' => true]
        ];
        $this->viewData["chatId"] = $chat_id;
        $auth_user = auth()->user();
        $this->chatModel->setAsViewedChatUserNotifications($chat_id, $auth_user->id);
        $this->chatModel->setAsUnviewedChatUserMessages($chat_id, $auth_user->id);

        return view(static::$viewPath . 'messageChat', $this->viewData);
    }
    public function get_chat_presupuesto_view($chat_id)
    {
        $chat = $this->chatModel->find($chat_id);
        $this->viewData['breadcrumb'] = [
            ['title' => lang("Chat.chat"), 'route' => route_to("mensajeriaView"), 'active' => false],
            ['title' => $chat->title, 'route' => 'javascript:void(0);', 'active' => true]
        ];
        $this->viewData["modelId"] = $chat->presupuesto_id;
        $this->viewData["type"] = "presupuesto";
        $auth_user = auth()->user();
        $this->chatModel->setAsViewedChatUserNotifications($chat_id, $auth_user->id);
        $this->chatModel->setAsUnviewedChatUserMessages($chat_id, $auth_user->id);

        if($chat->chat_department_id){
            return view(static::$viewPath . 'messageChatPresupuesto', $this->viewData);
        }else{
            return view(static::$viewPath . 'messageChatInternal', $this->viewData);
        }
    }
    public function get_chat_pedido_view($chat_id)
    {
        $chat = $this->chatModel->find($chat_id);
        $this->viewData['breadcrumb'] = [
            ['title' => lang("Chat.chat"), 'route' => route_to("mensajeriaView"), 'active' => false],
            ['title' => $chat->title, 'route' => 'javascript:void(0);', 'active' => true]
        ];
        $this->viewData["modelId"] = $chat->pedido_id;
        $this->viewData["type"] = "pedido";
        $auth_user = auth()->user();
        $this->chatModel->setAsViewedChatUserNotifications($chat_id, $auth_user->id);
        $this->chatModel->setAsUnviewedChatUserMessages($chat_id, $auth_user->id);
        if($chat->chat_department_id ){
            return view(static::$viewPath . 'messageChatPedido', $this->viewData);
        }else{
            return view(static::$viewPath . 'messageChatInternal', $this->viewData);
        }
    }
    public function get_chat_factura_view($chat_id)
    {
        $chat = $this->chatModel->find($chat_id);
        $this->viewData['breadcrumb'] = [
            ['title' => lang("Chat.chat"), 'route' => route_to("mensajeriaView"), 'active' => false],
            ['title' => $chat->title, 'route' => 'javascript:void(0);', 'active' => true]
        ];
        $this->viewData["modelId"] = $chat->factura_id;
        $this->viewData["type"] = "factura";
        $auth_user = auth()->user();
        $this->chatModel->setAsViewedChatUserNotifications($chat_id, $auth_user->id);
        $this->chatModel->setAsUnviewedChatUserMessages($chat_id, $auth_user->id);

        if($chat->chat_department_id){
            return view(static::$viewPath . 'messageChatFactura', $this->viewData);
        }else{
            return view(static::$viewPath . 'messageChatInternal', $this->viewData);
        }
    }
    public function get_chat(int $chat_id)
    {

        $data = $this->chatModel->getChat($chat_id);
        return $this->response->setJSON($data);
    }
    public function store_chat_message_presupuesto()
    {

        $data = $this->request->getPost();
        // $data = $this->chatModel->createChatPresupuesto();
        $existChat = $this->chatModel->existChatPresupuesto($data["chat_department_id"], $data["model_id"]);
        if ($existChat == false) {
            $chatId = $this->chatModel->createChatPresupuesto($data["chat_department_id"], $data["model_id"]);
        } else {
            $chat = $this->chatModel->getChatPresupuesto($data["chat_department_id"], $data["model_id"]);
            $chatId =  $chat->id;
        }
        $chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]);
        $dataResponse = $this->chatMessageModel->find($chat_message_id);
        $chatDepartmentUsers = $this->chatDeparmentModel->getChatDepartmentUsers($data["chat_department_id"]);
        foreach ($chatDepartmentUsers as  $user) {
            if ($user->id != auth()->user()->id) {
                $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user->id]);
            }
        }
        return $this->response->setJSON($dataResponse);
    }
    public function store_chat_message_pedido()
    {

        $data = $this->request->getPost();
        $existChat = $this->chatModel->existChatPedido($data["chat_department_id"], $data["model_id"]);
        if ($existChat == false) {
            $chatId = $this->chatModel->createChatPedido($data["chat_department_id"], $data["model_id"]);
        } else {
            $chat = $this->chatModel->getChatPedido($data["chat_department_id"], $data["model_id"]);
            $chatId =  $chat->id;
        }
        $chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]);
        $dataResponse = $this->chatMessageModel->find($chat_message_id);
        $chatDepartmentUsers = $this->chatDeparmentModel->getChatDepartmentUsers($data["chat_department_id"]);
        foreach ($chatDepartmentUsers as  $user) {
            if ($user->id != auth()->user()->id) {
                $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user->id]);
            }
        }
        return $this->response->setJSON($dataResponse);
    }
    public function store_chat_message_factura()
    {

        $data = $this->request->getPost();
        $existChat = $this->chatModel->existChatFactura($data["chat_department_id"], $data["model_id"]);
        if ($existChat == false) {
            $chatId = $this->chatModel->createChatFactura($data["chat_department_id"], $data["model_id"]);
        } else {
            $chat = $this->chatModel->getChatFactura($data["chat_department_id"], $data["model_id"]);
            $chatId =  $chat->id;
        }
        $chat_message_id = $this->chatMessageModel->insert(["chat_id" => $chatId, "sender_id" => auth()->user()->id, "message" => $data["message"]]);
        $dataResponse = $this->chatMessageModel->find($chat_message_id);
        $chatDepartmentUsers = $this->chatDeparmentModel->getChatDepartmentUsers($data["chat_department_id"]);
        foreach ($chatDepartmentUsers as  $user) {
            if ($user->id != auth()->user()->id) {
                $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user->id]);
            }
        }
        return $this->response->setJSON($dataResponse);
    }
    public function store_chat_message_single()
    {
        $data = $this->request->getPost();

        $existChat = $this->chatMessageModel->get_chat_contact_messages($data["receiver_id"]);
        if (count($existChat) > 0) {
            $chatId = $existChat[0]->chat_id;
        } else {
            $chatId = $this->chatModel->createChatSingle();
        }
        $chat_message_id = $this->chatMessageModel->insert(
            [
                "chat_id" => $chatId,
                "sender_id" => auth()->user()->id,
                "message" => $data["message"],
                "receiver_id" => $data["receiver_id"],
            ]
        );
        $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $data["receiver_id"]]);
        $dataResponse = $this->chatMessageModel->find($chat_message_id);
        return $this->response->setJSON($dataResponse);
    }
    public function get_chat_internal_contacts()
    {
        $auth_user = auth()->user();
        if ($auth_user->cliente_id) {
            $users = $this->chatModel->getOpenChatCliente($auth_user->id);
        } else {
            $users = $this->userModel->builder()
                ->whereNotIn("id", [$auth_user->id])
                ->where("deleted_at", null)
                ->get()->getResultObject();
        }
        foreach ($users as $user) {
            $user->unreadMessages = $this->chatMessageModel->get_chat_messages_count($user->id);
        }
        usort($users, fn($a, $b) => $a->unreadMessages < $b->unreadMessages);
        return $this->response->setJSON($users);
    }
    public function get_chat_internal_contact(int $user_id)
    {
        $auth_user = auth()->user();
        // if ($auth_user->cliente_id) {
        //     return $this->response->setJSON([]);
        // }
        $users = $this->userModel->builder()
            ->where("deleted_at", null)
            ->where("id", $user_id)
            ->get()->getFirstRow();
        return $this->response->setJSON($users);
    }
    public function get_chat_internal_messages(int $user_id)
    {
        $conversation = $this->chatMessageModel->get_chat_contact_messages($user_id);

        return $this->response->setJSON($conversation);
    }
    public function get_chat_cliente()
    {
        $cliente_id = auth()->user()->cliente_id;
        $response = [];
        if ($cliente_id) {
            $data = $this->clienteModel->getClienteDataPresupuestoPedidoFactura($cliente_id);
            $response["totalMessages"] = 0;
            $response["chatFacturas"] = $this->chatModel->getClienteChatFacturas($data["facturas"]);
            $mensajes_directos = $this->chatModel->getChatDirectMessageNotifications();

            foreach ($response["chatFacturas"] as $key => $value) {
                $response["totalMessages"] += $value->unreadMessages;
            }
            $response["chatPresupuestos"] = $this->chatModel->getClienteChatPresupuestos($data["presupuestos"]);
            foreach ($response["chatPresupuestos"] as $key => $value) {
                $response["totalMessages"] += $value->unreadMessages;
            }
            foreach ($mensajes_directos as $value) {
                $response["internals"][] = $value;
                $response["totalMessages"] += $value->unreadMessages;
            }
            $response["chatPedidos"] = $this->chatModel->getClienteChatPedidos($data["pedidos"]);
            foreach ($response["chatPedidos"] as $key => $value) {
                $response["totalMessages"] += $value->unreadMessages;
            }
            $response["data"] = $data;
        } else {
            $response["internals"] = $this->chatModel->getChatDepartmentNotifications();
            $internal_notifications = $this->chatModel->getChatInternalNotifications();
            $mensajes_directos = $this->chatModel->getChatDirectMessageNotifications();
            foreach ($internal_notifications as $value) {
                $response["internals"][] = $value;
            }
            foreach ($mensajes_directos as $value) {
                $response["internals"][] = $value;
            }
            $response["totalMessages"] = 0;
            foreach ($response["internals"] as $key => $value) {
                $response["totalMessages"] += $value->unreadMessages;
            }
        }
        return $this->response->setJSON($response);
    }

    public function get_chat_department_users(int $chat_department_id)
    {
        $data = $this->chatDeparmentModel->getChatDepartmentUsers($chat_department_id);
        return $this->response->setJSON($data);
    }
    public function get_chat_users_internal()
    {
        $query = $this->userModel->builder()->select(
            [
                "id",
                "CONCAT(first_name,' ',last_name,'(',username,')') as name"
            ]
        )->where("cliente_id", null)
            ->where("deleted_at", null)
            ->whereNotIn("id", [auth()->user()->id]);
        if ($this->request->getGet("q")) {
            $query->groupStart()
                ->orLike("users.username", $this->request->getGet("q"))
                ->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
                ->groupEnd();
        }

        return $this->response->setJSON($query->get()->getResultObject());
    }
    public function get_chat_users_all()
    {
        $query = $this->userModel->builder()->select(
            [
                "id",
                "CONCAT(first_name,' ',last_name,'(',username,')') as name"
            ]
        )
            ->where("deleted_at", null)
            ->whereNotIn("id", [auth()->user()->id]);
        if ($this->request->getGet("q")) {
            $query->groupStart()
                ->orLike("users.username", $this->request->getGet("q"))
                ->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
                ->groupEnd();
        }

        return $this->response->setJSON($query->get()->getResultObject());
    }
    public function get_presupuesto_client_users(int $presupuesto_id)
    {
        $pm = model(PresupuestoModel::class);
        $p = $pm->find($presupuesto_id);
        $query = $this->userModel->builder()->select(
            [
                "id",
                "CONCAT(first_name,' ',last_name,'(',username,')') as name"
            ]
        )
            ->where("deleted_at", null)
            ->whereNotIn("id", [auth()->user()->id])
            ->where("cliente_id",$p->cliente_id);
        if ($this->request->getGet("q")) {
            $query->groupStart()
                ->orLike("users.username", $this->request->getGet("q"))
                ->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
                ->groupEnd();
        }

        return $this->response->setJSON($query->get()->getResultObject());
    }
    public function get_pedido_client_users(int $pedido_id)
    {
        $pm = model(PedidoModel::class);
        $p = $pm->find($pedido_id);
        $query = $this->userModel->builder()->select(
            [
                "id",
                "CONCAT(first_name,' ',last_name,'(',username,')') as name"
            ]
        )
            ->where("deleted_at", null)
            ->whereNotIn("id", [auth()->user()->id])
            ->where("cliente_id",$p->cliente()->id);
        if ($this->request->getGet("q")) {
            $query->groupStart()
                ->orLike("users.username", $this->request->getGet("q"))
                ->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
                ->groupEnd();
        }

        return $this->response->setJSON($query->get()->getResultObject());
    }
    public function get_factura_client_users(int $factura_id)
    {
        $fm = model(FacturaModel::class);
        $f = $fm->find($factura_id);
        $query = $this->userModel->builder()->select(
            [
                "id",
                "CONCAT(first_name,' ',last_name,'(',username,')') as name"
            ]
        )
            ->where("deleted_at", null)
            ->whereNotIn("id", [auth()->user()->id])
            ->where("cliente_id",$f->cliente_id);
        if ($this->request->getGet("q")) {
            $query->groupStart()
                ->orLike("users.username", $this->request->getGet("q"))
                ->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
                ->groupEnd();
        }

        return $this->response->setJSON($query->get()->getResultObject());
    }
    public function store_hebra_presupuesto()
    {
        $auth_user = auth()->user();
        $bodyData = $this->request->getPost();
        $chat_id = $this->chatModel->insert([
            "presupuesto_id" => $bodyData["modelId"],
            "title" => $bodyData["title"]
        ]);
        $chatMessageId = $this->chatMessageModel->insert([
            "chat_id" => $chat_id,
            "message" => $bodyData["message"],
            "sender_id" => $auth_user->id
        ]);
        if (isset($bodyData["users"])) {
            $bodyData["users"][] = $auth_user->id;
            $chatUserData = array_map(fn($x) => ["user_id" => $x, "chat_id" => $chat_id], $bodyData["users"]);
            $this->chatUserModel->insertBatch($chatUserData);
            foreach ($bodyData["users"] as $userId) {
                $this->chatNotificationModel->insert(
                    ["chat_message_id" => $chatMessageId, "user_id" => $userId]
                );
            }
        }
        return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => true]);
    }

    public function store_hebra_pedido()
    {
        $bodyData = $this->request->getPost();
        $chat_id = $this->chatModel->insert([
            "pedido_id" => $bodyData["modelId"],
            "title" => $bodyData["title"]

        ]);
        $chatMessageId = $this->chatMessageModel->insert([
            "chat_id" => $chat_id,
            "message" => $bodyData["message"],
            "sender_id" => auth()->user()->id
        ]);
        if (isset($bodyData["users"])) {
            $chatUserData = array_map(fn($x) => ["user_id" => $x, "chat_id" => $chat_id], $bodyData["users"]);
            $this->chatUserModel->insertBatch($chatUserData);
            foreach ($bodyData["users"] as $userId) {
                $this->chatNotificationModel->insert(
                    ["chat_message_id" => $chatMessageId, "user_id" => $userId]
                );
            }
        }
        return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => true]);
    }

    public function store_hebra_factura()
    {
        $bodyData = $this->request->getPost();
        $chat_id = $this->chatModel->insert([
            "factura_id" => $bodyData["modelId"],
            "title" => $bodyData["title"]
        ]);
        $chatMessageId = $this->chatMessageModel->insert([
            "chat_id" => $chat_id,
            "message" => $bodyData["message"],
            "sender_id" => auth()->user()->id
        ]);
        if (isset($bodyData["users"])) {
            $chatUserData = array_map(fn($x) => ["user_id" => $x, "chat_id" => $chat_id], $bodyData["users"]);
            $this->chatUserModel->insertBatch($chatUserData);
            foreach ($bodyData["users"] as $userId) {
                $this->chatNotificationModel->insert(
                    ["chat_message_id" => $chatMessageId, "user_id" => $userId]
                );
            }
        }
        return $this->response->setJSON(["message" => "Hebra creada correctamente", "status" => true]);
    }
    public function update_hebra($chat_id)
    {
        $bodyData = $this->request->getPost();
        $chatMessageId =  $this->chatMessageModel->insert([
            "chat_id" => $chat_id,
            "message" => $bodyData["message"],
            "sender_id" => auth()->user()->id
        ]);
        $actualUsers = $this->chatUserModel->builder()->select("user_id")->where("chat_id", $chat_id)->get()->getResultArray();
        $actualUsersArray = array_map(fn($x) => $x["user_id"], $actualUsers);
        foreach ($actualUsersArray as $key => $user_id) {
            $this->chatNotificationModel->insert(
                ["chat_message_id" => $chatMessageId, "user_id" => $user_id]
            );
        }
        if (isset($bodyData["users"])) {
            foreach ($bodyData["users"] as $userId) {
                if (in_array($userId, $actualUsersArray) == false) {
                    $chatUserData = ["user_id" => $userId, "chat_id" => $chat_id];
                    $this->chatUserModel->insert($chatUserData);
                }
                $this->chatNotificationModel->insert(
                    ["chat_message_id" => $chatMessageId, "user_id" => $userId]
                );
            }
        }
        return $this->response->setJSON(["message" => "Hebra actualizada correctamente", "status" => true]);
    }
    public function get_hebra_presupuesto($presupuesto_id)
    {
        $data = $this->chatModel->getPresupuestoHebras($presupuesto_id);
        $notifications = $this->chatModel->builder()->select([
            "chat_notifications.id"
        ])
            ->join("chat_messages", "chat_messages.chat_id = chats.id", "left")
            ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left")
            ->where("chats.presupuesto_id", $presupuesto_id)
            ->where("chat_notifications.user_id", auth()->user()->id)
            ->get()->getResultArray();
        foreach ($notifications as $notification) {
            $this->chatNotificationModel->update($notification["id"], ["viewed" => true]);
        }
        return $this->response->setJSON($data);
    }
    public function get_hebra_pedido($pedido_id)
    {
        $data = $this->chatModel->getPedidoHebras($pedido_id);
        $notifications = $this->chatModel->builder()->select([
            "chat_notifications.id"
        ])
            ->join("chat_messages", "chat_messages.chat_id = chats.id", "left")
            ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left")
            ->where("chats.pedido_id", $pedido_id)
            ->where("chat_notifications.user_id", auth()->user()->id)
            ->get()->getResultArray();
        foreach ($notifications as $notification) {
            $this->chatNotificationModel->update($notification["id"], ["viewed" => true]);
        }
        return $this->response->setJSON($data);
    }
    public function get_hebra_factura($factura_id)
    {
        $data = $this->chatModel->getFacturaHebras($factura_id);
        $notifications = $this->chatModel->builder()->select([
            "chat_notifications.id"
        ])
            ->join("chat_messages", "chat_messages.chat_id = chats.id", "left")
            ->join("chat_notifications", "chat_notifications.chat_message_id = chat_messages.id", "left")
            ->where("chats.factura_id", $factura_id)
            ->where("chat_notifications.user_id", auth()->user()->id)
            ->get()->getResultArray();
        foreach ($notifications as $notification) {
            $this->chatNotificationModel->update($notification["id"], ["viewed" => true]);
        }
        return $this->response->setJSON($data);
    }

    public function datatable_messages()
    {
        $auth_user_id = auth()->user()->id;
        $query = $this->chatModel->getQueryDatatable($auth_user_id);
        return DataTable::of($query)
            ->edit('created_at', fn($q) => Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i"))
            ->edit('updated_at', fn($q) => Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i"))
            ->add("creator", fn($q) => $this->chatModel->getChatFirstUser($q->id)->userFullName)
            ->add("viewed", fn($q) =>  $this->chatModel->isMessageChatViewed($q->id, $auth_user_id))
            ->add("action", fn($q) => ["type" => "direct","modelId" => $q->id])
            ->toJson(true);
    }
    public function datatable_presupuesto_messages()
    {
        $auth_user_id = auth()->user()->id;
        $query = $this->chatModel->getQueryDatatableMessagePresupuesto($auth_user_id);
        return DataTable::of($query)
            ->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
            ->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
            ->add("creator", fn($q) => $this->chatModel->getChatFirstUser($q->id)->userFullName)
            ->add("viewed", fn($q) =>  $this->chatModel->isMessageChatViewed($q->id, $auth_user_id))
            ->add("action", fn($q) => ["type" => "presupuesto","modelId" => $q->id])
            ->toJson(true);
    }
    public function datatable_pedido_messages()
    {
        $auth_user_id = auth()->user()->id;
        $query = $this->chatModel->getQueryDatatableMessagePedido($auth_user_id);
        return DataTable::of($query)
            ->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
            ->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
            ->add("creator", fn($q) => $this->chatModel->getChatFirstUser($q->id)->userFullName)
            ->add("viewed", fn($q) =>  $this->chatModel->isMessageChatViewed($q->id, $auth_user_id))
            ->add("action", fn($q) => ["type" => "pedido","modelId" => $q->id])

            ->toJson(true);
    }
    public function datatable_factura_messages()
    {
        $auth_user_id = auth()->user()->id;
        $query = $this->chatModel->getQueryDatatableMessageFactura($auth_user_id);
        return DataTable::of($query)
            ->edit('created_at', fn($q) => $q->created_at ? Time::createFromFormat('Y-m-d H:i:s', $q->created_at)->format("d/m/Y H:i") : "")
            ->edit('updated_at', fn($q) => $q->updated_at ? Time::createFromFormat('Y-m-d H:i:s', $q->updated_at)->format("d/m/Y H:i") : "")
            ->add("creator", fn($q) => $this->chatModel->getChatFirstUser($q->id)->userFullName)
            ->add("viewed", fn($q) =>  $this->chatModel->isMessageChatViewed($q->id, $auth_user_id))
            ->add("action", fn($q) => ["type" => "factura","modelId" => $q->id])

            ->toJson(true);
    }
    public function store_new_direct_message()
    {
        $bodyData = $this->request->getPost();
        $rules = [
            "title" => "required|string",
            "message" => "required|string",
            "users" => "required",

        ];
        if (!$this->validate($rules)) {
            return $this->response->setStatusCode(400)->setJSON([
                'message' => lang('App.global_alert_save_error'),
                'status' => 'error',
                'errors' => $this->validator->getErrors(),
            ]);
        }
        $this->chatModel->createNewDirectChat(...$bodyData);
        return $this->response->setJSON(["message" => lang("Chat.new_message_ok"), "status" => true]);
    }
    public function store_new_direct_message_client()
    {
        $bodyData = $this->request->getPost();
        $rules = [
            "title" => "required|string",
            "message" => "required|string",
            "chat_department_id" => "required",

        ];
        if (!$this->validate($rules)) {
            return $this->response->setStatusCode(400)->setJSON([
                'message' => lang('App.global_alert_save_error'),
                'status' => 'error',
                'errors' => $this->validator->getErrors(),
            ]);
        }
        $users = $this->chatDeparmentModel->getChatDepartmentUsers($bodyData["chat_department_id"]);
        $bodyData["users"] = array_map(fn($q) => $q->id,$users);
        dd(1);
        $this->chatModel->createNewDirectChat(...$bodyData);
        return $this->response->setJSON(["message" => lang("Chat.new_message_ok"), "status" => true]);
    }
    public function get_chat_direct($chat_id)
    {
        $chatData = $this->chatModel->getChatDirect($chat_id);
        return $this->response->setJSON($chatData);
    }
    public function get_chat_direct_select_users($chat_id)
    {
        $chat_users_id = $this->chatUserModel->getChatUserArrayId($chat_id);

        $query = $this->userModel->builder()->select(
            [
                "id",
                "CONCAT(first_name,' ',last_name,'(',username,')') as name"
            ]
        )
            ->where("deleted_at", null)
            ->whereNotIn("id", $chat_users_id);
        if ($this->request->getGet("q")) {
            $query->groupStart()
                ->orLike("users.username", $this->request->getGet("q"))
                ->orLike("CONCAT(first_name,' ',last_name)", $this->request->getGet("q"))
                ->groupEnd();
        }

        return $this->response->setJSON($query->get()->getResultObject());
    }
    public function store_chat_direct_users($chat_id)
    {
        $bodyData = $this->request->getPost();
        $chat_users = [];
        foreach ($bodyData["users"] as $user_id) {
            $chat_users[] = ["chat_id" => $chat_id, "user_id" => $user_id];
            if ($bodyData["notification"]) {
                $this->chatModel->createNotificationsToNewChatUser($chat_id, $user_id);
            }
        }
        $this->chatUserModel->insertBatch($chat_users);
        return $this->response->setJSON(["message" => "ok", "status" => true]);
    }
    public function store_chat_direct_message(int $chat_id)
    {
        $bodyData = $this->request->getPost();
        $auth_user = auth()->user();
        $bodyData["sender_id"] =  $auth_user->id;
        $chat_message_id = $this->chatMessageModel->insert($bodyData);
        $users_id = $this->chatUserModel->getChatUserArrayId($chat_id);
        foreach ($users_id as $user_id) {
            if ($user_id != $auth_user->id) {
                $this->chatNotificationModel->insert(["chat_message_id" => $chat_message_id, "user_id" => $user_id]);
            }
        };
        $message = $this->chatMessageModel->get_chat_message($chat_message_id);
        return $this->response->setJSON($message);
    }
    public function update_chat_direct_message_unread($chat_id)
    {
        $this->chatModel->setAsUnviewedChatUserNotifications($chat_id, auth()->user()->id);
        return $this->response->setJSON(["message" => "ok", "status" => true]);
    }
}
