<?php

namespace App\Controllers;
use Config\Database;
use CodeIgniter\RESTful\ResourceController;

class EntryController extends ResourceController
{
    /*
        Created: 2025-02-27
        Author: Kārlis Grīnvalds
        Last edited: 2025-11-25
        Edited by: Kārlis Grīnvalds
    */

    // Used for getting all or specific entries; Also for creating, editing or deleting an entry

    /* ENTRY FUNCTIONS */

    // Retrieves all entries in the topic, function parameter is topic name
    public function GetEntries($name = null) {
        $db = Database::connect();
        $topic_id = $db->query('CALL get_topic_id('.$db->escape($name).')')->getResult();
        if (empty($topic_id)) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        $query = $db->query('CALL get_entries_by_topic('.$db->escape($topic_id[0]->id).')');
        $responses = [];
        if (!empty($query)) {
            foreach ($query->getResult() as $row) {
                $responses[] = [
                    "id" => $row->id,
                    "title" => $row->title,
                    "created_at" => $row->created_at,
                    "edited_at" => $row->edited_at
                ];
            }
        }
        return $this->respond($responses, 200);
    }

    // Retrieves a certain entry, function parameter is entry id
    public function GetEntry($id = null) {
        $db = Database::connect();
        // Checks if the ID is given
        if (empty($id)) {
            return $this->fail(["error" => "Where data?"], 400);
        }
        // Gets a certain entry and checks if it was retrieved / it exists
        $query = $db->query('CALL get_entry('.$db->escape($id).')');
        if (empty($query)) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Prepares data
        $responses = [];
        foreach ($query->getResult() as $row) {
            $responses[] = [
                "id" => $row->id,
                "title" => $row->title,
                "content" => $row->content,
                "created_at" => $row->created_at,
                "edited_at" => $row->edited_at,
            ];
        }
        // Returns entry data
        return $this->respond($responses, 200);
    }

    // Create a new or updates already existing entry, function parameter is entry id
    public function PostEntry($id = null) {
        $db = Database::connect();
        $item = []; // To get the user's id from session data
        // Checks if the user is logged in. If not, then this function doesn't continue
        $session = service("session");
        if ($session->has("userdata")) {
            $item = $session->get("userdata")->id;
            $session->close();
        }
        else {
            $session->close();
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Checks if posted data exists
        if (empty($this->request->getPost())) {
            return $this->fail(["error" => "Where data?"], 400);
        }
        // If the entry's id exists, then the entry will get updated, otherwise created/inserted
        if (!empty($id)) {
            // Checks if the entry exists
            $query = $db->query('CALL get_entry_user_id('.$db->escape($id).')')->getResult()[0];
            if ($query->user_id != $item) {
                return $this->fail(["error" => "Not found!"], 404);
            }
            // Prepares data for updating
            $sendData = [
                "title" => $this->request->getPost("title"),
                "content" => $this->request->getPost("content")
            ];
        }
        else {
            $query = $db->query('CALL get_topic_id('.$db->escape($this->CleanTitle($this->request->getPost("topic"))).')')->getResult()[0];
            if (empty($query)) {
                return $this->fail(["error" => "Not found!"], 404);
            }
            // Prepares data for insertion
            $sendData = [
                "topic_id" => $query->id,
                "user_id" => $this->request->getPost("user"),
                "title" => $this->request->getPost("title"),
                "content" => $this->request->getPost("content")
            ];
        }
        // Checks if the title isn't empty
        if (strlen($sendData["title"]) == 0) {
            return $this->fail(["error" => "Title was found empty! Do not use any HTML tags!"], 406);
        }
        if (!empty($id)) {
            $db->query('CALL put_entry('.$db->escape(json_encode($sendData)).', '.$db->escape($id).')');
            return $this->respond(["message" => "Updated successfully!"], 200);
        }
        $db->query('CALL post_entry('.$db->escape(json_encode($sendData)).')');
        return $this->respond(["message" => "Created successfully!"], 201);
    }

    // Deletes an entry, function parameter is entry id
    public function DeleteEntry($id = null) {
        $db = Database::connect();
        // Checks if the ID is given
        if (empty($id)) {
            return $this->fail(["error" => "Where data?"], 400);
        }
        // Checks if the user is logged in and is the owner of the entry. If not, then the entry doesn't get deleted
        $session = service("session");
        if ($session->has("userdata")) {
            $item = $session->get("userdata")->id;
            $session->close();
            $query = $db->query('CALL get_entry_user_id('.$db->escape($id).')')->getResult()[0];
            if ($query->user_id != $item) {
                return $this->fail(["error" => "Not found!"], 404);
            }
        }
        else {
            $session->close();
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Deletes the entry
        $db->query('CALL delete_entry("'.strval($id).'")');
        return $this->respond(["message" => "Deleted successfully!"], 200);
    }

    // Checks if the user can edit the entry, parameters needs entry id
    public function AllowToEdit($entry_id = null) {
        if (empty($entry_id)) {
            return $this->respond(false, 200);
        }
        $session = service("session");
        $item = ["message" => "User not logged in!"];
        if ($session->has("userdata")) {
            $item = $session->get("userdata");
        }
        else {
            return $this->respond(false, 200);
        }
        $session->close();
        $db = Database::connect();
        $query = $db->query('CALL user_allowed('.$db->escape($item->id).', '.$db->escape($entry_id).')')->getResult();
        if (empty($query)) {
            return $this->respond(false, 200);
        }
        return $this->respond(true, 200);
    }

    // Gets the search results
    public function SearchFunction() {
        $db = Database::connect();
        // Checks if the posted (GET) data exists
        if (empty($this->request->getGet())) {
            return $this->fail(["error" => "Where data?"], 400);
        }
        // Gets the searched value
        $params = explode(" ", urldecode($this->request->getGet("param")));
        // Finds any existing entries that have a similar title to searched value
        $responses = [];
        foreach ($params as $param) {
            $query = $db->query('CALL search_data('.$db->escape($param).')');
            if (empty($query)) {
                continue;
            }
            // Prepares data
            foreach ($query->getResult() as $row) {
                $responses[] = [
                    "id" => $row->id,
                    "title" => $row->title
                ];
            }
        }
        $result = [];
        $checkIds = [];
        foreach ($responses as $response) {
            if (!in_array($response["id"], $checkIds)) {
                $checkIds[] = $response["id"];
                $result[] = $response;
            }
        }
        return $this->respond($result, 200);
    }
}