<?php

declare(strict_types=1);

namespace App\Business\Settlement;

use App\Models\DberpPayableRecord;
use App\Models\DberpPaymentOrder;
use App\Models\DberpPurchaseOrder;
use App\Models\DberpReceiptOrder;
use App\Models\DberpReceivableRecord;
use App\Models\DberpSalesOrder;
use App\Models\DberpSettlementAdjustment;
use App\Models\DberpSettlementWriteOff;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

final class SettlementSourceTypeResolver
{
    /**
     * @var array<class-string<Model>, string>
     */
    private const MODEL_TO_KEY = [
        DberpSalesOrder::class => 'sales_order',
        DberpPurchaseOrder::class => 'purchase_order',
        DberpReceiptOrder::class => 'receipt_order',
        DberpPaymentOrder::class => 'payment_order',
        DberpReceivableRecord::class => 'receivable_record',
        DberpPayableRecord::class => 'payable_record',
        DberpSettlementWriteOff::class => 'settlement_write_off',
        DberpSettlementAdjustment::class => 'settlement_adjustment',
    ];

    public function fromModel(?Model $source): ?string
    {
        if ($source === null) {
            return null;
        }

        return self::MODEL_TO_KEY[$source::class] ?? Str::snake(class_basename($source));
    }

    public function normalize(?string $sourceType): ?string
    {
        if ($sourceType === null || $sourceType === '') {
            return null;
        }

        if (array_key_exists($sourceType, __('dberp.options.settlement_source_type'))) {
            return $sourceType;
        }

        if (is_subclass_of($sourceType, Model::class)) {
            return $this->fromModel(app($sourceType));
        }

        foreach (self::MODEL_TO_KEY as $class => $key) {
            if ($sourceType === $class) {
                return $key;
            }
        }

        return Str::snake(class_basename(str_replace('\\', '/', $sourceType)));
    }
}
