<?php

namespace App\Services\Billing;

use App\Models\CrmPurchase;
use Illuminate\Support\Str;

class OneTimePurchaseService
{
    public function __construct(private readonly BillingClient $billing)
    {
    }

    /** @return array<string, mixed>|null */
    public function product(string $productKey): ?array
    {
        $product = config('crm_products.'.$productKey);

        return is_array($product) ? $product : null;
    }

    public function hasPurchased(string $ownerRef, string $productKey): bool
    {
        return CrmPurchase::has($ownerRef, $productKey);
    }

    public function priceMinor(string $productKey): int
    {
        return (int) ($this->product($productKey)['price_minor'] ?? 0);
    }

    public function purchase(string $ownerRef, string $productKey): bool
    {
        if ($this->hasPurchased($ownerRef, $productKey)) {
            return true;
        }

        $product = $this->product($productKey);
        if (! $product) {
            return false;
        }

        $costMinor = (int) ($product['price_minor'] ?? 0);

        if ($costMinor > 0) {
            try {
                if (! $this->billing->canAfford($ownerRef, $costMinor)) {
                    return false;
                }

                $charged = $this->billing->debit(
                    $ownerRef,
                    $costMinor,
                    'purchase',
                    'crm-purchase-'.$productKey.'-'.$ownerRef,
                    'CRM: '.($product['name'] ?? $productKey),
                );

                if (! $charged) {
                    return false;
                }
            } catch (\Throwable) {
                return false;
            }
        }

        CrmPurchase::create([
            'owner_ref' => $ownerRef,
            'product_key' => $productKey,
            'cost_minor' => $costMinor,
            'purchased_at' => now(),
        ]);

        return true;
    }
}
