<?php
namespace Misuzu;

use stdClass;
use RuntimeException;

$forumCtx = $msz->getForumContext();
$forumCategories = $forumCtx->getCategories();
$forumTopics = $forumCtx->getTopics();
$forumPosts = $forumCtx->getPosts();
$usersCtx = $msz->getUsersContext();
$mode = (string)filter_input(INPUT_GET, 'm');

$authInfo = $msz->getAuthInfo();
$currentUser = $authInfo->getUserInfo();
$currentUserId = $currentUser === null ? '0' : $currentUser->getId();

if($mode === 'mark') {
    if(!$authInfo->isLoggedIn())
        Template::throwError(403);

    $categoryId = filter_input(INPUT_GET, 'f', FILTER_SANITIZE_NUMBER_INT);

    if($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
        $categoryInfos = $categoryId === null
            ? $forumCategories->getCategories()
            : $forumCategories->getCategoryChildren(parentInfo: $categoryId, includeSelf: true);

        foreach($categoryInfos as $categoryInfo) {
            $perms = $authInfo->getPerms('forum', $categoryInfo);
            if($perms->check(Perm::F_CATEGORY_LIST))
                $forumCategories->updateUserReadCategory($userInfo, $categoryInfo);
        }

        Tools::redirect($msz->getURLs()->format($categoryId ? 'forum-category' : 'forum-index', ['forum' => $categoryId]));
        return;
    }

    Template::render('confirm', [
        'title' => 'Mark forum as read',
        'message' => 'Are you sure you want to mark ' . ($categoryId < 1 ? 'the entire' : 'this') . ' forum as read?',
        'return' => $msz->getURLs()->format($categoryId ? 'forum-category' : 'forum-index', ['forum' => $categoryId]),
        'params' => [
            'forum' => $categoryId,
        ]
    ]);
    return;
}

if($mode !== '')
    Template::throwError(404);

$categories = $forumCategories->getCategories(hidden: false, asTree: true);

foreach($categories as $categoryId => $category) {
    $perms = $authInfo->getPerms('forum', $category->info);
    if(!$perms->check(Perm::F_CATEGORY_LIST)) {
        unset($categories[$categoryId]);
        continue;
    }

    $unread = false;

    if($category->info->mayHaveChildren())
        foreach($category->children as $childId => $child) {
            $childPerms = $authInfo->getPerms('forum', $child->info);
            if(!$childPerms->check(Perm::F_CATEGORY_LIST)) {
                unset($category->children[$childId]);
                continue;
            }

            $childUnread = false;

            if($category->info->isListing()) {
                if($child->info->mayHaveChildren()) {
                    foreach($child->children as $grandChildId => $grandChild) {
                        $grandChildPerms = $authInfo->getPerms('forum', $grandChild->info);
                        if(!$grandChildPerms->check(Perm::F_CATEGORY_LIST)) {
                            unset($child->children[$grandChildId]);
                            continue;
                        }

                        $grandChildUnread = false;

                        if($grandChild->info->mayHaveTopics()) {
                            $catIds = [$grandChild->info->getId()];
                            foreach($grandChild->childIds as $greatGrandChildId) {
                                $greatGrandChildPerms = $authInfo->getPerms('forum', $greatGrandChildId);
                                if($greatGrandChildPerms->check(Perm::F_CATEGORY_LIST))
                                    $catIds[] = $greatGrandChildId;
                            }

                            $grandChildUnread = $forumCategories->checkCategoryUnread($catIds, $currentUser);
                            if($grandChildUnread)
                                $childUnread = true;
                        }

                        $grandChild->perms = $grandChildPerms;
                        $grandChild->unread = $grandChildUnread;
                    }
                }

                if($child->info->mayHaveChildren() || $child->info->mayHaveTopics()) {
                    $catIds = [$child->info->getId()];
                    foreach($child->childIds as $grandChildId) {
                        $grandChildPerms = $authInfo->getPerms('forum', $grandChildId);
                        if($grandChildPerms->check(Perm::F_CATEGORY_LIST))
                            $catIds[] = $grandChildId;
                    }

                    try {
                        $lastPostInfo = $forumPosts->getPost(categoryInfos: $catIds, getLast: true, deleted: false);
                    } catch(RuntimeException $ex) {
                        $lastPostInfo = null;
                    }

                    if($lastPostInfo !== null) {
                        $child->lastPost = new stdClass;
                        $child->lastPost->info = $lastPostInfo;
                        $child->lastPost->topicInfo = $forumTopics->getTopic(postInfo: $lastPostInfo);

                        if($lastPostInfo->hasUserId()) {
                            $child->lastPost->user = $usersCtx->getUserInfo($lastPostInfo->getUserId());
                            $child->lastPost->colour = $usersCtx->getUserColour($child->lastPost->user);
                        }
                    }
                }
            }

            if($child->info->mayHaveTopics() && !$childUnread) {
                $childUnread = $forumCategories->checkCategoryUnread($child->info, $currentUser);
                if($childUnread)
                    $unread = true;
            }

            $child->perms = $childPerms;
            $child->unread = $childUnread;
        }

    if($category->info->mayHaveTopics() && !$unread)
        $unread = $forumCategories->checkCategoryUnread($category->info, $currentUser);

    if(!$category->info->isListing()) {
        if(!array_key_exists('0', $categories)) {
            $categories['0'] = $root = new stdClass;
            $root->info = null;
            $root->perms = 0;
            $root->unread = false;
            $root->colour = null;
            $root->children = [];
        }

        $categories['0']->children[$categoryId] = $category;
        unset($categories[$categoryId]);

        if($category->info->mayHaveChildren() || $category->info->mayHaveTopics()) {
            $catIds = [$category->info->getId()];
            foreach($category->childIds as $childId) {
                $childPerms = $authInfo->getPerms('forum', $childId);
                if($childPerms->check(Perm::F_CATEGORY_LIST))
                    $catIds[] = $childId;
            }

            try {
                $lastPostInfo = $forumPosts->getPost(categoryInfos: $catIds, getLast: true, deleted: false);
            } catch(RuntimeException $ex) {
                $lastPostInfo = null;
            }

            if($lastPostInfo !== null) {
                $category->lastPost = new stdClass;
                $category->lastPost->info = $lastPostInfo;
                $category->lastPost->topicInfo = $forumTopics->getTopic(postInfo: $lastPostInfo);

                if($lastPostInfo->hasUserId()) {
                    $category->lastPost->user = $usersCtx->getUserInfo($lastPostInfo->getUserId());
                    $category->lastPost->colour = $usersCtx->getUserColour($category->lastPost->user);
                }
            }
        }
    }

    $category->perms = $perms;
    $category->unread = $unread;
}

Template::render('forum.index', [
    'forum_categories' => $categories,
    'forum_empty' => empty($categories),
    'forum_show_mark_as_read' => $currentUser !== null,
]);
