<?php

declare(strict_types=1);

namespace App\Support;

use App\Models\DberpDictionaryItem;
use Illuminate\Validation\ValidationException;

final class DberpPriceLevelDictionary
{
    public const TYPE_CODE = 'price_level';

    /**
     * @return array<string, string>
     */
    public static function optionsForSelect(?string $preserveCode = null): array
    {
        return DberpDictionaryItem::query()
            ->whereHas('type', fn ($query) => $query->where('code', self::TYPE_CODE))
            ->where(function ($query) use ($preserveCode): void {
                $query->where('is_enabled', true);

                if ($preserveCode !== null && $preserveCode !== '') {
                    $query->orWhere('code', $preserveCode);
                }
            })
            ->orderBy('sort_order')
            ->orderBy('id')
            ->pluck('label', 'code')
            ->all();
    }

    public static function labelForCode(?string $code): ?string
    {
        if ($code === null || $code === '') {
            return null;
        }

        $label = self::codeLabelMap()[$code] ?? null;

        return $label !== null && $label !== '' ? $label : null;
    }

    public static function displayLabel(?string $code): string
    {
        if ($code === null || $code === '') {
            return '';
        }

        $label = self::labelForCode($code);

        if ($label !== null) {
            return $label;
        }

        return $code.' ('.(string) __('dberp.hints.price_level_unknown').')';
    }

    public static function isEnabledCode(?string $code): bool
    {
        if ($code === null || $code === '') {
            return false;
        }

        return DberpDictionaryItem::query()
            ->whereHas('type', fn ($query) => $query->where('code', self::TYPE_CODE))
            ->where('code', $code)
            ->where('is_enabled', true)
            ->exists();
    }

    public static function assertEnabledCode(?string $code, string $attribute = 'price_level_code'): void
    {
        if ($code === null || $code === '') {
            return;
        }

        if (! self::isEnabledCode($code)) {
            throw ValidationException::withMessages([
                $attribute => (string) __('dberp.errors.price_level_code_invalid'),
            ]);
        }
    }

    /**
     * @return array<string, string>
     */
    private static function codeLabelMap(): array
    {
        return once(function (): array {
            return DberpDictionaryItem::query()
                ->whereHas('type', fn ($query) => $query->where('code', self::TYPE_CODE))
                ->orderBy('sort_order')
                ->orderBy('id')
                ->pluck('label', 'code')
                ->all();
        });
    }
}
