<?php

namespace App\Services;

use App\Exceptions\CouponPoolExhaustedException;
use App\Models\Coupon;
use Illuminate\Database\UniqueConstraintViolationException;

class CouponService
{
    public function __construct(
        private CouponCodePool $couponCodePool,
    ) {}

    public function findOrCreateForPhone(string $phone): Coupon
    {
        $existing = Coupon::query()->where('phone', $phone)->first();

        if ($existing) {
            return $existing;
        }

        return $this->createWithUniqueCode($phone);
    }

    private function createWithUniqueCode(string $phone): Coupon
    {
        for ($attempt = 0; $attempt < 10; $attempt++) {
            $code = $this->couponCodePool->pickRandom();

            if ($code === null) {
                throw new CouponPoolExhaustedException;
            }

            try {
                return Coupon::query()->create([
                    'phone' => $phone,
                    'code' => $code,
                ]);
            } catch (UniqueConstraintViolationException) {
                continue;
            }
        }

        throw new CouponPoolExhaustedException;
    }
}
