<?php

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

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

    // Reminder - intl extension MUST be enabled for transliterator_transliterate() function to work

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

    // Retrieves all entries in the topic, topic name is needed
    public function GetEntries($topic) {
        // Checks if topic exists
        $db = Database::connect();
        $topic_id = $db->query('CALL get_topic_id('.$db->escape($topic).')')->getResult();
        if (empty($topic_id)) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Checks permissions
        $test = new TransferController();
        if ($test->CheckUserReadPermissions($topic) == false) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Gets all entries related to that topic
        $query = $db->query('CALL get_entries_by_topic('.$db->escape($topic_id[0]->id).')')->getResult();
        // Prepares data and sends it
        $responses = [];
        if (!empty($query)) {
            foreach ($query as $row) {
                $responses[] = [
                    "name" => $row->name,
                    "title" => $row->title,
                    "created_at" => $row->created_at,
                    "edited_at" => $row->edited_at
                ];
            }
        }
        return $this->respond(esc($responses), 200);
    }

    // Retrieves a certain entry, entry name is needed
    public function GetEntry() {
        // Checks given data
        if (empty($this->request->getGet())) {
            return $this->fail(["error" => "Where data?"], 400);
        }
        // Checks permissions
        $test = new TransferController();
        if ($test->CheckUserReadPermissions($this->request->getGet("topic")) == false) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Checks if entry exists
        $db = Database::connect();
        $query = $db->query('CALL get_entry('.$db->escape($this->request->getGet("topic")).', '.$db->escape(explode("#", $this->request->getGet("entry_name"))[0]).')')->getResult();
        if (empty($query)) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Prepares data and sends it
        $responses = [];
        foreach ($query as $row) {
            $responses[] = [
                "id" => $row->id,
                "title" => $row->title,
                "content" => $row->content,
                "created_at" => $row->created_at,
                "edited_at" => $row->edited_at,
            ];
        }
        return $this->respond(esc($responses), 200);
    }

    // Create a new or updates already existing entry, entry id is needed
    public function PostEntry($id) {
        // Checks posted data
        if (empty($this->request->getPost())) {
            return $this->fail(["error" => "Where data?", "csrfHash" => csrf_hash()], 400);
        }
        // If the entry's id exists, then the entry will get updated, otherwise created/inserted
        $db = Database::connect();
        $test = new PermissionController();
        $perms = $test->GetUserPermissions($this->request->getPost("topic"));
        if (!empty($id)) {
            // Checks permissions
            if (!empty($perms)) {
                if ($perms["edit_entries"] == false && $perms["owner"] == false) {
                    return $this->fail(["error" => "You don't have the permission to do this!", "csrfHash" => csrf_hash()], 403);
                }
            }
            else {
                return $this->fail(["error" => "You don't have the permission to do this!", "csrfHash" => csrf_hash()], 403);
            }
            // Prepares data for updating
            $str = transliterator_transliterate('Any-Latin; Latin-ASCII;', $this->request->getPost("name"));
            $sendData = [
                "name" => strtolower(preg_replace('/[^a-zA-Z0-9\-_]/', '', $str)),
                "title" => $this->request->getPost("title"),
                "content" => $this->request->getPost("content")
            ];
        }
        else {
            // Checks permissions
            if (!empty($perms)) {
                if ($perms["create"] == false && $perms["owner"] == false) {
                    return $this->fail(["error" => "You don't have the permission to do this!", "csrfHash" => csrf_hash()], 403);
                }
            }
            else {
                return $this->fail(["error" => "You don't have the permission to do this!", "csrfHash" => csrf_hash()], 403);
            }
            // Checks if topic exists
            $query = $db->query('CALL get_topic_id('.$db->escape($this->request->getPost("topic")).')')->getResult();
            if (empty($query)) {
                return $this->fail(["error" => "Not found!"], 404);
            }
            // Prepares data for insertion
            $str = transliterator_transliterate('Any-Latin; Latin-ASCII;', $this->request->getPost("name"));
            $sendData = [
                "topic_id" => $query[0]->id,
                "name" => strtolower(preg_replace('/[^a-zA-Z0-9\-_]/', '', $str)),
                "title" => $this->request->getPost("title"),
                "content" => $this->request->getPost("content")
            ];
        }
        // Checks if the title or name isn't empty
        if (strlen($sendData["title"]) == 0 || strlen($sendData["name"]) == 0) {
            return $this->fail(["error" => "Title was found empty! Do not use any HTML tags!", "csrfHash" => csrf_hash()], 406);
        }
        if (!empty($id)) {
            // Updates
            $db->query('CALL put_entry('.$db->escape(json_encode($sendData)).', '.$db->escape($id).')');
            return $this->respond(["message" => "Updated successfully!", "redirect" => $sendData["name"], "csrfHash" => csrf_hash()], 200);
        }
        // Creates
        $db->query('CALL post_entry('.$db->escape(json_encode($sendData)).')');
        return $this->respond(["message" => "Created successfully!", "redirect" => $sendData["name"], "csrfHash" => csrf_hash()], 201);
    }

    // Deletes entry, entry id is needed
    public function DeleteEntry($id = null) {
        // Checks given data
        if (empty($id)) {
            return $this->fail(["error" => "Where data?", "csrfHash" => csrf_hash()], 400);
        }
        // Checks permissions
        $test = new PermissionController();
        $perms = $test->GetUserPermissions($this->request->getRawInput()["topic"]);
        if (!empty($perms)) {
            if ($perms["delete_files"] == true || $perms["owner"] == true) {
                // "Deletes" entry
                $db = Database::connect();
                $db->query('CALL delete_entry('.$db->escape($id).')');
                return $this->respond(["message" => "Deleted successfully!", "csrfHash" => csrf_hash()], 200);
            }
        }
        return $this->fail(["error" => "You don't have the permission to do this!", "csrfHash" => csrf_hash()], 403);
    }

    // Returns search results
    public function SearchFunction() {
        // Checks get data
        if (empty($this->request->getGet())) {
            return $this->fail(["error" => "Where data?"], 400);
        }
        // Checks permissions
        $test = new TransferController();
        if ($test->CheckUserReadPermissions($this->request->getGet("topic")) == false) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Checks if topic exists
        $db = Database::connect();
        $topic_id = $db->query('CALL get_topic_id('.$db->escape($this->request->getGet("topic")).')')->getResult();
        if (empty($topic_id)) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Gets the searched value
        $params = urldecode($this->request->getGet("param"));
        // Finds any existing entries that have a similar title to searched value
        $responses = [];
        $query = $db->query('CALL search_data('.$db->escape($params).','.$topic_id[0]->id.')');
        // Prepares data
        foreach ($query->getResult() as $row) {
            $responses[] = [
                "name" => $row->name,
                "title" => $row->title
            ];
        }
        return $this->respond(esc($responses), 200);
    }
}