<?php

declare(strict_types=1);

namespace App\Business\Product;

use App\Models\DberpProduct;
use Illuminate\Support\Facades\Schema;

/**
 * 第 5 步：规格组合数据兼容（默认组合、空关联回填、风险登记）。
 */
final class ProductSkuCompatibilityService
{
    public function __construct(
        private readonly ProductSkuLifecycleService $lifecycleService,
    ) {}

    /**
     * 为「未启用规格矩阵」的物料确保至少一条可用的默认规格组合，并收敛单规格形态。
     *
     * @return array{processed_products: int, risks: list<array{product_id: int, reason: string}>}
     */
    public function ensureDefaultSkusForNonSpecMatrixProducts(bool $dryRun = false): array
    {
        if (! Schema::hasTable('dberp_product_skus')) {
            return ['processed_products' => 0, 'risks' => []];
        }

        $risks = [];
        foreach (DberpProduct::query()->where('spec_enabled', true)->whereDoesntHave('skus')->cursor() as $product) {
            if (! $product instanceof DberpProduct) {
                continue;
            }

            $risks[] = [
                'product_id' => (int) $product->getKey(),
                'reason' => (string) __('dberp.messages.product_sku_compat_spec_matrix_without_combos'),
            ];
        }

        if ($dryRun) {
            return [
                'processed_products' => (int) DberpProduct::query()->where('spec_enabled', false)->whereDoesntHave('skus')->count(),
                'risks' => $risks,
            ];
        }

        $processed = 0;
        foreach (DberpProduct::query()->where('spec_enabled', false)->cursor() as $product) {
            if (! $product instanceof DberpProduct) {
                continue;
            }

            $this->lifecycleService->enforceSingleSpecMode($product->fresh());
            $processed++;
        }

        return ['processed_products' => $processed, 'risks' => $risks];
    }

    /**
     * 将仍为空的 `product_sku_id` 映射到物料下**唯一一条启用的**规格组合（与第 6 步 `ProductSkuLineBackfillService` 规则一致）；无法唯一确定时记入 risks，不写库。
     *
     * @return array{updated_rows: int, risks: list<array<string, mixed>>}
     */
    public function mapLegacyNullProductSkuIds(bool $dryRun = false): array
    {
        if (! Schema::hasTable('dberp_product_skus')) {
            return ['updated_rows' => 0, 'risks' => []];
        }

        $tables = [
            'dberp_inventory_balances' => 'product_sku_id',
            'dberp_inventory_transactions' => 'product_sku_id',
            'dberp_purchase_order_items' => 'product_sku_id',
            'dberp_purchase_receipt_order_items' => 'product_sku_id',
            'dberp_sales_order_items' => 'product_sku_id',
            'dberp_sales_outbound_order_items' => 'product_sku_id',
        ];

        return ProductSkuReferenceGuard::mapNullProductSkuIds($tables, $dryRun);
    }

    /**
     * 迁移/运维入口：顺序执行默认组合与空关联回填。
     *
     * @return array<string, mixed>
     */
    public function runCompatibilityPass(bool $dryRun = false): array
    {
        $defaults = $this->ensureDefaultSkusForNonSpecMatrixProducts($dryRun);
        $mapped = $this->mapLegacyNullProductSkuIds($dryRun);

        return [
            'dry_run' => $dryRun,
            'default_sku_pass' => $defaults,
            'null_sku_mapping' => $mapped,
        ];
    }
}
