<?php

namespace App\Controllers\Api\V1;

use App\Controllers\BaseController;
use App\Exceptions\ValidationException;
use App\Services\Auth\AuthService;

class AuthController extends BaseController
{
    private AuthService $auth;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->auth = new AuthService();
    }

    public function registerCandidate()
    {
        $rules = [
            'name'     => 'required|min_length[2]|max_length[150]',
            'email'    => 'required|valid_email',
            'password' => 'required|min_length[8]',
            'phone'    => 'permit_empty|min_length[7]|max_length[30]',
        ];

        if (! $this->validate($rules)) {
            return $this->jsonValidationError($this->validator->getErrors());
        }

        try {
            $user = $this->auth->registerCandidate($this->request->getJSON(true));
        } catch (ValidationException $e) {
            return $this->jsonValidationError($e->getErrors());
        }

        $tokens = $this->auth->issueTokenPair($user);

        return $this->jsonSuccess([
            'user'   => $user->toArray(),
            'tokens' => $tokens,
        ], [], 201);
    }

    public function registerAgency()
    {
        $rules = [
            'owner_name'    => 'required|min_length[2]|max_length[150]',
            'email'         => 'required|valid_email',
            'password'      => 'required|min_length[8]',
            'company_name'  => 'required|min_length[2]|max_length[150]',
            'company_email' => 'permit_empty|valid_email',
        ];

        if (! $this->validate($rules)) {
            return $this->jsonValidationError($this->validator->getErrors());
        }

        $result = $this->auth->registerAgencyOwner($this->request->getJSON(true));
        $tokens = $this->auth->issueTokenPair($result['user']);

        return $this->jsonSuccess([
            'user'   => $result['user']->toArray(),
            'agency' => $result['agency']->toArray(),
            'tokens' => $tokens,
        ], [], 201);
    }

    public function login()
    {
        $rules = [
            'email'    => 'required|valid_email',
            'password' => 'required',
        ];

        if (! $this->validate($rules)) {
            return $this->jsonValidationError($this->validator->getErrors());
        }

        $input = $this->request->getJSON(true);

        $user = $this->auth->attemptLogin(
            $input['email'],
            $input['password'],
            $this->request->getIPAddress(),
            $this->request->getUserAgent()->getPlatform() ?? 'unknown',
            $this->request->getUserAgent()->getBrowser() ?? 'unknown'
        );

        if (! $user) {
            return $this->jsonError([['code' => 'INVALID_CREDENTIALS', 'message' => 'Invalid email or password, or account not active.']], 401);
        }

        $tokens = $this->auth->issueTokenPair($user);

        return $this->jsonSuccess([
            'user'   => $user->toArray(),
            'tokens' => $tokens,
        ]);
    }

    public function refresh()
    {
        $refreshToken = $this->request->getJSON(true)['refresh_token'] ?? null;

        if (! $refreshToken) {
            return $this->jsonError([['code' => 'MISSING_TOKEN', 'message' => 'refresh_token is required.']], 400);
        }

        $jwt = new \App\Services\Auth\JwtService();
        $result = $jwt->verifyAndRotateRefreshToken($refreshToken);

        if (! $result) {
            return $this->jsonError([['code' => 'INVALID_REFRESH_TOKEN', 'message' => 'Refresh token is invalid, expired, or revoked.']], 401);
        }

        $tokens = $this->auth->issueTokenPair($result['user']);

        return $this->jsonSuccess(['tokens' => $tokens]);
    }

    public function logout()
    {
        $user = $this->currentUser();
        $refreshToken = $this->request->getJSON(true)['refresh_token'] ?? null;
        $this->auth->logout($user->id, $refreshToken);

        return $this->jsonSuccess(['message' => 'Logged out.']);
    }

    public function me()
    {
        return $this->jsonSuccess(['user' => $this->currentUser()->toArray()]);
    }
}
