<?php

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

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

    // Used for viewing certain HTML files on the website

    // Index page
    public function Index() {
        $viewData = [
            "BodyParts" => view("partials/body_parts"),
        ];
        return view("index", $viewData);
    }

    // Create account page
    public function ViewCreateAccountPage() {
        return $this->RedirectUser("index", "create_account");
    }

    // Log in page
    public function ViewLogInPage() {
        return $this->RedirectUser("index", "log_in");
    }

    // Topic form page
    public function ViewTopicFormPage() {
        return $this->RedirectUser("topic_form", "log_in");
    }

    // User settings page
    public function ViewUserPage() {
        return $this->RedirectUser("user_settings", "log_in");
    }

    // Admin panel page, topic name is needed
    public function AdminPanel($topic) {
        // Checks given data
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        // Checks user's session data
        $session = $this->CheckSession();
        if ($session["hasSession"]) {
            $db = Database::connect();
            $query = $db->query('CALL get_permission_read('.$db->escape($topic).', '.$db->escape($session["id"]).')')->getResult();
            if (!empty($query)) {
                if ($query[0]->owner == $session["id"]) {
                    $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
                    $viewData = [
                        "BodyParts" => view("partials/body_parts"),
                        "Title" => "Admin panel | ".esc($topicTitle[0]->title)." Wiki"
                    ];
                    return view("admin_panel", $viewData);
                }
            }
        }
        return view("errors/error404.html");
    }

    // Entry list page
    public function EntriesPage($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == true) {
            $db = Database::connect();
            $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
            $viewData = [
                "BodyParts" => view("partials/body_parts"),
                "Title" => "Entries | ".esc($topicTitle[0]->title)." Wiki"
            ];
            return view("entries", $viewData);
        }
        return view("errors/error404.html");
    }

    // File list page
    public function FilesPage($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == true) {
            $db = Database::connect();
            $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
            $viewData = [
                "BodyParts" => view("partials/body_parts"),
                "Title" => "Files | ".esc($topicTitle[0]->title)." Wiki"
            ];
            return view("files", $viewData);
        }
        return view("errors/error404.html");
    }

    // Search result page
    public function SearchPage($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == true) {
            $db = Database::connect();
            $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
            $viewData = [
                "BodyParts" => view("partials/body_parts"),
                "Title" => "Search results | ".esc($topicTitle[0]->title)." Wiki"
            ];
            return view("search", $viewData);
        }
        return view("errors/error404.html");
    }

    // File upload page
    public function FileUploadPage($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == true) {
            $test = new PermissionController();
            $perms = $test->GetUserPermissions($topic);
            if (!empty($perms)) {
                if ($perms["create"] == true || $perms["owner"] == true) {
                    $db = Database::connect();
                    $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
                    $viewData = [
                        "BodyParts" => view("partials/body_parts"),
                        "Title" => "File upload | ".esc($topicTitle[0]->title)." Wiki"
                    ];
                    return view("upload_file", $viewData);
                }
            }
        }
        return view("errors/error404.html");
    }

    // Create entry page
    public function CreateEntryPage($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == true) {
            $test = new PermissionController();
            $perms = $test->GetUserPermissions($topic);
            if (!empty($perms)) {
                if ($perms["create"] == true || $perms["owner"] == true) {
                    $db = Database::connect();
                    $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
                    $viewData = [
                        "BodyParts" => view("partials/body_parts"),
                        "Title" => "New entry | ".esc($topicTitle[0]->title)." Wiki"
                    ];
                    return view("create_entry", $viewData);
                }
            }
        }
        return view("errors/error404.html");
    }

    // Topic view and edit page, topic name is needed
    public function ViewTopic($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == false) {
            return view("errors/error404.html");
        }
        // Checks whether the user want's to edit the topic
        $info = explode("/Page:Main", $_SERVER["REQUEST_URI"])[1];
        $db = Database::connect();
        $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
        $viewData = [
            "BodyParts" => view("partials/body_parts"),
        ];
        if (strlen($info) > 0) {
            if ($info == "?a=edit") {
                $test = new PermissionController();
                $perms = $test->GetUserPermissions($topic);
                if (!empty($perms)) {
                    if ($perms["edit_topic"] == true || $perms["owner"] == true) {
                        $viewData["Title"] = "Editing ".esc($topicTitle[0]->title)." Wiki";
                        return view("edit_topic", $viewData);
                    }
                }
            }
        }
        $viewData["ImageViewer"] = view("partials/image_gallery");
        $viewData["Title"] = esc($topicTitle[0]->title)." Wiki";
        return view("topic", $viewData);
    }

    // File view and edit page
    public function ViewFile($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == false) {
            return view("errors/error404.html");
        }
        // Retrieves file name
        $info = explode("/File:", $_SERVER["REQUEST_URI"])[1];
        $action = explode("?a=", $info);
        $file = $action[0];
        if (sizeof($action) == 2) {
            $action = $action[1];
        }
        // Checks for existing file entry
        $db = Database::connect();
        $query = $db->query('CALL get_file('.$db->escape($file).')')->getResult();
        if (empty($query)) {
            return view("errors/error404.html");
        }
        // Check for user action
        $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
        $viewData = [
            "BodyParts" => view("partials/body_parts"),
        ];
        if ($action == "edit") {
            $test = new PermissionController();
            $perms = $test->GetUserPermissions($topic);
            if (!empty($perms)) {
                if ($perms["edit_files"] == true || $perms["owner"] == true) {
                    $viewData["Title"] = "Editing ".esc($query[0]->given)." | ".esc($topicTitle[0]->title)." Wiki";
                    return view("edit_file", $viewData);
                }
            }
        }
        $viewData["Title"] = esc($query[0]->given)." | ".esc($topicTitle[0]->title)." Wiki";
        return view("file", $viewData);
    }

    // Entry view and edit page
    public function ViewEntry($topic) {
        if ($this->CheckTopic($topic) == false) {
            return view("errors/error404.html");
        }
        if ($this->CheckUserReadPermissions($topic) == false) {
            return view("errors/error404.html");
        }
        // Retrieves entry name
        $info = explode("/", $_SERVER["REQUEST_URI"])[2];
        $action = explode("?a=", $info);
        $entry = $action[0];
        if (sizeof($action) == 2) {
            $action = $action[1];
        }
        // Checks for existing entry
        $db = Database::connect();
        $query = $db->query('CALL get_entry('.$db->escape($topic).', '.$db->escape($entry).')')->getResult();
        if (empty($query)) {
            return view("errors/error404.html");
        }
        // Check for user action
        $topicTitle = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
        $viewData = [
            "BodyParts" => view("partials/body_parts"),
        ];
        if ($action == "edit") {
            $test = new PermissionController();
            $perms = $test->GetUserPermissions($topic);
            if (!empty($perms)) {
                if ($perms["edit_entries"] == true || $perms["owner"] == true) {
                    $viewData["Title"] = "Editing ".esc($query[0]->title)." | ".esc($topicTitle[0]->title)." Wiki";
                    return view("edit_entry", $viewData);
                }
            }
        }
        $viewData["ImageViewer"] = view("partials/image_gallery");
        $viewData["Title"] = esc($query[0]->title)." | ".esc($topicTitle[0]->title)." Wiki";
        return view("entry", $viewData);
    }

    // Error page
    public function ErrorPage() {
        return view("errors/error404.html");
    }

    // Checks user's session data
    function CheckSession() {
        $session = service("session");
        $hasSession = false;
        $id = 0;
        if ($session->has("userdata")) {
            $hasSession = true;
            $id = $session->get("userdata")->id;
        }
        $session->close();
        return ["hasSession" => $hasSession, "id" => $id];
    }

    // Shows the user the page - path1 is if the user has an active session while path2 is not
    function RedirectUser($path1, $path2) {
        $viewData = [
            "BodyParts" => view("partials/body_parts"),
        ];
        // Checks user session data
        $session = $this->CheckSession();
        if ($session["hasSession"]) {
            return view($path1, $viewData);
        }
        return view($path2, $viewData);
    }

    // Checks if the given topic exists - needs topic name
    function CheckTopic($topic) {
        if (empty($topic)) {
            return false;
        }
        $db = Database::connect();
        $query = $db->query('CALL get_topic_by_name('.$db->escape($topic).')')->getResult();
        if (empty($query)) {
            return false;
        }
        return true;
    }

    // Checks if the user can view a certain page
    function CheckUserReadPermissions($topic) {
        $session = $this->CheckSession();
        $db = Database::connect();
        $query = $db->query('CALL get_permission_read('.$db->escape($topic).', '.$db->escape($session["id"]).')')->getResult();
        if (!empty($query)) {
            if ($query[0]->owner == $session["id"]) {
                return true;
            }
            if ($query[0]->public == 1 && $session["hasSession"] == false) {
                return true;
            }
            if (($query[0]->read == 1 || $query[0]->read !== 0) && $session["hasSession"] == true) {
                return true;
            }
        }
        return false;
    }
}