<?php
namespace Misuzu;

use Misuzu\Users\User;
use Misuzu\Users\UserSession;

$postId = !empty($_GET['p']) && is_string($_GET['p']) ? (int)$_GET['p'] : 0;
$topicId = !empty($_GET['t']) && is_string($_GET['t']) ? (int)$_GET['t'] : 0;
$moderationMode = !empty($_GET['m']) && is_string($_GET['m']) ? (string)$_GET['m'] : '';
$submissionConfirmed = !empty($_GET['confirm']) && is_string($_GET['confirm']) && $_GET['confirm'] === '1';

$topicUser = User::getCurrent();
$topicUserId = $topicUser === null ? 0 : $topicUser->getId();

if($topicId < 1 && $postId > 0) {
    $postInfo = forum_post_find($postId, $topicUserId);

    if(!empty($postInfo['topic_id'])) {
        $topicId = (int)$postInfo['topic_id'];
    }
}

$topic = forum_topic_get($topicId, true);
$perms = $topic
    ? forum_perms_get_user($topic['forum_id'], $topicUserId)[MSZ_FORUM_PERMS_GENERAL]
    : 0;

if(isset($topicUser) && $topicUser->hasActiveWarning())
    $perms &= ~MSZ_FORUM_PERM_SET_WRITE;

$topicIsNuked = empty($topic['topic_id']);
$topicIsDeleted = !empty($topic['topic_deleted']);
$canDeleteAny = perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST);

if($topicIsNuked || $topicIsDeleted) {
    $topicRedirectInfo = forum_topic_redir_info($topicId);
    Template::set('topic_redir_info', $topicRedirectInfo);

    if($topicIsNuked || !$canDeleteAny) {
        if(empty($topicRedirectInfo))
            echo render_error(404);
        else
            header('Location: ' . $topicRedirectInfo->topic_redir_url);
        return;
    }
}

if(!perms_check($perms, MSZ_FORUM_PERM_VIEW_FORUM)) {
    echo render_error(403);
    return;
}

$topicIsLocked = !empty($topic['topic_locked']);
$topicIsArchived = !empty($topic['topic_archived']);
$topicPostsTotal = (int)($topic['topic_count_posts'] + $topic['topic_count_posts_deleted']);
$topicIsFrozen = $topicIsArchived || $topicIsDeleted;
$canDeleteOwn = !$topicIsFrozen && !$topicIsLocked && perms_check($perms, MSZ_FORUM_PERM_DELETE_POST);
$canBumpTopic = !$topicIsFrozen && perms_check($perms, MSZ_FORUM_PERM_BUMP_TOPIC);
$canLockTopic = !$topicIsFrozen && perms_check($perms, MSZ_FORUM_PERM_LOCK_TOPIC);
$canNukeOrRestore = $canDeleteAny && $topicIsDeleted;
$canDelete = !$topicIsDeleted && (
    $canDeleteAny || (
        $topicPostsTotal > 0
        && $topicPostsTotal <= MSZ_FORUM_TOPIC_DELETE_POST_LIMIT
        && $canDeleteOwn
        && $topic['author_user_id'] === $topicUserId
    )
);

$validModerationModes = [
    'delete', 'restore', 'nuke',
    'bump', 'lock', 'unlock',
];

if(in_array($moderationMode, $validModerationModes, true)) {
    if(!CSRF::validateRequest()) {
        echo render_info("Couldn't verify this request, please refresh the page and try again.", 403);
        return;
    }

    if(!UserSession::hasCurrent()) {
        echo render_info('You must be logged in to manage posts.', 401);
        return;
    }

    if($topicUser->isBanned()) {
        echo render_info('You have been banned, check your profile for more information.', 403);
        return;
    }

    switch($moderationMode) {
        case 'delete':
            $canDeleteCode = forum_topic_can_delete($topic, $topicUserId);
            $canDeleteMsg = '';
            $responseCode = 200;

            switch($canDeleteCode) {
                case MSZ_E_FORUM_TOPIC_DELETE_USER:
                    $responseCode = 401;
                    $canDeleteMsg = 'You must be logged in to delete topics.';
                    break;
                case MSZ_E_FORUM_TOPIC_DELETE_TOPIC:
                    $responseCode = 404;
                    $canDeleteMsg = "This topic doesn't exist.";
                    break;
                case MSZ_E_FORUM_TOPIC_DELETE_DELETED:
                    $responseCode = 404;
                    $canDeleteMsg = 'This topic has already been marked as deleted.';
                    break;
                case MSZ_E_FORUM_TOPIC_DELETE_OWNER:
                    $responseCode = 403;
                    $canDeleteMsg = 'You can only delete your own topics.';
                    break;
                case MSZ_E_FORUM_TOPIC_DELETE_OLD:
                    $responseCode = 401;
                    $canDeleteMsg = 'This topic has existed for too long. Ask a moderator to remove if it absolutely necessary.';
                    break;
                case MSZ_E_FORUM_TOPIC_DELETE_PERM:
                    $responseCode = 401;
                    $canDeleteMsg = 'You are not allowed to delete topics.';
                    break;
                case MSZ_E_FORUM_TOPIC_DELETE_POSTS:
                    $responseCode = 403;
                    $canDeleteMsg = 'This topic already has replies, you may no longer delete it. Ask a moderator to remove if it absolutely necessary.';
                    break;
                case MSZ_E_FORUM_TOPIC_DELETE_OK:
                    break;
                default:
                    $responseCode = 500;
                    $canDeleteMsg = sprintf('Unknown error \'%d\'', $canDelete);
            }

            if($canDeleteCode !== MSZ_E_FORUM_TOPIC_DELETE_OK) {
                echo render_info($canDeleteMsg, $responseCode);
                break;
            }

            if(!isset($_GET['confirm'])) {
                Template::render('forum.confirm', [
                    'title' => 'Confirm topic deletion',
                    'class' => 'far fa-trash-alt',
                    'message' => sprintf('You are about to delete topic #%d. Are you sure about that?', $topic['topic_id']),
                    'params' => [
                        't' => $topic['topic_id'],
                        'm' => 'delete',
                    ],
                ]);
                break;
            } elseif(!$submissionConfirmed) {
                url_redirect(
                    'forum-topic',
                    ['topic' => $topic['topic_id']]
                );
                break;
            }

            $deleteTopic = forum_topic_delete($topic['topic_id']);

            if($deleteTopic)
                $msz->createAuditLog('FORUM_TOPIC_DELETE', [$topic['topic_id']]);

            if(!$deleteTopic) {
                echo render_error(500);
                break;
            }

            url_redirect('forum-category', [
                'forum' => $topic['forum_id'],
            ]);
            break;

        case 'restore':
            if(!$canNukeOrRestore) {
                echo render_error(403);
                break;
            }

            if(!isset($_GET['confirm'])) {
                Template::render('forum.confirm', [
                    'title' => 'Confirm topic restore',
                    'class' => 'fas fa-magic',
                    'message' => sprintf('You are about to restore topic #%d. Are you sure about that?', $topic['topic_id']),
                    'params' => [
                        't' => $topic['topic_id'],
                        'm' => 'restore',
                    ],
                ]);
                break;
            } elseif(!$submissionConfirmed) {
                url_redirect('forum-topic', [
                    'topic' => $topic['topic_id'],
                ]);
                break;
            }

            $restoreTopic = forum_topic_restore($topic['topic_id']);

            if(!$restoreTopic) {
                echo render_error(500);
                break;
            }

            $msz->createAuditLog('FORUM_TOPIC_RESTORE', [$topic['topic_id']]);

            url_redirect('forum-category', [
                'forum' => $topic['forum_id'],
            ]);
            break;

        case 'nuke':
            if(!$canNukeOrRestore) {
                echo render_error(403);
                break;
            }

            if(!isset($_GET['confirm'])) {
                Template::render('forum.confirm', [
                    'title' => 'Confirm topic nuke',
                    'class' => 'fas fa-radiation',
                    'message' => sprintf('You are about to PERMANENTLY DELETE topic #%d. Are you sure about that?', $topic['topic_id']),
                    'params' => [
                        't' => $topic['topic_id'],
                        'm' => 'nuke',
                    ],
                ]);
                break;
            } elseif(!$submissionConfirmed) {
                url_redirect('forum-topic', [
                    'topic' => $topic['topic_id'],
                ]);
                break;
            }

            $nukeTopic = forum_topic_nuke($topic['topic_id']);

            if(!$nukeTopic) {
                echo render_error(500);
                break;
            }

            $msz->createAuditLog('FORUM_TOPIC_NUKE', [$topic['topic_id']]);

            url_redirect('forum-category', [
                'forum' => $topic['forum_id'],
            ]);
            break;

        case 'bump':
            if($canBumpTopic && forum_topic_bump($topic['topic_id'])) {
                $msz->createAuditLog('FORUM_TOPIC_BUMP', [$topic['topic_id']]);
            }

            url_redirect('forum-topic', [
                'topic' => $topic['topic_id'],
            ]);
            break;

        case 'lock':
            if($canLockTopic && !$topicIsLocked && forum_topic_lock($topic['topic_id'])) {
                $msz->createAuditLog('FORUM_TOPIC_LOCK', [$topic['topic_id']]);
            }

            url_redirect('forum-topic', [
                'topic' => $topic['topic_id'],
            ]);
            break;

        case 'unlock':
            if($canLockTopic && $topicIsLocked && forum_topic_unlock($topic['topic_id'])) {
                $msz->createAuditLog('FORUM_TOPIC_UNLOCK', [$topic['topic_id']]);
            }

            url_redirect('forum-topic', [
                'topic' => $topic['topic_id'],
            ]);
            break;
    }
    return;
}

$topicPosts = $topic['topic_count_posts'];

if($canDeleteAny) {
    $topicPosts += $topic['topic_count_posts_deleted'];
}

$topicPagination = new Pagination($topicPosts, MSZ_FORUM_POSTS_PER_PAGE, 'page');

if(isset($postInfo['preceeding_post_count'])) {
    $preceedingPosts = $postInfo['preceeding_post_count'];

    if($canDeleteAny) {
        $preceedingPosts += $postInfo['preceeding_post_deleted_count'];
    }

    $topicPagination->setPage(floor($preceedingPosts / $topicPagination->getRange()), true);
}

if(!$topicPagination->hasValidOffset()) {
    echo render_error(404);
    return;
}

Template::set('topic_perms', $perms);

$posts = forum_post_listing(
    $topic['topic_id'],
    $topicPagination->getOffset(),
    $topicPagination->getRange(),
    perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST)
);

if(!$posts) {
    echo render_error(404);
    return;
}

$canReply = !$topicIsArchived && !$topicIsLocked && !$topicIsDeleted && perms_check($perms, MSZ_FORUM_PERM_CREATE_POST);

forum_topic_mark_read($topicUserId, $topic['topic_id'], $topic['forum_id']);

Template::render('forum.topic', [
    'topic_breadcrumbs' => forum_get_breadcrumbs($topic['forum_id']),
    'global_accent_colour' => forum_get_colour($topic['forum_id']),
    'topic_info' => $topic,
    'topic_posts' => $posts,
    'can_reply' => $canReply,
    'topic_pagination' => $topicPagination,
    'topic_can_delete' => $canDelete,
    'topic_can_nuke_or_restore' => $canNukeOrRestore,
    'topic_can_bump' => $canBumpTopic,
    'topic_can_lock' => $canLockTopic,
]);
