<?php

namespace Shm\ShmAdmin\AdminRPC;

use Shm\Shm;
use Shm\ShmAddons\AdminActions\AdminAction;
use Shm\ShmAddons\AdminActions\AdminActionResult;
use Shm\ShmAdmin\AdminPanel;
use Shm\ShmAdmin\Types\BaseStructureType;
use Shm\ShmAdmin\Utils\SubAccountUtils;
use Shm\ShmAuth\Auth;
use Shm\ShmDB\mDB;
use Shm\ShmRPC\ShmRPC;

use Shm\ShmUtils\I18n;
use Shm\ShmUtils\Response;
use ShmAuditLog\ShmAuditLog;

class AdminRPCActions
{

    public static function allActions()
    {

        return ShmRPC::lazy(function () {

            return [
                'type' => Shm::arrayOf(Shm::structure([
                    'key' => Shm::string(),
                    'title' => Shm::string(),
                    'icon' => Shm::string(),
                ])->staticBaseTypeName("AdminActionMenuItem")),
                'args' => [
                    'collection' => Shm::nonNull(Shm::string()),
                    '_ids' => Shm::nonNull(Shm::arrayOf(Shm::string())),

                ],

                'resolve' => function ($root, $args) {

                    Auth::authenticateOrThrow(...AdminPanel::$authStructures);

                    $structure = AdminPanel::fullSchema()->findItemByCollection($args['collection']);

                    if (!$structure) {
                        ShmRPC::error(I18n::get('data_not_available'));
                    }

                    $ids = $args['_ids'];
                    $ids = array_map(function ($id) {
                        return mDB::id($id);
                    }, $ids);

                    if ($structure->single) {


                        $pipeline = $structure->getPipeline();

                        $pipeline = [
                            ...$pipeline,

                        ];

                        $_id = $structure->aggregate($pipeline)->toArray()[0]['_id'] ?? null;

                        if ($_id) {
                            $ids = [$_id];
                        } else {
                            ShmRPC::error(I18n::get('data_not_available'));
                        }
                    }



                    $actions =  $structure->getActions();

                    $result = [];
                    foreach ($actions as $action) {
                        if ($action instanceof AdminAction) {


                            if (Auth::subAccountAuth()) {
                                if (!SubAccountUtils::canShowAction($structure->collection, $action->key)) {
                                    continue;
                                }
                            }

                            if (!$action->shouldShow($ids)) {
                                continue;
                            }

                            $result[] = [
                                'key' => $action->key,
                                'title' => $action->title(),
                                'icon' => $action->icon(),
                            ];
                        }
                    }

                    return $result;
                }
            ];
        });
    }


    public static function prepareAction()
    {

        return ShmRPC::lazy(function () {

            return [
                'type' => Shm::structure([
                    'args' => BaseStructureType::get(),
                    'key' => Shm::string(),
                    'title' => Shm::string(),
                    'icon' => Shm::string(),
                    'multiSelect' => Shm::boolean(),
                ])->staticBaseTypeName("AdminActionItem"),
                'args' => [
                    'collection' => Shm::nonNull(Shm::string()),
                    '_ids' => Shm::arrayOf(Shm::string()),
                    'action' => Shm::nonNull(Shm::string()),

                ],

                'resolve' => function ($root, $args) {

                    Auth::authenticateOrThrow(...AdminPanel::$authStructures);

                    $structure = AdminPanel::fullSchema()->findItemByCollection($args['collection']);

                    if (!$structure) {
                        ShmRPC::error(I18n::get('data_not_available'));
                    }



                    $action =  $structure->getActionByKey($args['action']);

                    if (!$action) {
                        ShmRPC::error(I18n::get('action_not_found'));
                    }

                    $argsSchema = $action->argsSchema($args['_ids']);


                    return [
                        'args' => $argsSchema->inAdmin()->editable()->json(),
                        'key' => $action->key,
                        'title' => $action->title(),
                        'icon' => $action->icon(),

                    ];
                }
            ];
        });
    }

    public static function runAction()
    {

        return ShmRPC::lazy(function () {

            return [
                'type' => Shm::structure([
                    'payload' => Shm::structure([
                        'url' => Shm::string(),
                    ]),
                ]),
                'args' => [
                    'collection' => Shm::nonNull(Shm::string()),
                    '_ids' => Shm::arrayOf(Shm::string()),
                    'action' => Shm::nonNull(Shm::string()),
                    'values' => Shm::mixed(),
                ],

                'resolve' => function ($root, $args) {

                    Auth::authenticateOrThrow(...AdminPanel::$authStructures);

                    $structure = AdminPanel::fullSchema()->findItemByCollection($args['collection']);

                    if (!$structure) {
                        ShmRPC::error(I18n::get('data_not_available'));
                    }

                    $action =  $structure->getActionByKey($args['action']);

                    if (!$action) {
                        ShmRPC::error(I18n::get('action_not_found'));
                    }

                    $ids = $args['_ids'] ?? [];
                    $ids = array_map(function ($id) {
                        return mDB::id($id);
                    }, $ids);

                    if ($structure->single) {


                        $pipeline = $structure->getPipeline();

                        $pipeline = [
                            ...$pipeline,

                        ];

                        $_id = $structure->aggregate($pipeline)->toArray()[0]['_id'] ?? null;

                        if ($_id) {
                            $ids = [$_id];
                        } else {
                            ShmRPC::error(I18n::get('error_occurred'));
                        }
                    }


                    if (count($ids) === 0) {
                        ShmRPC::error(I18n::get('error_occurred'));
                    }


                    $result = $action->resolve($ids, $args['values']);

                    if (! $result) {
                        ShmRPC::error(I18n::get('error_occurred'));
                    }

                    if ($result instanceof AdminActionResult) {
                        return $result->json();
                    }

                    return null;
                }
            ];
        });
    }
}
