<?php

declare(strict_types=1);

namespace App\Business\Purchase;

use App\Business\Inventory\Enums\InventoryDocumentStatus;
use App\Models\DberpPurchaseOrder;
use App\Models\DberpPurchaseReceiptOrder;
use App\Support\DberpDocumentRemarkPropagation;

final class PurchaseReturnReferenceDefaultsResolver
{
    public function __construct(
        private readonly PurchaseOrderRequestedWarehouseResolver $requestedWarehouseResolver,
    ) {}

    /**
     * @return array<string, int|null>
     */
    public function resolveFromPurchaseOrder(DberpPurchaseOrder $order): array
    {
        $order->loadMissing('items');

        $defaults = [
            'supplier_id' => (int) $order->supplier_id,
            'handler_employee_id' => $order->handler_employee_id !== null ? (int) $order->handler_employee_id : null,
        ];

        $warehouseId = $this->resolveWarehouseIdForPurchaseOrder($order);

        if ($warehouseId !== null) {
            $defaults['warehouse_id'] = $warehouseId;
        }

        $defaults['remark'] = DberpDocumentRemarkPropagation::trimmedOrNull($order->remark);

        return $defaults;
    }

    /**
     * @return array<string, int|null>
     */
    public function resolveFromPurchaseReceipt(DberpPurchaseReceiptOrder $receipt): array
    {
        return [
            'purchase_order_id' => $receipt->purchase_order_id !== null ? (int) $receipt->purchase_order_id : null,
            'purchase_receipt_order_id' => (int) $receipt->getKey(),
            'supplier_id' => (int) $receipt->supplier_id,
            'warehouse_id' => (int) $receipt->warehouse_id,
            'handler_employee_id' => $receipt->handler_employee_id !== null ? (int) $receipt->handler_employee_id : null,
            'remark' => DberpDocumentRemarkPropagation::trimmedOrNull($receipt->remark),
        ];
    }

    public function hasAmbiguousWarehouseForPurchaseOrder(DberpPurchaseOrder $order): bool
    {
        $order->loadMissing('items');

        return count($this->distinctEffectiveReceiptWarehouseIds($order)) > 1
            || $this->requestedWarehouseResolver->hasMixedRequestedWarehouses($order);
    }

    public function resolveWarehouseIdForPurchaseOrder(DberpPurchaseOrder $order): ?int
    {
        $order->loadMissing('items');

        $receiptWarehouseIds = $this->distinctEffectiveReceiptWarehouseIds($order);

        if (count($receiptWarehouseIds) === 1) {
            return $receiptWarehouseIds[0];
        }

        return $this->requestedWarehouseResolver->resolveDefaultReceiptWarehouseId($order);
    }

    /**
     * @return list<int>
     */
    private function distinctEffectiveReceiptWarehouseIds(DberpPurchaseOrder $order): array
    {
        return DberpPurchaseReceiptOrder::query()
            ->where('purchase_order_id', $order->getKey())
            ->where('status', InventoryDocumentStatus::Effective->value)
            ->whereNotNull('warehouse_id')
            ->distinct()
            ->orderBy('warehouse_id')
            ->pluck('warehouse_id')
            ->map(fn (mixed $id): int => (int) $id)
            ->values()
            ->all();
    }
}
