<?php

declare(strict_types=1);

namespace Dealerdirect\Agreements;

use Cloudinary\Cloudinary;
use Dealerdirect\Agreements\Models\AbstractModel;
use Dealerdirect\Agreements\Models\CarBeModel;
use Dealerdirect\Agreements\Models\CarNlModel;
use Dealerdirect\Agreements\Models\MotorbikeModel;
use Dealerdirect\Agreements\Pdf\Generator;
use DealerDirect\Generic\Category\Site;
use Doctrine\DBAL\Connection;
use Dompdf\Dompdf;
use Illuminate\Contracts\Filesystem\Filesystem;

final class Factory
{
    public static function forSalesAgreement(
        Filesystem $storage,
        AbstractModel $model,
        ?Dompdf $dompdf = null
    ): Factories\SalesAgreementFactory {
        $data = $model->getSaleData();
        $template = Factories\SalesAgreementFactory::getSalesAgreementTemplate($data);
        $dompdf ??= Generator::applyOptionsToPdf(new Dompdf(), $template->getResourcesFolder());
        $generator = new Generator($dompdf, $template);

        return new Factories\SalesAgreementFactory($data, $storage, $generator);
    }

    public static function forPurchaseAgreement(
        Filesystem $storage,
        AbstractModel $model,
        Cloudinary $cloudinary,
        ?Dompdf $dompdf = null
    ): Factories\PurchaseAgreementFactory {
        $data = $model->getPurchaseData();
        $template = Factories\PurchaseAgreementFactory::getPurchaseAgreementTemplate($data, $cloudinary);
        $dompdf ??= Generator::applyOptionsToPdf(new Dompdf(), $template->getResourcesFolder());
        $generator = new Generator($dompdf, $template);

        return new Factories\PurchaseAgreementFactory($data, $storage, $generator);
    }

    public static function getModelByReference(int $reference, Connection $connection, int $deliverId): AbstractModel
    {
        return match ($reference) {
            Site::REF_CAR_NL,
            Site::REF_CAR_MARKTPLAATS_NL => new CarNlModel($connection, $deliverId),
            Site::REF_CAR_BE_NL => new CarBeModel($connection, $deliverId),
            Site::REF_MOTO_NL,
            Site::REF_MOTO_BE,
            Site::REF_MOTO_DE,
            Site::REF_BICYCLE_NL,
            Site::REF_SCOOTER_NL => new MotorbikeModel($connection, $deliverId),
            default => throw new \Exception("Error, reference '$reference' is not defined!"),
        };
    }
}
