<?php

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

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

    // Retrieves a certain topic, topic name is needed
    public function GetTopic($topic) {
        // Checks given data
        if (empty($topic)) {
            return $this->fail(["error" => "Where data?"], 400);
        }
        // Checks permissions
        $test = new TransferController();
        if ($test->CheckUserReadPermissions($topic) == false) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        $db = Database::connect();
        // Checks if topic exists
        $query = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
        if (empty($query)) {
            return $this->fail(["error" => "Not found!"], 404);
        }
        // Prepares topic data
        $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);
    }

    // Retrieves all public topics
    public function GetPublicTopics() {
        $db = Database::connect();
        // Gets all topics
        $query = $db->query('CALL get_public_topics()')->getResult();
        // Prepares topic data
        $responses = [];
        foreach ($query as $row) {
            $responses[] = [
                "id" => $row->id,
                "name" => $row->name,
                "title" => $row->title
            ];
        }
        return $this->respond(esc($responses), 200);
    }

    // Creates a new topic
    public function CreateTopic() {
        // Checks user's session data
        $item = null;
        $session = service("session");
        if ($session->has("userdata")) {
            $item = $session->get("userdata")->id;
            $session->close();
        }
        else {
            $session->close();
            return $this->fail(["error" => "User not found!", "csrfHash" => csrf_hash()], 404);
        }
        // Checks posted data
        if (empty($this->request->getPost())) {
            return $this->fail(["error" => "No data given!", "csrfHash" => csrf_hash()], 404);
        }
        // Connects to database
        $db = Database::connect();
        // Generates a random name for the topic
        for ($_ = 0; $_ < 10; $_++) {
            $baseString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            $topicName = substr(str_shuffle($baseString), 0, 12);
            $query = $db->query('CALL get_topic_by_name('.$db->escape($topicName).')')->getResult();
            if (empty($query)) {
                break;
            }
            if ($_ >= 9) {
                return $this->fail(["error" => "Something gone wrong with the server. Please, try again!", "csrfHash" => csrf_hash()], 500);
            }
        }
        // Prepares topic data for insert
        $response = array_values((array) $db->query('SELECT post_topic('.$db->escape($item).', '.$db->escape($topicName).', '.$db->escape($this->request->getPost("title")).')')->getResult()[0])[0];
        return $this->respond(["name" => $response, "csrfHash" => csrf_hash()], 201);
    }

    // Updates topic, topic name is needed
    public function UpdateTopic($topic) {
        // Checks given data
        if (empty($topic)) {
            return $this->fail(["error" => "Topic name not given!", "csrfHash" => csrf_hash()], 400);
        }
        if (empty($this->request->getPost())) {
            return $this->fail(["error" => "Input fields are empty!", "csrfHash" => csrf_hash()], 400);
        }
        // Checks permissions
        $test = new PermissionController();
        $perms = $test->GetUserPermissions($topic);
        if (!empty($perms)) {
            if ($perms["edit_topic"] == 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
        $sendData = [
            "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!", "csrfHash" => csrf_hash()], 406);
        }
        $db = Database::connect();
        $db->query('CALL put_topic('.$db->escape(json_encode($sendData)).', '.$db->escape($topic).')');
        return $this->respond(["message" => "Updated successfully!", "csrfHash" => csrf_hash()], 200);
    }

    // Retrieves topics in which user has special access, permissions and ownership
    public function GetTopicPermissions() {
        // Gets user id
        $id;
        $session = service("session");
        if ($session->has("userdata")) {
            $id = $session->get("userdata")->id;
            $session->close();
        }
        else {
            $session->close();
            return $this->fail(["error" => "User not found!"], 404);
        }
        // Gets topics which the user has permissions
        $db = Database::connect();
        $query = $db->query('CALL get_permissions_topics('.$db->escape($id).')')->getResult();
        // Prepares data and sends
        $response = [];
        foreach ($query as $row) {
            $response[] = [
                "t_name" => $row->t_name,
                "t_title" => $row->t_title,
                "t_public" => $row->t_public,
                "t_owner" => ($row->t_owner == $id) ? true : false,
                "permissions" => [
                    "read" => ($row->read == 1) ? "can visit the topic" : "",
                    "create" => ($row->create == 1) ? "can create entries" : "",
                    "upload" => ($row->upload == 1) ? "can upload files" : "",
                    "edit_entries" => ($row->edit_entries == 1) ? "can edit entries" : "",
                    "edit_files" => ($row->edit_files == 1) ? "can edit uploaded files" : "",
                    "edit_topic" => ($row->edit_topic == 1) ? "can edit topic's main page" : "",
                    "delete_entries" => ($row->delete_entries == 1) ? "can delete entries" : "",
                    "delete_files" => ($row->delete_files == 1) ? "can delete uploaded files" : "",
                ]
            ];
        }
        return $this->respond(esc($response), 200);
    }
}