<?php
// SPDX-FileCopyrightText: IndieHosters <contact@indiehosters.net>
// SPDX-License-Identifier: AGPL-3.0-or-later

namespace OCA\CustomNav\Service;

use OCA\CustomNav\AppInfo\Application;
use OCP\INavigationManager;
use OCP\IConfig;
use OCP\IUser;

class Manager
{
    protected INavigationManager $navigationManager;

    protected IConfig $config;

    private const CONFIG_APPS_KEY = "apps";
    private const CONFIG_DISABLE_USER_EDIT_KEY = "disableUserEdit";

    public function __construct(
        INavigationManager $navigationManager,
        IConfig $config,
    ) {
        $this->navigationManager = $navigationManager;
        $this->config = $config;
    }

    public function isDisableUserEdit(): bool
    {
        return  boolval($this->config->getAppValue(Application::APP_ID, self::CONFIG_DISABLE_USER_EDIT_KEY, "0"));
    }

    public function setDisableUserEdit(bool $value)
    {
        $this->config->setAppValue(Application::APP_ID, self::CONFIG_DISABLE_USER_EDIT_KEY, $value ? "1" : "0");
    }

    public function getSystemOverwrite(): array
    {
        $value = $this->config->getAppValue(Application::APP_ID, self::CONFIG_APPS_KEY, "{}");
        return json_decode($value, true);
    }

    public function setSystemOverwrite(array $overwrite)
    {
        $v = json_encode($overwrite);
        $this->config->setAppValue(Application::APP_ID, self::CONFIG_APPS_KEY, $v);
    }

    public function getUserOverwrite(IUser $user): array
    {
        $value = $this->config->getUserValue($user->getUID(), Application::APP_ID, self::CONFIG_APPS_KEY, "{}");
        return json_decode($value, true);
    }

    public function setUserOverwrite(IUser $user, array $overwrite)
    {
        $v = json_encode($overwrite);
        $this->config->setUserValue($user->getUID(), Application::APP_ID, self::CONFIG_APPS_KEY, $v);
    }


    public function toOverwrite(array $apps): array
    {
        $overwrite = [];
        if (isset($apps)) {
            usort($apps, function ($a, $b) {
                return $a["order"] - $b["order"];
            });
            foreach ($apps as $app) {
                $overwrite[$app["id"]] = [
                    "order" => intval($app["order"]),
                    "displayed" => $app["displayed"],
                ];
            }
        }
        return $overwrite;
    }

    public function getDefaultApps(): array
    {
        $apps = $this->navigationManager->getAll();
        usort($apps, function ($a, $b) {
            return $a["order"] - $b["order"];
        });
        foreach ($apps as $i => &$app) {
            $app["displayed"] = true;
            $app["order"] = $i;
        }
        return $apps;
    }

    public function applyOverwrites(array $apps, array ...$overwrites): array
    {
        $overwrittenApps = [];
        foreach ($apps as $app) {
            foreach ($overwrites as $overwrite) {
                if ($appOverwrite = &$overwrite[$app["id"]] !== null) {
                    if ($displayed = &$appOverwrite["displayed"] !== null) {
                        $app["displayed"] = $displayed;
                    }
                    if ($order = &$appOverwrite["order"] !== null) {
                        // Accommodate previously stored str values
                        $app["order"] = intval($order);
                    }
                }
            }
            array_push($overwrittenApps, $app);
        }
        usort($overwrittenApps, function ($a, $b) {
            return $a["order"] - $b["order"];
        });
        return $overwrittenApps;
    }
}
