<?php namespace App\Controllers;

use App\Controllers\BaseController;
use App\Models\ThreadModel;
use App\Models\MessageModel;
use App\Models\UserModel;
class MessagesController extends BaseController
{
	protected $threadModel;
    protected $messageModel;

	protected $userModel;

	public function __construct()
    {
        $this->threadModel = new ThreadModel();
        $this->messageModel = new MessageModel();
		$this->userModel = new UserModel();
    }

    public function createNewThread($userId)
    {

        $session = session();
		$usr = session()->get('id');
        if (!$usr>0) 
		{
	     $this->response->redirect(site_url('/login'));
		  exit;
        }


        $thread = $this->threadModel->getThread($usr, $userId);

        if ($thread) {
            $threadId = $thread['id'];
        }
        else{
            $threadId = $this->threadModel->insert([
                'sender_id' => $usr,
                'receiver_id' => $userId,
            ]);

        }

        
        $this->response->redirect(site_url('/messages/'.$threadId));
    }

	public function index($threadId = null)
	{
		$session = session();
		$usr = session()->get('id');
        if (!$usr>0) 
		{
	     $this->response->redirect(site_url('/login'));
		  exit;
        }


		// Fetch all threads involving the user
        $threads = $this->threadModel
            ->where('sender_id', $usr)
            ->orWhere('receiver_id', $usr)
            ->orderBy('created_at', 'DESC')
            ->findAll();

        // Format thread data for the view (e.g., showing the latest message in each thread)
        $formattedThreads = [];
        foreach ($threads as $thread) {
            $otherUserId = ($thread['sender_id'] == $usr) ? $thread['receiver_id'] : $thread['sender_id'];
            $latestMessage = $this->messageModel->where('thread_id', $thread['id'])
                ->orderBy('created_at', 'DESC')
                ->first();

			$otherUser = $this->userModel->where('id', $otherUserId)->first();
			$otherUserName = $otherUser['lastname'] . ' ' . $otherUser['firstname'];
            $unreadMessages = $this->messageModel->where('thread_id', $thread['id'])
                ->where('sender_id !=', $usr)
                ->where('status', 'unread')
                ->countAllResults();

            $formattedThreads[] = [
                'thread_id' => $thread['id'],
                'other_user_id' => $otherUserId,
                'latest_message' => $latestMessage['message'] ?? '',
                'latest_message_time' => $latestMessage['created_at'] ?? '',
                'status' => $latestMessage['status'] ?? 'read',
                'unread_messages' => $unreadMessages ?? 0,
				'other_user_name' => $otherUserName,
            ];
        }


        // Check if a specific thread should be opened by default
        if(isset($threadId)) {

            // Check if user is part of the thread
            // Validation is needed in case of malicious attempts with url paths
            if ($this->threadModel->isParticipant($threadId, $usr)) {
                return view('messages/index', ['threads' => $formattedThreads, 'active_thread' => $threadId]);
            }

        }

        // Pass the data to the view
        return view('messages/index', ['threads' => $formattedThreads]);
        
	}


	public function viewThreads()
    {
        $userId = session()->get('id');
        $threads = $this->threadModel
            ->select('threads.*, COUNT(CASE WHEN messages.status = "unread" THEN 1 END) as unread_messages')
            ->join('messages', 'threads.id = messages.thread_id', 'left')
            ->where('threads.sender_id', $userId)
            ->orWhere('threads.receiver_id', $userId)
            ->groupBy('threads.id')
            ->orderBy('threads.created_at', 'DESC')
            ->where('sender_id', $userId)
            ->orWhere('receiver_id', $userId)
            ->orderBy('created_at', 'DESC')
            ->findAll();

        return view('messages/threads', ['threads' => $threads]);
    }

    public function viewMessages($threadId)
    {
        $userId = session()->get('id');

        // Fetch messages in the thread
        $messages = $this->messageModel->getMessagesByThread($threadId);

        // Mark all messages as read
        $this->messageModel->markAllAsRead($threadId, $userId);

        return view('messages/conversation', ['messages' => $messages, 'threadId' => $threadId]);
    }


	public function getMessages()
{
    if ($this->request->isAJAX()) {
        $threadId = $this->request->getGet('thread_id');
        $messages = $this->messageModel->where('thread_id', $threadId)
            ->orderBy('created_at', 'ASC')
            ->findAll();

        $otherUserId = $this->threadModel->getOtherUserId($threadId, session()->get('id'));

		$otherUser = $this->userModel->where('id', $otherUserId)->first();
		$otherUserName = $otherUser['lastname'] . ' ' . $otherUser['firstname'];

        // Mark all messages as read
        $this->messageModel->markAllAsRead($threadId, session()->get('id'));

        return $this->response->setJSON([
            'status' => 'success',
            'messages' => $messages,
            'other_user_id' => $otherUserId,
            'current_user_id' => session()->get('id'),
			'other_user_name' => $otherUserName,
        ]);
    }
    return $this->response->setStatusCode(400, 'Bad Request');
}


	public function sendMessage()
	{
		if ($this->request->isAJAX()) {
			$data = $this->request->getPost();
	
			// Validation
			$validation = \Config\Services::validation();
			$validation->setRules([
				'thread_id' => 'required|integer',
				'message' => 'required|min_length[1]|max_length[1000]'
			]);
	
			if (!$validation->run($data)) {
				return $this->response->setJSON([
					'status' => 'error',
					'errors' => $validation->getErrors()
				]);
			}
	
			$senderId = session()->get('id');
			$threadId = $data['thread_id'];
	
			// Save the message
			$this->messageModel->save([
				'thread_id' => $threadId,
				'sender_id' => $senderId,
				'message' => $data['message']
			]);
	
			// Fetch the newly added message for the response
			$newMessage = $this->messageModel->where('thread_id', $threadId)
				->orderBy('created_at', 'DESC')
				->first();
	
			return $this->response->setJSON([
				'status' => 'success',
				'message' => $newMessage
			]);
		}
	
		// If not an AJAX request, return a 400 Bad Request
		return $this->response->setStatusCode(400, 'Bad Request');
	}
	
}
