<?php

declare(strict_types=1);

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Services\ApiClient;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;

abstract class BaseAdminController extends BaseController
{
    protected ApiClient $apiClient;

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger): void
    {
        parent::initController($request, $response, $logger);
        helper('rbac');
        $this->apiClient = new ApiClient();
    }

    /**
     * RBAC fitur (`Config\AdminAccess` + `canAccess()`). Null = boleh lanjut.
     */
    protected function enforceAccess(string $feature): ?ResponseInterface
    {
        if (canAccess($feature)) {
            return null;
        }

        if ($this->request->isAJAX()) {
            return $this->response->setStatusCode(403)->setJSON([
                'status' => 0,
                'pesan'  => 'Akses ditolak untuk peran Anda.',
            ]);
        }

        return redirect()->to(site_url('admin'))->with('error', 'Akses ditolak untuk peran Anda.');
    }

    protected function adminToken(): ?string
    {
        $t = session()->get('admin_mobile_token');

        return is_string($t) && $t !== '' ? $t : null;
    }

    /**
     * @param array<string, scalar|null> $extra
     *
     * @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
     */
    protected function apiMobile(string $method, array $extra = []): array
    {
        $token = $this->adminToken();
        if ($token === null) {
            return [
                'transport_ok' => false,
                'http_code'    => 0,
                'json'         => null,
                'error'        => 'Belum login — tidak ada token API.',
                'raw'          => '',
            ];
        }

        return $this->apiClient->postMobileWithToken($method, $token, $extra);
    }

    /**
     * @param array<string, scalar|null> $query
     *
     * @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
     */
    protected function apiAdminGet(string $path, array $query = []): array
    {
        $token = $this->adminToken();
        if ($token === null) {
            return [
                'transport_ok' => false,
                'http_code'    => 0,
                'json'         => null,
                'error'        => 'Belum login — tidak ada token API.',
                'raw'          => '',
            ];
        }

        return $this->apiClient->getAdmin($path, $token, $query);
    }

    /**
     * @param array<string, scalar|null> $form
     *
     * @return array{transport_ok: bool, http_code: int, json: array<string, mixed>|null, error: string|null, raw: string}
     */
    protected function apiAdminPost(string $path, array $form = []): array
    {
        $token = $this->adminToken();
        if ($token === null) {
            return [
                'transport_ok' => false,
                'http_code'    => 0,
                'json'         => null,
                'error'        => 'Belum login — tidak ada token API.',
                'raw'          => '',
            ];
        }

        return $this->apiClient->postAdmin($path, $token, $form);
    }
}
