<?php
// +----------------------------------------------------------------------
// | onezan-admin 快速开发的管理平台
// +----------------------------------------------------------------------
// | 官方网址：https://www.onezan.cn
// +----------------------------------------------------------------------
// | onezan团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: 543885307@qq.com
// +----------------------------------------------------------------------
namespace app\service\domain\admin;

use app\model\AdminRole;
use app\model\AdminUser;
use app\repository\admin\RoleRepository;
use app\service\domain\admin\CoreAdminPermissionService;
use Core\service\BaseCoreService;

/**
 * 角色服务
 * Class CoreRoleService
 * @package app\service\domain\admin
 */
class CoreRoleService extends BaseCoreService
{
    /**
     * 保存角色
     * @param AdminUser $actor
     * @param array $payload
     * @return array
     */
    public function save(AdminUser $actor, array $payload): array
    {
        $id = is_numeric($payload['id'] ?? null) ? (int)$payload['id'] : 0;
        $name = trim((string)($payload['name'] ?? ''));
        $code = trim((string)($payload['code'] ?? ''));
        $status = (int)($payload['status'] ?? 1) ? 1 : 0;
        $permissions = $payload['permissions'] ?? [];

        if ($name === '' || $code === '') {
            return ['code' => 1, 'msg' => ''];
        }
        if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]{2,50}$/', $code)) {
            return ['code' => 1, 'msg' => ''];
        }

        $normalizedPermissions = $this->normalizePermissionsPayload($permissions);
        $normalizedPermissions = $this->permissionService()->getRegistry()->normalizePermissions($normalizedPermissions, false);
        if (!$this->permissionService()->canGrantPermissions($actor, $normalizedPermissions)) {
            return ['code' => 1, 'msg' => 'Unknown error'];
        }

        if ($id > 0) {
            $role = $this->roleRepository()->findById($id);
            if (!$role) {
                return ['code' => 1, 'msg' => 'Unknown error'];
            }
        } else {
            $exists = $this->roleRepository()->findByCode($code);
            if ($exists) {
                return ['code' => 1, 'msg' => 'Unknown error'];
            }
            $role = new AdminRole();
        }

        if ($id <= 0 || (string)($role->code ?? '') !== $code) {
            $exists = $this->roleRepository()->findByCode($code);
            if ($exists && (int)$exists->id !== (int)($role->id ?? 0)) {
                return ['code' => 1, 'msg' => 'Unknown error'];
            }
        }

        $role->name = $name;
        $role->code = $code;
        $role->permissions = json_encode($normalizedPermissions, JSON_UNESCAPED_UNICODE);
        $role->status = $status;
        $this->roleRepository()->save($role);

        return ['code' => 0, 'msg' => ''];
    }

    /**
     * 删除角色
     * @param int $id
     * @return array
     */
    public function delete(int $id): array
    {
        $role = $this->roleRepository()->findById($id);
        if (!$role) {
            return ['code' => 1, 'msg' => 'Unknown error'];
        }
        if ((string)$role->code === 'super_admin') {
            return ['code' => 1, 'msg' => ''];
        }
        if ($this->roleRepository()->inUse($id)) {
            return ['code' => 1, 'msg' => ''];
        }

        $this->roleRepository()->delete($role);
        return ['code' => 0, 'msg' => ''];
    }

    /**
     * 规色权限归一化
     * @param $permissions
     * @return array
     */
    private function normalizePermissionsPayload($permissions): array
    {
        $normalized = [];

        if (is_array($permissions)) {
            foreach ($permissions as $permission) {
                if (!is_string($permission)) {
                    continue;
                }
                $permission = trim($permission);
                if ($permission !== '') {
                    $normalized[] = $permission;
                }
            }
            return $normalized;
        }

        if (is_string($permissions) && trim($permissions) !== '') {
            $decoded = json_decode(trim($permissions), true);
            if (is_array($decoded)) {
                foreach ($decoded as $permission) {
                    if (!is_string($permission)) {
                        continue;
                    }
                    $permission = trim($permission);
                    if ($permission !== '') {
                        $normalized[] = $permission;
                    }
                }
            }
        }

        return $normalized;
    }

    /**
     * 获取角色权限服务
     * @return CoreAdminPermissionService
     */

    private function permissionService(): CoreAdminPermissionService
    {
        return $this->app->make(CoreAdminPermissionService::class);
    }

    /**
     * 获取角色仓库
     * @return RoleRepository
     */

    private function roleRepository(): RoleRepository
    {
        return $this->app->make(RoleRepository::class);
    }
}