<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Throwable;

class RecaptchaV3
{
    /**
     * Google reCAPTCHA v3 server-side verify
     *
     * @return array Google response array
     */
    public function verify(string $token, string $expectedAction, ?string $ip = null): array
    {
        $secret = (string) config('services.recaptcha.secret');

        // secret 없으면 무조건 실패(운영 안전)
        if ($secret === '') {
            if ($this->isDev()) {
                Log::warning('[recaptcha] secret missing', [
                    'expected_action' => $expectedAction,
                ]);
            }
            return [
                'success' => false,
                'error-codes' => ['missing-input-secret'],
            ];
        }

        try {
            $resp = Http::asForm()
                ->timeout(3)          // 너무 길게 잡지 말기
                ->connectTimeout(2)
                ->retry(1, 200)       // 네트워크 순간 오류 대비(1회만)
                ->post('https://www.google.com/recaptcha/api/siteverify', [
                    'secret'   => $secret,
                    'response' => $token,
                    'remoteip' => $ip,
                ]);

            $data = $resp->json();

            if (!is_array($data)) {
                if ($this->isDev()) {
                    Log::warning('[recaptcha] invalid json', [
                        'status' => $resp->status(),
                        'body_snippet' => mb_substr((string)$resp->body(), 0, 200),
                        'expected_action' => $expectedAction,
                    ]);
                }

                return [
                    'success' => false,
                    'error-codes' => ['invalid-json'],
                ];
            }

            // (선택) 개발환경에서만 핵심만 로깅 (token/secret 절대 로그 금지)
            if ($this->isDev()) {
                Log::info('[recaptcha] verify ok', [
                    'expected_action' => $expectedAction,
                    'success' => $data['success'] ?? null,
                    'score' => $data['score'] ?? null,
                    'action' => $data['action'] ?? null,
                    'hostname' => $data['hostname'] ?? null,
                    'error_codes' => $data['error-codes'] ?? null,
                ]);
            }

            return $data;

        } catch (Throwable $e) {
            if ($this->isDev()) {
                Log::error('[recaptcha] verify exception', [
                    'expected_action' => $expectedAction,
                    'message' => $e->getMessage(),
                ]);
            }

            return [
                'success' => false,
                'error-codes' => ['http-exception'],
            ];
        }
    }

    /**
     * 정책 판단: success + action 일치 + score >= min_score
     */
    public function isPass(array $data, string $expectedAction): bool
    {
        if (!($data['success'] ?? false)) return false;

        // action은 v3에서 꼭 맞춰주는 게 좋음
        if (($data['action'] ?? '') !== $expectedAction) return false;

        $min = (float) config('services.recaptcha.min_score', 0.5);
        $score = (float) ($data['score'] ?? 0);

        return $score >= $min;
    }

    private function isDev(): bool
    {
        // 네 환경명에 맞춰 추가 가능: staging 등
        return app()->environment(['local', 'development', 'staging']);
    }
}
