<?php

require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/init.inc"; global $title; global $isLoggedIn; global $lang; global $pages; global $_PROFILE;
require_once $_SERVER['DOCUMENT_ROOT'] . "/includes/util/random.inc";

$parts = explode("/", $_GET['_']);
$select = $parts[2] ?? null;

if ($select === "add") {
    $id = random();
    file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $id . ".json", json_encode([
        "name" => "Untitled document ($id)",
        "category" => null,
        "contents" => "This is a new document you just created.",
        "last" => [
            "author" => $_PROFILE["login"],
            "date" => time()
        ]
    ]));

    header("Location: /-/docs/$id");
    die();
} elseif (isset($select)) {
    if (ctype_alnum($select) && file_exists($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json")) {
        $id = $_documentId = $select;
        $data = json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $select . ".json"), true);
        $titleBase = " · " . $title . " · Cold Haze";
        $title = $data["name"] . " · " . $title;
    } else {
        header("Location: /-/docs");
        die();
    }
}

require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/header.inc';

function showDocument($item) { ?>
    <div style="display: grid; grid-template-columns: 2fr repeat(3, 1fr);">
        <?= $item["name"] ?>&nbsp;
        <?php if (str_starts_with(strip_tags($item["contents"]), "/delete")): ?>
            <span class="badge bg-warning rounded-pill text-black" style="width: max-content;">Deleting in <?= round((($item["last"]["date"] + 86400) - time()) / 3600) ?> hours</span>
        <?php else: ?>
            <span class="text-muted"><?= prettySize(filesize($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $item["id"] . ".json")) ?></span>
            <span class="relative-time text-muted" data-relative-timestamp="<?= $item["last"]["date"] ?>"><?= timeAgo($item["last"]["date"]) ?></span>
            <span class="text-muted"><?= $item["last"]["author"] === "raindrops" ? "Raindrops System" : "Cloudburst System" ?></span>
        <?php endif; ?>
    </div>
<?php }

?>

<br>
<div class="container">
    <div>
        <?php if (isset($data)): ?><div id="page-content">
            <h2>
                <span contenteditable="true" id="document-name" style="outline: none;"><?= $data["name"] ?></span>
                <a href="/-/docs" class="small btn btn-outline-light" style="float:right;margin-top:5px;vertical-align:middle;opacity:1 !important; color:white;">Back</a>
            </h2>
            <p><b>Category:</b> <span id="category" contenteditable="true" style="outline: none;"><?= $data["category"] ?? "Unsorted" ?></span></p>
            <p>
                <?php if ($data["last"]["date"] === 0): ?>
                    Last modified <span id="last-edit-time" class="relative-time" data-relative-timestamp="">never</span>
                <?php else: ?>
                    Last modified <span id="last-edit-time" class="relative-time" data-relative-timestamp="<?= $data["last"]["date"] ?>"><?= timeAgo($data["last"]["date"]) ?></span>
                    <?php if ($data["last"]["author"] !== $_PROFILE["login"]): ?>
                        <span id="last-edit-author">by <?= $data["last"]["author"] === "raindrops" ? "the Raindrops System" : "the Cloudburst System" ?></span>
                    <?php endif; ?>
                <?php endif; ?>
                · <span id="editor-save-status" class="text-muted">Saved</span>
            </p>

            <?php $timeDiff = round((1800 - (time() - $data["last"]["date"])) / 60); if ($timeDiff >= 0 && $data["last"]["author"] !== $_PROFILE["login"]): ?>
            <div class="alert alert-warning">
                <b>This document is currently in use by <?= $data["last"]["author"] === "raindrops" ? "the Raindrops System" : "the Cloudburst System" ?>.</b> It has been open in read-only to prevent conflicts with the changes they make. If they stopped editing the document, it will become editable for you after you refresh the page in <?= $timeDiff ?> minute<?= $timeDiff > 1 ? "s" : "" ?>.
            </div>
            <?= $data["contents"] ?>
            <?php else: ?>
            <textarea id="editor"><?= $data["contents"] ?></textarea>

            <script src="/assets/editor/editor.js"></script>
            <script>
                let editor;
                ClassicEditor
                    .create( document.querySelector( '#editor' ), {
                        toolbar: [
                            'undo', 'redo', '|', 'removeFormat', '|', 'heading', '|', 'fontSize', 'fontColor', 'fontBackgroundColor', 'alignment', '|', 'bold', 'italic', 'underline', 'strikethrough', '|', 'subscript', 'superscript', '|', 'code', '|', 'outdent', 'indent', '|', 'bulletedList', 'numberedList', '|', 'link', 'imageUpload', 'mediaEmbed', 'blockQuote', 'insertTable', 'codeBlock', '|', 'horizontalLine'
                        ]
                    } )

                    .then( newEditor => {
                        editor = newEditor;
                    } )
                    .catch( error => {
                        console.error( error );
                    } );
            </script>
            <!--suppress CssUnresolvedCustomProperty -->
            <style>
                :root {
                    --ck-color-base-background: transparent;
                }

                .ck-toolbar {
                    filter: invert(1);
                    border-bottom-left-radius: var(--ck-border-radius) !important;
                    border-bottom-right-radius: var(--ck-border-radius) !important;
                    border-bottom-width: 1px !important;
                }

                .ck-tooltip__text {
                    color: white !important;
                }

                .ck-dropdown__panel {
                    background: #ddd !important;
                }

                .ck-color-grid__tile {
                    filter: invert(1);
                }

                .ck-balloon-rotator {
                    background-color: #ccc !important;
                }

                .ck-balloon-panel {
                    filter: invert(1);
                }

                .ck-editor__editable {
                    border-color: transparent !important;
                }

                .ck.ck-sticky-panel__content_sticky {
                    top: 59px !important;
                }
            </style>
            <script>

                let titleBase = "<?= $titleBase ?>";
                let lastSavedData = editor.getData();
                let lastFetchedData = editor.getData();
                let timeSinceLastModified = 0;
                let saving = false;

                async function save() {
                    let data = editor.getData();
                    document.getElementById("editor-save-status").innerHTML = "Saving...";
                    document.getElementById("editor-save-status").classList.remove("text-danger");
                    document.getElementById("editor-save-status").classList.remove("text-muted");
                    document.getElementById("editor-save-status").classList.remove("text-warning");
                    document.getElementById("editor-save-status").classList.add("text-primary");
                    saving = true;

                    try {
                        await window.fetch("/api/docs?id=<?= $_documentId ?>", {
                            method: "POST",
                            body: JSON.stringify({ content: data, name: document.getElementById("document-name").innerText, category: document.getElementById("category").innerText })
                        });
                        document.getElementById("last-edit-time").setAttribute("data-relative-timestamp", (new Date().getTime() / 1000).toFixed(0));
                        if (document.getElementById("last-edit-author")) document.getElementById("last-edit-author").outerHTML = "";
                        document.title = document.getElementById("document-name").innerText + titleBase;
                        document.getElementById("editor-save-status").innerHTML = "Saved";
                        document.getElementById("editor-save-status").classList.remove("text-danger");
                        document.getElementById("editor-save-status").classList.add("text-muted");
                        document.getElementById("editor-save-status").classList.remove("text-warning");
                        document.getElementById("editor-save-status").classList.remove("text-primary");
                        lastSavedData = data;
                        saving = false;
                    } catch (e) {
                        console.error(e);
                        document.getElementById("editor-save-status").innerHTML = "Failed to save";
                        document.getElementById("editor-save-status").classList.add("text-danger");
                        document.getElementById("editor-save-status").classList.remove("text-muted");
                        document.getElementById("editor-save-status").classList.remove("text-warning");
                        document.getElementById("editor-save-status").classList.remove("text-primary");
                    }
                }

                document.onclick = async () => {
                    if (saving) return;

                    if (editor.getData() !== lastSavedData) {
                        await save();
                    }
                }

                setInterval(async () => {
                    if (saving) return;

                    if (editor.getData() !== lastSavedData) {
                        document.getElementById("editor-save-status").innerHTML = "Modified";
                        document.getElementById("editor-save-status").classList.remove("text-danger");
                        document.getElementById("editor-save-status").classList.remove("text-muted");
                        document.getElementById("editor-save-status").classList.add("text-warning");
                        document.getElementById("editor-save-status").classList.remove("text-primary");

                        if (editor.getData() !== lastFetchedData) {
                            lastFetchedData = editor.getData();
                            timeSinceLastModified = 0;
                        } else {
                            timeSinceLastModified++;
                        }

                        if (timeSinceLastModified > 20 || !document.hasFocus()) {
                            await save();
                        }
                    } else {
                        timeSinceLastModified = 0;
                    }
                }, 100)

            </script>
            <?php endif; ?>
        </div><?php else: ?>
            <h2>Documents</h2>
            <div id="list">
                <?php

                $documents = array_map(function ($i) {
                    return [
                        "id" => substr($i, 0, -5),
                        ...(json_decode(file_get_contents($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs/" . $i), true) ?? [])
                    ];
                }, array_filter(scandir($_SERVER['DOCUMENT_ROOT'] . "/includes/data/docs"), function ($i) {
                    return !str_starts_with($i, ".") && str_ends_with($i, ".json");
                }));

                $deletable = array_values(array_filter($documents, function ($i) {
                    return str_starts_with(strip_tags($i["contents"]), "/delete");
                }));
                $unsorted_pre = array_values(array_filter($documents, function ($i) {
                    return !str_starts_with(strip_tags($i["contents"]), "/delete");
                }));

                $categoryFirst = [];
                $unsorted = [];
                $categories = [];
                foreach ($unsorted_pre as $item) {
                    if (isset($item["category"])) {
                        $existing_categories = [...array_keys($categories), ...array_keys($categoryFirst)];
                        $matched_category = null;

                        foreach ($existing_categories as $existing_category) {
                            if (levenshtein($item["category"], $existing_category) < 3) {
                                $matched_category = $existing_category;
                            }
                        }

                        $selected_category = $matched_category ?? $item["category"];

                        if (str_starts_with($item["category"], ".")) {
                            if (!isset($categoryFirst[$selected_category])) $categoryFirst[$selected_category] = [];
                            $categoryFirst[$selected_category][] = $item;
                        } else {
                            if (!isset($categories[$selected_category])) $categories[$selected_category] = [];
                            $categories[$selected_category][] = $item;
                        }
                    } else {
                        $unsorted[] = $item;
                    }
                }

                foreach ($categories as $category => $_) {
                    uasort($categories[$category], function ($a, $b) {
                        return preg_replace("/[^a-z\d]/m", "", strtolower($b["name"])) < preg_replace("/[^a-z\d]/m", "", strtolower($a["name"]));
                    });
                }

                foreach ($categoryFirst as $category => $_) {
                    uasort($categoryFirst[$category], function ($a, $b) {
                        return preg_replace("/[^a-z\d]/m", "", strtolower($b["name"])) < preg_replace("/[^a-z\d]/m", "", strtolower($a["name"]));
                    });
                }

                uasort($unsorted, function ($a, $b) {
                    return preg_replace("/[^a-z\d]/m", "", strtolower($b["name"])) < preg_replace("/[^a-z\d]/m", "", strtolower($a["name"]));
                });

                uasort($deletable, function ($a, $b) {
                    return preg_replace("/[^a-z\d]/m", "", strtolower($b["name"])) < preg_replace("/[^a-z\d]/m", "", strtolower($a["name"]));
                });

                $fullList = [...$categoryFirst, ...$categories];

                ?>

                <?php foreach ($fullList as $category => $items): if ($category != "Archives"): ?>
                <h4><?= str_starts_with($category, ".") ? substr($category, 1) : $category ?></h4><div class="list-group">
                <?php foreach ($items as $item): ?>
                    <a href="/-/docs/<?= $item["id"] ?>" id="document-<?= $item["id"] ?>" class="list-group-item list-group-item-action document-listing <?php if (str_starts_with(strip_tags($item["contents"]), "/delete")): ?>opacity-75<?php endif; ?>">
                        <?php showDocument($item) ?>
                    </a>
                <?php endforeach; ?></div>
                <hr>
                <?php endif; endforeach; ?>

                <h4>Unsorted</h4><div class="list-group">
                <?php foreach ($unsorted as $item): ?>
                <a href="/-/docs/<?= $item["id"] ?>" id="document-<?= $item["id"] ?>" class="list-group-item list-group-item-action document-listing <?php if (str_starts_with(strip_tags($item["contents"]), "/delete")): ?>opacity-75<?php endif; ?>">
                    <?php showDocument($item) ?>
                </a>
                <?php endforeach; ?></div>

                <hr>
                <details>
                    <summary>Show archives and marked for deletion</summary>

                    <h4 style="margin-top: 10px;">Archives</h4>
                    <div class="list-group">
                        <?php foreach ($categories["Archives"] as $item): ?>
                            <a href="/-/docs/<?= $item["id"] ?>" id="document-<?= $item["id"] ?>" class="list-group-item list-group-item-action document-listing <?php if (str_starts_with(strip_tags($item["contents"]), "/delete")): ?>opacity-75<?php endif; ?>">
                                <?php showDocument($item) ?>
                            </a>
                        <?php endforeach; ?></div>

                    <hr>
                    <h4 id="deletable">Marked for deletion</h4><div class="list-group">
                        <?php foreach ($deletable as $item): ?>
                            <a href="/-/docs/<?= $item["id"] ?>" id="document-<?= $item["id"] ?>" class="list-group-item list-group-item-action document-listing <?php if (str_starts_with(strip_tags($item["contents"]), "/delete")): ?>opacity-75<?php endif; ?>">
                                <?php showDocument($item) ?>
                            </a>
                        <?php endforeach; ?></div>
                </details>
            </div>

            <hr>
            <div id="page-content">
                <a href="/-/docs/add">Create a new document</a>
            </div>
        <?php endif; ?>
    </div>
</div>

<script>
    setInterval(async () => {
        Array.from(document.getElementsByClassName("relative-time")).forEach((el) => {
            el.innerText = timeAgo(parseInt(el.getAttribute("data-relative-timestamp")) * 1000);
        })
    }, 1000)

    function timeAgo(time) {
        if (!isNaN(parseInt(time))) {
            time = new Date(time).getTime();
        }

        let periods = ["sec", "min", "hr", "d", "wk", "mo", "y", "ages"];

        let lengths = ["60", "60", "24", "7", "4.35", "12", "100"];

        let now = new Date().getTime();

        let difference = Math.round((now - time) / 1000);
        let tense;
        let period;

        if (difference <= 10 && difference >= 0) {
            return "now";
        } else if (difference > 0) {
            tense = "ago";
        } else {
            tense = "later";
        }

        let j;

        for (j = 0; difference >= lengths[j] && j < lengths.length - 1; j++) {
            difference /= lengths[j];
        }

        difference = Math.round(difference);

        period = periods[j];

        return `${difference} ${period} ${tense}`;
    }
</script>
<style>
    .list-group-item {
        color: #fff;
        background-color: #222;
        border: 1px solid rgba(255, 255, 255, .125);
    }

    .list-group-item.disabled {
        color: #fff;
        background-color: #222;
        border-color: rgba(255, 255, 255, .125);
        opacity: .75;
    }

    .list-group-item:hover {
        background-color: #252525;
        color: #ddd;
    }

    .list-group-item:active, .list-group-item:focus {
        background-color: #272727;
        color: #bbb;
    }
</style>

<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/components/footer.inc'; ?>