<?php
declare(strict_types=1);

namespace App\Modules\ParentAuth\Controllers\Api;

use App\Core\ApiController;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Core\ApiErrorCodes;
use App\Modules\ParentAuth\Services\ParentAuthService;

final class ParentTokenController extends ApiController
{
    private ParentAuthService $authService;

    public function __construct()
    {
        $this->authService = new ParentAuthService();
    }

    public function login(Request $request): Response
    {
        $input = $request->jsonBody();
        $phone = trim((string) ($input['phone'] ?? ''));
        $pin = (string) ($input['pin'] ?? '');
        $deviceInfo = $input['device_info'] ?? null;

        if ($phone === '' || $pin === '') {
            return $this->errorResponse('رقم الهاتف والرمز مطلوبان', 422, [], ApiErrorCodes::VALIDATION_FAILED);
        }

        $parent = $this->authService->findByPhone($phone);

        if (!$parent || !$this->authService->verifyPin($parent, $pin)) {
            return $this->errorResponse('رقم الهاتف أو الرمز غير صحيح', 401, [], ApiErrorCodes::AUTH_INVALID);
        }

        $tokenData = $this->authService->createToken((int) $parent['id'], 'mobile', $deviceInfo);

        return $this->successResponse([
            'token' => $tokenData['token'],
            'expires_at' => $tokenData['expires_at'],
            'parent' => [
                'id' => (int) $parent['id'],
                'name' => $parent['full_name_ar'],
                'phone' => $parent['phone'],
            ],
        ], 201);
    }

    public function otpRequest(Request $request): Response
    {
        $input = $request->jsonBody();
        $phone = trim((string) ($input['phone'] ?? ''));

        if ($phone === '') {
            return $this->errorResponse('رقم الهاتف مطلوب', 422, [], ApiErrorCodes::VALIDATION_FAILED);
        }

        $parent = $this->authService->findByPhone($phone);

        if ($parent) {
            $this->authService->generateOtp((int) $parent['id']);
        }

        return $this->successResponse(['sent' => true]);
    }

    public function otpVerify(Request $request): Response
    {
        $input = $request->jsonBody();
        $phone = trim((string) ($input['phone'] ?? ''));
        $otp = (string) ($input['otp'] ?? '');
        $deviceInfo = $input['device_info'] ?? null;

        if ($phone === '' || $otp === '') {
            return $this->errorResponse('رقم الهاتف ورمز التحقق مطلوبان', 422, [], ApiErrorCodes::VALIDATION_FAILED);
        }

        $parent = $this->authService->findByPhone($phone);

        if (!$parent) {
            return $this->errorResponse('رمز التحقق غير صحيح', 401, [], ApiErrorCodes::AUTH_INVALID);
        }

        $parentFresh = App::getInstance()->db()->selectOne(
            "SELECT * FROM parent_accounts WHERE id = ? AND is_active = 1",
            [(int) $parent['id']]
        );

        if (!$parentFresh || !$this->authService->verifyOtp($parentFresh, $otp)) {
            return $this->errorResponse('رمز التحقق غير صحيح أو منتهي الصلاحية', 401, [], ApiErrorCodes::AUTH_INVALID);
        }

        $tokenData = $this->authService->createToken((int) $parentFresh['id'], 'mobile', $deviceInfo);

        return $this->successResponse([
            'token' => $tokenData['token'],
            'expires_at' => $tokenData['expires_at'],
            'parent' => [
                'id' => (int) $parentFresh['id'],
                'name' => $parentFresh['full_name_ar'],
                'phone' => $parentFresh['phone'],
            ],
        ], 201);
    }

    public function refresh(Request $request): Response
    {
        $parent = App::getInstance()->currentParent();
        $currentToken = $request->bearerToken();

        $tokenData = $this->authService->refreshToken($currentToken, (int) $parent->id);

        return $this->successResponse([
            'token' => $tokenData['token'],
            'expires_at' => $tokenData['expires_at'],
        ], 201);
    }

    public function logout(Request $request): Response
    {
        $token = $request->bearerToken();
        $this->authService->revokeToken($token);

        return $this->successResponse(['logged_out' => true]);
    }
}
