<?php
namespace Misuzu;

use DateTimeInterface;
use RuntimeException;
use Misuzu\Changelog\Changelog;
use Carbon\CarbonImmutable;
use Index\{XArray,XDateTime};

if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
    die('Script must be called through the Misuzu route dispatcher.');

if(!$msz->authInfo->getPerms('global')->check(Perm::G_CL_CHANGES_MANAGE))
    Template::throwError(403);

$changeActions = [];
foreach(Changelog::ACTIONS as $action)
    $changeActions[$action] = Changelog::actionText($action);

$changeId = (string)filter_input(INPUT_GET, 'c', FILTER_SANITIZE_NUMBER_INT);
$changeInfo = null;
$changeTagIds = [];
$tagInfos = $msz->changelog->getTags();

if(empty($changeId))
    $isNew = true;
else
    try {
        $isNew = false;
        $changeInfo = $msz->changelog->getChange($changeId);
        $changeTagIds = XArray::select($msz->changelog->getTags(changeInfo: $changeInfo), fn($tagInfo) => $tagInfo->id);
    } catch(RuntimeException $ex) {
        Template::throwError(404);
    }

if($_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_GET['delete'])) {
    if(!CSRF::validateRequest())
        Template::throwError(403);

    $msz->changelog->deleteChange($changeInfo);
    $msz->createAuditLog('CHANGELOG_ENTRY_DELETE', [$changeInfo->id]);
    Tools::redirect($msz->urls->format('manage-changelog-changes'));
    return;
}

// make errors not echos lol
while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
    $action = trim((string)filter_input(INPUT_POST, 'cl_action'));
    $summary = trim((string)filter_input(INPUT_POST, 'cl_summary'));
    $body = trim((string)filter_input(INPUT_POST, 'cl_body'));
    $userId = (int)filter_input(INPUT_POST, 'cl_user', FILTER_SANITIZE_NUMBER_INT);
    $createdAt = trim((string)filter_input(INPUT_POST, 'cl_created'));
    $tags = filter_input(INPUT_POST, 'cl_tags', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);

    if($userId < 1) $userId = null;
    else $userId = (string)$userId;

    if(empty($createdAt))
        $createdAt = null;
    else {
        $createdAt = CarbonImmutable::createFromFormat(DateTimeInterface::ATOM, $createdAt . ':00Z');
        if((int)$createdAt->format('U') < 0)
            $createdAt = null;
    }

    if($isNew) {
        $changeInfo = $msz->changelog->createChange($action, $summary, $body, $userId, $createdAt);
    } else {
        if($action === $changeInfo->action)
            $action = null;
        if($summary === $changeInfo->summary)
            $summary = null;
        if($body === $changeInfo->body)
            $body = null;
        if($createdAt !== null && XDateTime::compare($createdAt, $changeInfo->createdAt) === 0)
            $createdAt = null;
        $updateUserInfo = $userId !== $changeInfo->userId;

        if($action !== null || $summary !== null || $body !== null || $createdAt !== null || $updateUserInfo)
            $msz->changelog->updateChange($changeInfo, $action, $summary, $body, $updateUserInfo, $userId, $createdAt);
    }

    if(!empty($tags)) {
        $tCurrent = $changeTagIds;
        $tApply = $tags;
        $tRemove = [];

        foreach($tCurrent as $tag)
            if(!in_array($tag, $tApply)) {
                $tRemove[] = $tag;
                $msz->changelog->removeTagFromChange($changeInfo, $tag);
            }

        $tCurrent = array_diff($tCurrent, $tRemove);

        foreach($tApply as $tag)
            if(!in_array($tag, $tCurrent)) {
                $msz->changelog->addTagToChange($changeInfo, $tag);
                $tCurrent[] = $tag;
            }
    }

    $msz->createAuditLog(
        $isNew ? 'CHANGELOG_ENTRY_CREATE' : 'CHANGELOG_ENTRY_EDIT',
        [$changeInfo->id]
    );

    Tools::redirect($msz->urls->format('manage-changelog-change', ['change' => $changeInfo->id]));
    return;
}

Template::render('manage.changelog.change', [
    'change_new' => $isNew,
    'change_info' => $changeInfo,
    'change_info_tags' => $changeTagIds,
    'change_tags' => $tagInfos,
    'change_actions' => $changeActions,
    'change_author_id' => $msz->authInfo->userId,
]);