<?php

namespace App\Services;

use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

class OtpService
{
    public function send(string $phone, string $purpose = 'login', ?string $ipAddress = null): array
    {
        $otp = config('app.debug') ? env('PRONTO_DEMO_OTP', '123456') : (string) random_int(100000, 999999);

        DB::table('auth_otps')->insert([
            'phone' => $phone,
            'purpose' => $purpose,
            'otp_hash' => Hash::make($otp),
            'expires_at' => now()->addMinutes(10),
            'ip_address' => $ipAddress,
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        DB::table('communication_logs')->insert([
            'channel' => 'sms',
            'template_key' => 'otp',
            'recipient' => $phone,
            'payload_json' => json_encode(['otp' => config('app.debug') ? $otp : 'hidden']),
            'provider' => 'local',
            'status' => config('app.debug') ? 'sent_demo' : 'queued',
            'sent_at' => now(),
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return [
            'phone' => $phone,
            'purpose' => $purpose,
            'expires_in_seconds' => 600,
            'demo_otp' => config('app.debug') ? $otp : null,
        ];
    }

    public function verify(string $phone, string $otp, string $purpose = 'login'): bool
    {
        $record = DB::table('auth_otps')
            ->where('phone', $phone)
            ->where('purpose', $purpose)
            ->whereNull('verified_at')
            ->where('expires_at', '>', Carbon::now())
            ->latest('id')
            ->first();

        if (! $record) {
            return false;
        }

        DB::table('auth_otps')->where('id', $record->id)->increment('attempts');

        if (! Hash::check($otp, $record->otp_hash)) {
            return false;
        }

        DB::table('auth_otps')->where('id', $record->id)->update([
            'verified_at' => now(),
            'updated_at' => now(),
        ]);

        return true;
    }
}
