<?php

declare(strict_types=1);

namespace Dealerdirect\Agreements\Pdf\Templates;

use Cloudinary\Cloudinary;
use Cloudinary\Transformation\Delivery;
use Cloudinary\Transformation\Gravity;
use Cloudinary\Transformation\Quality;
use Cloudinary\Transformation\Resize;
use Dealerdirect\Agreements\Utils\GeneralUtils;
use Dealerdirect\Agreements\Utils\VehicleData;
use DealerDirect\Generic\Category\VehicleType;
use Dealerdirect\Generic\Enums\SiteReference;

/**
 * @property \Dealerdirect\Agreements\DataObjects\PurchaseAgreement $data
 */
final class PurchaseAgreement extends AbstractTemplate
{
    private ?Cloudinary $cloudinary = null;

    public function setCloudinary(Cloudinary $cloudinary): void
    {
        $this->cloudinary = $cloudinary;
    }

    public function getImage(): string
    {
        if (null === $this->cloudinary) {
            throw new \LogicException('Cloudinary is not set');
        }

        if (null === $this->data->vehicle->image) {
            return '';
        }

        $url = (string) $this->cloudinary
            ->image($this->data->vehicle->image)
            ->delivery(Delivery::quality(Quality::auto()))
            // ->resize(Resize::fill(240, 200, Gravity::ocrText()))
            ->resize(Resize::fill(240, 200, Gravity::auto()))
            ->signUrl()
            ->toUrl();

        if (empty($contents = file_get_contents($url))) {
            return '';
        }

        return 'data:image/jpeg;base64,' . base64_encode($contents);
    }

    public function getTemplate(): string
    {
        return 'purchase-agreement.php';
    }

    /**
     * @return array<string,string> Title-value pairs of the company data
     */
    public function getContactDetails(): array
    {
        $consumer = $this->data->consumer;

        $name = $consumer->getName(true);
        if ($consumer->companyNameSeller) {
            $name .= " ({$consumer->companyNameSeller})";
        }

        return [
            $this->translate('labels.name') => $name,
            $this->translate('labels.street_and_number') => "{$consumer->streetName} {$consumer->houseNumber}",
            $this->translate('labels.zip_code_and_city') => "{$consumer->zipCode} {$consumer->city}",
            $this->translate('labels.phone_numbers') => GeneralUtils::combinePhoneNumbers(
                $consumer->phoneNumbers[0] ?? '',
                $consumer->phoneNumbers[1] ?? '',
                $consumer->country,
            ),
            $this->translate('labels.country') => $this->translate("general.country.{$consumer->country}"),
            $this->translate('labels.email') => implode(', ', $consumer->getValidEmails()),
        ];
    }

    /**
     * @return array<string,string> Title-value pairs of the vehicle data
     */
    public function getVehicleData(): array
    {
        return VehicleData::for(
            $this->translator,
            $this->data->vehicle,
            SiteReference::from($this->data->siteReference)
        );
    }

    /**
     * @return ?string Comma-separated list of vehicle accessories or null if the vehicle is a bicycle
     */
    public function getVehicleAccessories(): ?string
    {
        if (VehicleType::BICYCLE === $this->data->vehicleType) {
            return null;
        }

        if (empty($accessories = $this->data->vehicle->options)) {
            return $this->translate('labels.unknown');
        }

        return implode(', ', array_map(
            fn(int $accessory) => $this->translate("options.$accessory"),
            $accessories
        ));
    }

    /**
     * @return array<int,array<string,string>>
     */
    public function getChecklist(): ?array
    {
        $checklist = $this->data->vehicle->getChecklist($this->locale);
        if (empty($checklist)) {
            return null;
        }

        $amount = count($checklist);
        $partitions = [];
        foreach ($checklist as $index => $item) {
            $partition = (int) ($index / ($amount / 2));
            $partitions[$partition][] = $item;
        }

        return $partitions;
    }

    /**
     * @return array<string,string>
     */
    public function getComments(): array
    {
        $comments = [];
        if (!empty($this->data->internalComments)) {
            $comments[$this->translate('labels.internal_comment')] = nl2br($this->data->internalComments);
        }

        if (!empty($this->data->consumerComments)) {
            $comments[$this->translate('labels.consumer_comment')] = nl2br($this->data->consumerComments);
        }

        return $comments;
    }

    public function getLogo(): string
    {
        return 'data:image/png;base64,' . base64_encode(
            file_get_contents($this->getResourcesFolder() . '/img/logo_dealerdirect.png')
        );
    }
}
