<?php

namespace App\Filters;

use App\Libraries\ChurchContext;
use App\Libraries\PermissionService;
use App\Libraries\TokenService;
use App\Models\PlatformAdminModel;
use App\Models\UserModel;
use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class AuthFilter implements FilterInterface
{
    public function before(RequestInterface $request, $arguments = null): mixed
    {
        $authHeader = $request->getHeaderLine('Authorization');

        if (!$authHeader || !str_starts_with($authHeader, 'Bearer ')) {
            return $this->unauthorized('Missing or malformed Authorization header');
        }

        $raw      = substr($authHeader, 7);
        $service  = new TokenService();
        $tokenRow = $service->validate($raw);

        if (!$tokenRow) {
            return $this->unauthorized('Invalid or expired token');
        }

        $ctx = ChurchContext::getInstance();
        PermissionService::clearCache();

        if (!empty($tokenRow['is_platform_admin'])) {
            $adminModel = new PlatformAdminModel();
            $admin      = $adminModel->find($tokenRow['platform_admin_id']);

            if (!$admin || !$admin['is_active']) {
                return $this->unauthorized('Account inactive');
            }

            $ctx->setIsPlatformAdmin(true);
            $ctx->setPlatformAdmin($admin);
        } else {
            $userModel = new UserModel();
            $user      = $userModel->find($tokenRow['user_id']);

            if (!$user || !$user['is_active']) {
                return $this->unauthorized('Account inactive');
            }

            $ctx->setUser($user);
            $ctx->setChurchId((int) $user['church_id']);
        }

        return null;
    }

    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null): ResponseInterface
    {
        return $response;
    }

    private function unauthorized(string $message): ResponseInterface
    {
        return response()
            ->setStatusCode(401)
            ->setContentType('application/json')
            ->setJSON(['status' => 'error', 'message' => $message]);
    }
}
