<?php

namespace Mtc\Core\Admin;

use App\Support\EnvironmentHelper;
use Mtc\Core\AdminUser;

class OtpAuthService
{
    /**
     * @var string
     */
    protected string $otpApiUrl;

    /**
     * @param string $apiUrl
     */
    public function __construct(string $apiUrl = 'https://projects.mtcmedia.co.uk/api/vcs/admin-access-check')
    {
        $this->otpApiUrl = $apiUrl;
    }

    /**
     * @param string $username
     *
     * @return bool
     */
    public static function shouldHandleLogin(string $username): bool
    {
        if (EnvironmentHelper::isLocalDevelopment() && config('auth.bypass_otp', false)) {
            return false;
        }

        return preg_match('/@(mtc\.co\.uk|mtcmedia\.co\.uk)$/i', $username)
            || strtolower($username) === 'mtcadmin';
    }

    /**
     * @param string $email
     * @param string $otp
     *
     * @return array
     */
    public function validateOtp(string $email, string $otp): array
    {
        $host = $_SERVER['HTTP_HOST'] ?? 'unknown';
        $domain = preg_replace('/^www\./', '', $host);

        $query = http_build_query([
            'email' => $email,
            'otp' => $otp,
            'domain' => $domain
        ]);

        $url = $this->otpApiUrl . '?' . $query;

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($response) {
            try {
                $data = json_decode($response, true, 512, JSON_THROW_ON_ERROR);

                return [
                    'valid' => $data['valid'] ?? false,
                    'message' => $data['message'] ?? 'Unknown response from OTP check.',
                ];
            } catch (\JsonException $e) {
                return [
                    'valid' => false,
                    'message' => 'Invalid JSON response from OTP service.',
                ];
            }
        }

        return [
            'valid' => false,
            'message' => 'Unable to reach OTP validation service.',
        ];
    }

    /**
     * @param string $username
     * @param string $otp
     * @param callable $setError
     * @param callable $setSession
     *
     * @return bool
     */
    public function attemptOtpLogin(string $username, string $otp, callable $setError, callable $setSession): bool
    {
        if (strtolower($username) === 'mtcadmin') {
            $setError("Login using your own project system email and OTP. Direct 'mtcadmin' login is not permitted.");

            return false;
        }

        $result = $this->validateOtp($username, $otp);

        if (!$result['valid']) {
            $setError($result['message']);

            return false;
        }

        $user = AdminUser::whereUsername('mtcadmin')->first();

        if (!$user) {
            $setError('Invalid username or password.');

            return false;
        }

        $setSession($user->id);

        return true;
    }
}