<?php

declare(strict_types=1);

namespace SHServ\Integrations\GAuth;

use SHServ\Integrations\GAuth\AuthService;
use SHServ\Integrations\GAuth\PermissionResolver;

trait AuthControllerTrait
{
    /**
     * Require authenticated user. Returns error response if not auth.
     */
    protected function require_auth(): ?string
    {
        if (!$this->resolve_user()) {
            return $this->utils()->response_error('unauthenticated', [], [], 401);
        }
        return null;
    }

    /**
     * Require specific permission. Returns error response if denied.
     */
    protected function require_permission(string $permissionSlug): ?string
    {
        $authError = $this->require_auth();
        if ($authError !== null) {
            return $authError;
        }

        $user = $this->resolve_user();
        if (!$user) {
            return $this->utils()->response_error('unauthenticated', [], [], 401);
        }

        $resolver = new PermissionResolver();
        if (!$resolver->has($user['id'], $user['system_role'], $permissionSlug)) {
            return $this->utils()->response_error('permission_denied', [$permissionSlug], [], 403);
        }

        return null;
    }

    /**
     * Resolve current user from session or Bearer token.
     */
    protected function resolve_user(): ?array
    {
        if (session_status() === PHP_SESSION_NONE) {
            @session_start();
        }

        // 1. Session-based auth
        $sessionUserId = $_SESSION['shserv_user_id'] ?? null;
        if ($sessionUserId) {
            return $this->load_user_by_id((int) $sessionUserId);
        }

        // 2. Bearer token auth
        $bearer = $this->get_bearer_token();
        if ($bearer) {
            return $this->resolve_user_by_bearer($bearer);
        }

        return null;
    }

    /**
     * Extract Bearer token from Authorization header.
     */
    protected function get_bearer_token(): ?string
    {
        $header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
        if (str_starts_with($header, 'Bearer ')) {
            return substr($header, 7);
        }
        return null;
    }

    /**
     * Resolve user by OAuth access token via local session table.
     */
    protected function resolve_user_by_bearer(string $token): ?array
    {
        $tb = app()->thin_builder;
        $result = $tb->select('shserv_sessions', ['user_id'], [['access_token', '=', $token]]);
        if ($result) {
            return $this->load_user_by_id((int) $result[0]['user_id']);
        }
        return null;
    }

    /**
     * Load user row from shserv_users by local ID.
     */
    protected function load_user_by_id(int $userId): ?array
    {
        $tb = app()->thin_builder;
        $result = $tb->select(
            'shserv_users',
            ['id', 'gauth_user_id', 'email', 'display_name', 'avatar_url', 'system_role', 'status'],
            [['id', '=', $userId]]
        );
        return $result ? $result[0] : null;
    }

    /**
     * Get current user data (session or Bearer).
     */
    protected function get_current_user(): ?array
    {
        return $this->resolve_user();
    }

    /**
     * Get effective permissions for current user.
     */
    protected function get_current_permissions(): array
    {
        $user = $this->resolve_user();
        if (!$user) {
            return [];
        }

        $resolver = new PermissionResolver();
        return $resolver->resolve((int) $user['id'], $user['system_role']);
    }
}
