<?php
include 'k-api.php';

// CHANGE THIS
const ADMIN_PASS = "superdengipassword4";

const API_PATH = "./";

function db()
{
    $pdo = new PDO('sqlite:' . API_PATH . 'data.db');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $pdo;
};


function relativePathToUrl(string $rel)
{
    $parts = explode('/', dirname($_SERVER['SCRIPT_NAME']) . '/' . $rel);
    $norm = [];
    foreach ($parts as $p) {
        if ($p === '..' && $norm) array_pop($norm);
        elseif ($p && $p !== '.') $norm[] = $p;
    }
    $proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
    return $proto . '://' . $_SERVER['HTTP_HOST'] . '/' . implode('/', $norm);
}


function FastDBReq(PDO $db, string $sql, array $params = []): array
{   
    try {
        $stmt = $db->prepare($sql);
        $stmt->execute($params);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        throw $e;
    }
}

function Login(mixed $req)
{
    return isset($req->data['pass']) && $req->data['pass'] == ADMIN_PASS;
}

CreateApi(function ($api) {
    $api->on('/', 'GET', function ($req) {
        return 'hi';
    });
    $api->on('/phpliteadmin', 'GET', function () {
        header('Location:  ./adm/phpliteadmin.php');
        return "";
    });
    $api->on('/login', 'POST', function ($req) {
        if (!isset($req->data['pass'])) {
            $req->res->code(401);
            return 'bad data';
        }
        if ($req->data['pass'] == ADMIN_PASS) {
            return true;
        }
        return false;
    });
    $api->on('/class', 'POST', function ($req) {
        if (!Login($req)) {
            $req->res->code(401);
            return ['ok' => "auth_fail"];
        }
        $db = db();
        if (isset($req->data['classId'])) {
            $classId = $req->data['classId'];
            if (isset($req->data['action'])) {
                switch ($req->data['action']) {
                    // actions
                    case "update_name":
                        try {
                            if (!isset($req->data['value'])) {
                                $req->res->code(400);
                                return "bad data";
                            }
                            $value = trim($req->data['value']);
                            if (strlen($value) == 0) {
                                $req->res->code(400);
                                return "bad data";
                            }
                            FastDBReq($db, "UPDATE classes SET userclassname = ? WHERE classid=?", [$value, $classId]);
                            return true;
                        } catch (PDOException $e) {
                            error_log($e);
                            return "егор";
                        }
                        break;
                    case 'create_admin':
                        if (!isset($req->data['value'])) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        $value = trim($req->data['value']);
                        if (strlen($value) == 0 || !str_contains($value, ';')) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        $value = explode(';', $value);
                        if (sizeof($value) != 3) {
                            $req->res->code(400);
                            return 'bad data';
                        }
                        $n_adminId = $value[0];
                        $n_adminName = base64_decode($value[1]);
                        $n_adminLevel = $value[2];

                        try {
                            FastDBReq($db, "INSERT INTO admins (adminId,adminName,adminClass,adminPrems) VALUES (?,?,?,?)", [$n_adminId, $n_adminName, $classId, $n_adminLevel]);
                            return true;
                        } catch (PDOException) {
                            $req->res->code(500);
                            return "ошибка";
                        }
                    case "create":
                        if (!isset($req->data['value'])) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        $classname = trim($req->data['value']);
                        if (strlen($classname) == 0) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        FastDBReq($db, "INSERT INTO classes (classid, userclassname) VALUES (?,?)", [$classId, $classname]);
                        return true;
                        break;
                    case "DELETE":
                        // DANGER ZONE::
                        FastDBReq($db, "DELETE FROM classes WHERE classid=?", [$classId]);
                        FastDBReq($db, "DELETE FROM admins WHERE adminClass=?", [$classId]);
                        return true;
                        break;
                    default:
                        $db = null;
                        return "?";
                }
            } else {
                // display class page
                
                $results = FastDBReq($db, "SELECT * FROM classes WHERE classId=?", [$classId]);
                if (count($results) == 0) {
                    $db = null;
                    $req->res->code(400);
                    return "idi naxodi";
                }
                $classData = $results[0];
                $adminsData = FastDBReq($db, "SELECT * FROM admins WHERE adminClass=?", [$classId]);
                $db = null;

                return ["ok" => 'da', "class" => $classData, "admins" => $adminsData];
            }
        } else {
            // diplay all classes
            $result = FastDBReq($db, "SELECT * FROM classes");
            return ['ok' => 'da', "data" => $result];
        }
    });

    $api->on('/admin', "POST", function ($req) {
        if (!Login($req)) {
            $req->res->code(401);
            return "auth_fail";
        }
        $db = db();
        if (isset($req->data['adminId'])) {
            if (isset($req->data['action'])) {
                switch ($req->data['action']) {
                    case "update_name":
                        if (!$req->hasData(['value', 'adminId'])) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        $value = trim($req->data['value']);
                        $adminId = $req->data['adminId'];
                        if (strlen($value) == 0) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        try {
                            FastDBReq($db, 'UPDATE admins SET adminName = ? WHERE adminId = ?', [$value, $adminId]);
                        } catch (PDOException) {
                            $db = null;
                            return "egor";
                        }
                        $db = null;
                        return true;
                    case "DELETE":
                        //scary
                        if (!isset($req->data['adminId'])) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        $adminId = $req->data['adminId'];
                        FastDBReq($db, "DELETE FROM admins WHERE adminId=?", [$adminId]);
                        return true;
                    case "update_level":
                        if (!$req->hasData(['value', 'adminId'])) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        $value = trim($req->data['value']);
                        $adminId = $req->data['adminId'];
                        if (strlen($value) == 0) {
                            $req->res->code(400);
                            return "bad data";
                        }
                        try {
                            FastDBReq($db, 'UPDATE admins SET adminPrems = ? WHERE adminId = ?', [$value, $adminId]);
                        } catch (PDOException) {
                            $db = null;
                            return "egor";
                        }
                        $db = null;
                        return true;
                }
            }
        }
    });

    $api->on('/server', "POST", function ($req) {
        if (!Login($req)) {
            $req->res->code(401);
            return "auth_fail";
        }
        if (isset($req->data['action'])) {
            switch ($req->data['action']) {
                case 'enable':
                    // unblock
                    if (file_exists(API_PATH . 'api.lock')) {
                        rename(API_PATH . 'api.lock', API_PATH . '_api.lock');
                    }
                    break;
                case 'disable':
                    // block
                    if (file_exists(API_PATH . 'api.lock')) return true;
                    if (file_exists(API_PATH . '_api.lock')) {
                        rename(API_PATH . '_api.lock', API_PATH . 'api.lock');
                    } else {
                        $f = fopen(API_PATH . 'api.lock', 'w');
                        fclose($f);
                    }
                    break;
                case 'update_block_message':
                    if (!isset($req->data['value'])) {
                        $req->res->code(400);
                        return false;
                    }
                    if (file_exists(API_PATH . 'api.lock')) {
                        // write to existing
                        $f = fopen(API_PATH . 'api.lock', 'w');
                    } else {
                        $f = fopen(API_PATH . '_api.lock', 'w');
                    }
                    fwrite($f, $req->data['value']);
                    fclose($f);
                    break;

                default:
                    return false;
            }
            return true;
        } else {
            $capi = relativePathToUrl(API_PATH . 'api.php');
            $status = !file_exists(API_PATH . 'api.lock');
            $apiblockmsg = "";
            if ($status) {
                // server enabled (lock disabled)
                if (file_exists(API_PATH . '_api.lock')) {
                    $apiblockmsg = file_get_contents(API_PATH . '_api.lock');
                }
            } else {
                $apiblockmsg = file_get_contents(API_PATH . 'api.lock');
            }
            return ["CLIENT_API" => $capi, "STATUS" => $status, "BLOCKMSG" => $apiblockmsg];
        }
    });
});
