<?php

namespace App;

use Illuminate\Support\Facades\Http;
use Mtc\MercuryDataModels\ValuationAdjustment;
use Mtc\MercuryDataModels\VehicleValuation;
use Illuminate\Database\Eloquent\Builder;
use Mtc\VehicleValuation\Contracts\IPRestrictedValuationDriver;
use Mtc\VehicleValuation\Contracts\ValuationResponse;

class ValuationRepository extends \Mtc\VehicleValuation\ValuationRepository
{
    #[\Override]
    protected function getQuery(): Builder
    {
        return VehicleValuation::query();
    }

    #[\Override]
    public function get(
        string $registration,
        int $mileage,
        ?string $variant = null,
        ?string $cosmetic_condition = null,
        ?array $data = null
    ) {
        if ($this->isIPRestrictedProvider()) {
            if ($this->requestViaAdmin($registration, $mileage, $variant)) {
                return $this->getLocalValuation($registration, $mileage);
            }
            throw new \Exception('Unable to retrieve valuation');
        }

        return parent::get($registration, $mileage, $variant, $cosmetic_condition, $data);
    }
    /**
     * Store a valuation result from API
     *
     * @param ValuationResponse $valuation
     * @return Builder|Model
     */
    #[\Override]
    protected function store(ValuationResponse $valuation): ?VehicleValuation
    {
        return $this->adjustValuation(parent::store($valuation));
    }

    protected function adjustValuation($valuation)
    {
        $valuationAdjustments = ValuationAdjustment::query()
            ->with('rules')
            ->active()
            ->get();

        foreach ($valuationAdjustments as $valuationAdjustment) {
            if ($valuationAdjustment->evaluate($valuation)) {
                $valuation->adjust($valuationAdjustment);
                break;
            }
        }

        return $valuation;
    }

    protected function isIPRestrictedProvider(): bool
    {
        return $this->getApiDriver() instanceof IPRestrictedValuationDriver;
    }

    protected function requestViaAdmin(string $registration, int $mileage, ?string $variant): bool
    {
        $headers = [
            'X-Tenant' => tenant('id'),
            'Authorization' => base64_encode(tenant('id') . ':' . config('app.proxy_token'))
        ];
        $admin_endpoint = config('app.admin_url') . '/api/proxy/valuations';
        return Http::withHeaders($headers)
            ->post($admin_endpoint, [
                'registration_number' => $registration,
                'mileage' => $mileage,
                'variant_id' => $variant
            ])
            ->successful();
    }
}
