<?php

namespace App;

use App\Facades\Settings;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Mtc\MercuryDataModels\CarConfiguratorModel;
use Mtc\MercuryDataModels\Page;
use Mtc\MercuryDataModels\NewCar;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleOffer;

class SiteRepository
{
    public function vehicleUrl(Vehicle $vehicle, bool $withAccess = false, bool $absolute = true): ?string
    {
        try {
            $urlPath = $vehicle->urlPath();
            if ($withAccess) {
                $urlPath .= $this->accessParam($vehicle);
            }

            if ($absolute && Settings::get('vehicles-url-path-include-www')) {
                $base_url = $this->baseUrl();

                if (stripos($base_url, '//www.') === false) {
                    $base_url = str_replace('//', '//www.', $base_url);
                }

                return $base_url . $urlPath;
            }

            return $absolute ? $this->baseUrl() . $urlPath : $urlPath;
        } catch (ModelNotFoundException $exception) {
            return null;
        }
    }

    public function pageUrl(Page $page, bool $withAccess = false, bool $absolute = true): ?string
    {
        return $this->buildUrl(
            $page->urlPath() === '/home' ? '/' : $page->urlPath(),
            $page,
            $withAccess,
            $absolute
        );
    }

    public function offerUrl(VehicleOffer $offer, bool $withAccess = false, bool $absolute = true): ?string
    {
        return $this->buildUrl($offer->urlPath(), $offer, $withAccess, $absolute);
    }

    public function configuratorUrl(CarConfiguratorModel $car, bool $withAccess = false, bool $absolute = true): ?string
    {
        return $this->buildUrl($car->urlPath(), $car, $withAccess, $absolute);
    }

    public function newCarUrl(NewCar $newCar, bool $withAccess = false, bool $absolute = true): ?string
    {
        return $this->buildUrl($newCar->urlPath(), $newCar, $withAccess, $absolute);
    }

    public function url(string $endpoint = '', bool $absolute = true): ?string
    {
        return $this->buildUrl('/' . ltrim($endpoint, '/'), null, false, $absolute);
    }

    public function baseUrl(): string
    {
        $domain = tenant()->domains()
            ->orderByDesc('primary')
            ->firstOrFail();

        $protocol = config('app.env') === 'local' ? 'http://' : 'https://';

        return $protocol . $domain->domain;
    }

    private function accessParam(Model $model): string
    {
        return  '?' . http_build_query([
            'a' => base64_encode($model->id . '-' . $model->slug),
        ]);
    }

    private function buildUrl(
        string $path,
        ?Model $model = null,
        bool $withAccess = false,
        bool $absolute = true
    ): ?string {
        try {
            if ($withAccess && $model) {
                $path .= $this->accessParam($model);
            }

            return $absolute ? $this->baseUrl() . $path : $path;
        } catch (ModelNotFoundException $exception) {
            return null;
        }
    }
}
