<?php

declare(strict_types=1);

namespace Dealerdirect\Agreements\DataObjects;

use Dealerdirect\Agreements\Utils\Translator;
use Dealerdirect\Generic\Enums\VehicleType;

final class Conditions implements DataObject
{
    private const KEY_EXTERIOR = 'exterior';
    private const KEY_TECHNICAL = 'technical';
    private const KEY_DRIVABLE = 'drivable';
    private const KEY_DAMAGE_FREE = 'damageFree';
    private const KEY_INTERIOR = 'interior';
    private const KEY_TIRE_PROFILE = 'tireProfile';
    private const KEY_FRONT_TIRE_PROFILE = 'frontTireProfile';
    private const KEY_REAR_TIRE_PROFILE = 'rearTireProfile';
    private const KEY_PROPULSION = 'propulsion';
    private const KEY_GENERAL = 'general';
    private const KEY_BATTERY = 'battery';

    public function __construct(
        public readonly int $exterior,
        public readonly int $technical,
        public readonly int $drivable,
        public readonly int $damageFree,
        public readonly int $interior,
        public readonly int $tireProfile,
        public readonly int $frontTireProfile,
        public readonly int $rearTireProfile,
        public readonly int $propulsion,
        public readonly int $general,
        public readonly int $battery,
    ) {
    }

    public function for(Translator $translator, VehicleType $vehicleType): array
    {
        return match ($vehicleType) {
            VehicleType::CAR,
            VehicleType::CAMPER,
            VehicleType::CARAVAN => $this->forCar($translator),

            VehicleType::MOTORBIKE => $this->forMotorbike($translator),

            VehicleType::SCOOTER => $this->forScooter($translator),

            VehicleType::BICYCLE => $this->forBicycle($translator),

            default => throw new \InvalidArgumentException('Unsupported vehicle type: ' . $vehicleType->value),
        };
    }

    public function forCar(Translator $translator): array
    {
        return $this->render($translator, [
            self::KEY_EXTERIOR,
            self::KEY_INTERIOR,
            self::KEY_TECHNICAL,
            self::KEY_TIRE_PROFILE,
            self::KEY_DAMAGE_FREE,
            self::KEY_DRIVABLE,
        ]);
    }

    public function forMotorbike(Translator $translator): array
    {
        return $this->render($translator, [
            self::KEY_EXTERIOR,
            self::KEY_TECHNICAL,
            self::KEY_FRONT_TIRE_PROFILE,
            self::KEY_REAR_TIRE_PROFILE,
            self::KEY_PROPULSION,
            self::KEY_DAMAGE_FREE,
            self::KEY_DRIVABLE,
        ]);
    }

    public function forScooter(Translator $translator): array
    {
        return $this->render($translator, [
            self::KEY_EXTERIOR,
            self::KEY_TECHNICAL,
            self::KEY_DAMAGE_FREE,
            self::KEY_DRIVABLE,
        ]);
    }

    public function forBicycle(Translator $translator): array
    {
        return $this->render($translator, [
            self::KEY_GENERAL,
            self::KEY_BATTERY,
        ]);
    }

    private function render(Translator $translator, array $keys): array
    {
        $data = [];
        foreach ($keys as $key) {
            $label = $this->getLabel($translator, $key);
            $data[$label] = $this->data($translator, $key);
        }

        return $data;
    }

    private function data(Translator $translator, string $key): string|int
    {
        $value = $this->{$key};

        return match ($key) {
            self::KEY_EXTERIOR,
            self::KEY_TECHNICAL,
            self::KEY_INTERIOR,
            self::KEY_TIRE_PROFILE,
            self::KEY_FRONT_TIRE_PROFILE,
            self::KEY_REAR_TIRE_PROFILE,
            self::KEY_PROPULSION,
            self::KEY_GENERAL,
            self::KEY_BATTERY => $translator->get("vehicle.condition.{$value}"),

            self::KEY_DRIVABLE => $translator->get("general.driveable.{$value}"),
            self::KEY_DAMAGE_FREE => $translator->get("general.damageFree.{$value}"),

            default => throw new \InvalidArgumentException("Unsupported key: $key"),
        };
    }

    private function getLabel(Translator $translator, string $key): string
    {
        $key = match ($key) {
            self::KEY_EXTERIOR => 'body_type',
            self::KEY_TIRE_PROFILE => 'tire_profile',
            self::KEY_FRONT_TIRE_PROFILE => 'front_tire_profile',
            self::KEY_REAR_TIRE_PROFILE => 'rear_tire_profile',
            self::KEY_DAMAGE_FREE => 'damage_free',

            self::KEY_DRIVABLE,
            self::KEY_TECHNICAL,
            self::KEY_INTERIOR,
            self::KEY_PROPULSION,
            self::KEY_GENERAL,
            self::KEY_BATTERY => $key,

            default => throw new \InvalidArgumentException("Unsupported key: $key"),
        };

        return $translator->get("labels.$key");
    }
}
