<?php

declare(strict_types=1);

namespace App\Support;

use App\Models\DberpCustomer;
use App\Models\DberpCustomerPriceRule;
use App\Models\DberpDictionaryItem;
use App\Models\DberpPaymentOrder;
use App\Models\DberpReceiptOrder;
use App\Models\DberpSupplier;
use App\Models\DberpSystemProfile;
use Illuminate\Support\Facades\Schema;

final class DictionaryItemUsageChecker
{
    public function canDelete(DberpDictionaryItem $item): bool
    {
        return $this->usageReasons($item) === [];
    }

    /**
     * @return list<string>
     */
    public function usageReasons(DberpDictionaryItem $item): array
    {
        if ($item->is_system_preset || $item->is_delete_locked) {
            return [(string) __('dberp.dictionary_item_control.preset_delete_forbidden')];
        }

        $typeCode = $item->resolveTypeCode();

        if ($typeCode === null || $typeCode === '') {
            return [(string) __('dberp.dictionary_item_control.unknown_type_delete_forbidden')];
        }

        if (DberpDictionaryItemMaintenance::isSystemFixedForTypeCode($typeCode)) {
            return [(string) __('dberp.dictionary_item_control.system_fixed_delete_forbidden')];
        }

        return match ($typeCode) {
            DberpPriceLevelDictionary::TYPE_CODE => $this->priceLevelReasons((string) $item->code),
            'source_type' => $this->sourceTypeReasons($item),
            'receipt_method' => $this->receiptMethodReasons($item),
            'payment_method' => $this->paymentMethodReasons($item),
            'settlement_method' => $this->settlementMethodReasons((string) $item->code),
            default => [],
        };
    }

    /**
     * @return list<string>
     */
    private function priceLevelReasons(string $code): array
    {
        $reasons = [];

        if (DberpCustomer::query()->where('price_level_code', $code)->exists()) {
            $reasons[] = (string) __('dberp.errors.dictionary_item_used_by_customers');
        }

        if (DberpCustomerPriceRule::query()->where('price_level_code', $code)->exists()) {
            $reasons[] = (string) __('dberp.errors.dictionary_item_used_by_customer_price_rules');
        }

        return $reasons;
    }

    /**
     * @return list<string>
     */
    private function sourceTypeReasons(DberpDictionaryItem $item): array
    {
        if (DberpSystemProfile::query()->where('default_source_type_item_id', $item->getKey())->exists()) {
            return [(string) __('dberp.errors.dictionary_item_used_by_system_profile')];
        }

        return [];
    }

    /**
     * @return list<string>
     */
    private function receiptMethodReasons(DberpDictionaryItem $item): array
    {
        if (! Schema::hasTable('dberp_receipt_orders')) {
            return [];
        }

        if (DberpReceiptOrder::query()->where('payment_method_item_id', $item->getKey())->exists()) {
            return [(string) __('dberp.errors.dictionary_item_used_by_receipt_orders')];
        }

        return [];
    }

    /**
     * @return list<string>
     */
    private function paymentMethodReasons(DberpDictionaryItem $item): array
    {
        if (! Schema::hasTable('dberp_payment_orders')) {
            return [];
        }

        if (DberpPaymentOrder::query()->where('payment_method_item_id', $item->getKey())->exists()) {
            return [(string) __('dberp.errors.dictionary_item_used_by_payment_orders')];
        }

        return [];
    }

    /**
     * @return list<string>
     */
    private function settlementMethodReasons(string $code): array
    {
        $reasons = [];

        if (DberpCustomer::query()->where('settlement_method', $code)->exists()) {
            $reasons[] = (string) __('dberp.errors.dictionary_item_used_by_customers');
        }

        if (DberpSupplier::query()->where('settlement_method', $code)->exists()) {
            $reasons[] = (string) __('dberp.errors.dictionary_item_used_by_suppliers');
        }

        return $reasons;
    }
}
