<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\StorePermissionRequest;
use App\Http\Requests\UpdatePermissionRequest;
use hg\apidoc\annotation as Apidoc;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Permission;
use Spatie\Permission\Models\Role;

#[Apidoc\Title('权限管理')]
class PermissionController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api');
        $this->middleware('permission:platform.permissions.view|platform.roles.manage|platform.users.manage,api')->only(['index', 'show']);
        $this->middleware('permission:platform.permissions.manage,api')->only(['store', 'update', 'destroy', 'syncRolePermissions']);
    }

    #[Apidoc\Title('权限列表'), Apidoc\Method('GET'), Apidoc\Url('/permissions')]
    public function index(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'per_page' => ['nullable', 'integer', 'min:1', 'max:200'],
        ]);
        $perPage = (int) ($validated['per_page'] ?? 20);
        $permissions = Permission::query()->latest()->paginate($perPage);

        $permissions->getCollection()->transform(function (Permission $permission) {
            return $this->applyDefaultMeta($permission);
        });

        return response()->json(['code' => 0, 'message' => 'ok', 'data' => $permissions]);
    }

    #[Apidoc\Title('创建权限'), Apidoc\Method('POST'), Apidoc\Url('/permissions')]
    public function store(StorePermissionRequest $request): JsonResponse
    {
        $defaultMeta = $this->defaultPermissionMeta($request->string('name')->toString());

        $permission = Permission::query()->create([
            ...$request->safe()->except(['guard_name']),
            'guard_name' => 'api',
            'category' => $request->string('category', $defaultMeta['category'])->toString(),
            'description' => $request->string('description', $defaultMeta['description'])->toString(),
        ]);

        $this->auditLog($request, 'permission_create', ['metadata' => ['target_permission_id' => $permission->id]]);

        return response()->json(['code' => 0, 'message' => 'ok', 'data' => $permission], 201);
    }

    #[Apidoc\Title('权限详情'), Apidoc\Method('GET'), Apidoc\Url('/permissions/{id}')]
    public function show(int $id): JsonResponse
    {
        $permission = Permission::query()->findOrFail($id);

        return response()->json(['code' => 0, 'message' => 'ok', 'data' => $this->applyDefaultMeta($permission)]);
    }

    #[Apidoc\Title('更新权限'), Apidoc\Method('PUT'), Apidoc\Url('/permissions/{id}')]
    public function update(UpdatePermissionRequest $request, int $id): JsonResponse
    {
        $permission = Permission::query()->findOrFail($id);
        $permission->update([
            ...$request->safe()->except(['guard_name']),
            'guard_name' => 'api',
        ]);

        $this->auditLog($request, 'permission_update', ['metadata' => ['target_permission_id' => $permission->id]]);

        return response()->json(['code' => 0, 'message' => 'ok', 'data' => $this->applyDefaultMeta($permission->fresh())]);
    }

    #[Apidoc\Title('删除权限'), Apidoc\Method('DELETE'), Apidoc\Url('/permissions/{id}')]
    public function destroy(Request $request, int $id): JsonResponse
    {
        $permission = Permission::query()->findOrFail($id);
        $this->auditLog($request, 'permission_delete', ['metadata' => ['target_permission_id' => $permission->id]]);
        $permission->delete();

        return response()->json(['code' => 0, 'message' => 'ok', 'data' => null]);
    }

    #[Apidoc\Title('同步角色权限'), Apidoc\Method('PUT'), Apidoc\Url('/roles/{id}/permissions')]
    public function syncRolePermissions(Request $request, int $id): JsonResponse
    {
        $validated = $request->validate([
            'permission_ids' => ['present', 'array'],
            'permission_ids.*' => ['integer', 'exists:permissions,id'],
        ]);

        $role = Role::query()->findOrFail($id);
        $role->syncPermissions($validated['permission_ids']);

        $this->auditLog($request, 'role_permissions_update', ['metadata' => ['target_role_id' => $role->id]]);

        return response()->json(['code' => 0, 'message' => 'ok', 'data' => $role->load('permissions')]);
    }

    private function applyDefaultMeta(Permission $permission): Permission
    {
        $defaults = $this->defaultPermissionMeta((string) $permission->name);
        $dirty = false;

        if (empty($permission->category) || $permission->category === 'general') {
            $permission->category = $defaults['category'];
            $dirty = true;
        }

        if (empty($permission->description)) {
            $permission->description = $defaults['description'];
            $dirty = true;
        }

        if ($dirty) {
            $permission->save();
        }

        return $permission;
    }

    private function defaultPermissionMeta(string $name): array
    {
        $map = [
            'platform.users.view' => ['category' => '用户管理', 'description' => '查看用户列表与详情'],
            'platform.users.manage' => ['category' => '用户管理', 'description' => '创建、修改、删除用户并分配权限'],
            'platform.roles.view' => ['category' => '角色管理', 'description' => '查看角色列表与角色权限'],
            'platform.roles.manage' => ['category' => '角色管理', 'description' => '创建、修改、删除角色'],
            'platform.permissions.view' => ['category' => '权限管理', 'description' => '查看权限配置'],
            'platform.permissions.manage' => ['category' => '权限管理', 'description' => '创建、修改、删除权限规则'],
            'platform.servers.view' => ['category' => '资源管理', 'description' => '查看服务器与资源信息'],
            'platform.servers.manage' => ['category' => '资源管理', 'description' => '维护服务器与资源信息'],
            'platform.accounts.view' => ['category' => '堡垒机账号', 'description' => '查看堡垒机授权账号'],
            'platform.accounts.manage' => ['category' => '堡垒机账号', 'description' => '维护堡垒机授权账号与刷新令牌'],
            'platform.logs.view' => ['category' => '日志审计', 'description' => '查看访问与操作日志'],
            'platform.logs.manage' => ['category' => '日志审计', 'description' => '新增或维护日志数据'],
            'resource.servers.use' => ['category' => '资源使用', 'description' => '发起服务器资源访问与连接操作'],
        ];

        if (isset($map[$name])) {
            return $map[$name];
        }

        if (str_starts_with($name, 'resource.servers.use.')) {
            return [
                'category' => '资源使用',
                'description' => '服务器资源访问权限',
            ];
        }

        return [
            'category' => '通用',
            'description' => '系统权限：'.$name,
        ];
    }
}
