<?php

declare(strict_types=1);

namespace App\Business\DataImport;

use App\Business\DataImport\Contracts\DataImportHandler;
use App\Business\DataImport\Enums\DataImportType;
use App\Business\DataImport\Handlers\CustomerCategoryImportHandler;
use App\Business\DataImport\Handlers\CustomerImportHandler;
use App\Business\DataImport\Handlers\OpeningStockImportHandler;
use App\Business\DataImport\Handlers\ProductBrandImportHandler;
use App\Business\DataImport\Handlers\ProductCategoryImportHandler;
use App\Business\DataImport\Handlers\ProductImportHandler;
use App\Business\DataImport\Handlers\SupplierCategoryImportHandler;
use App\Business\DataImport\Handlers\SupplierImportHandler;
use App\Business\DataImport\Handlers\UnitImportHandler;
use App\Business\DataImport\Handlers\WarehouseImportHandler;
use Illuminate\Contracts\Container\Container;
use InvalidArgumentException;

final class DataImportHandlerRegistry
{
    /**
     * @var array<string, class-string<DataImportHandler>>
     */
    private array $handlers;

    public function __construct(
        private readonly Container $container,
    ) {
        $this->handlers = [
            DataImportType::Unit->value => UnitImportHandler::class,
            DataImportType::ProductCategory->value => ProductCategoryImportHandler::class,
            DataImportType::ProductBrand->value => ProductBrandImportHandler::class,
            DataImportType::Product->value => ProductImportHandler::class,
            DataImportType::CustomerCategory->value => CustomerCategoryImportHandler::class,
            DataImportType::Customer->value => CustomerImportHandler::class,
            DataImportType::SupplierCategory->value => SupplierCategoryImportHandler::class,
            DataImportType::Supplier->value => SupplierImportHandler::class,
            DataImportType::Warehouse->value => WarehouseImportHandler::class,
            DataImportType::OpeningStock->value => OpeningStockImportHandler::class,
        ];
    }

    public function supports(DataImportType $importType): bool
    {
        return isset($this->handlers[$importType->value]);
    }

    public function resolve(DataImportType $importType): DataImportHandler
    {
        $handlerClass = $this->handlers[$importType->value] ?? null;

        if ($handlerClass === null) {
            throw new InvalidArgumentException((string) __('dberp.data_import.errors.unsupported_import_type'));
        }

        return $this->container->make($handlerClass);
    }

    /**
     * @return list<DataImportType>
     */
    public function supportedTypes(): array
    {
        return array_map(
            static fn (string $value): DataImportType => DataImportType::from($value),
            array_keys($this->handlers),
        );
    }
}
