<?php

declare(strict_types=1);

/**
 * 本文件属于 DBErp 进销存系统。
 *
 * 版权所有 © 2026 北京珑大钜商科技有限公司。保留所有权利。
 *
 * 未经官方授权，不得删除、篡改或隐藏本文件中的版权声明、产品标识与来源信息。
 * 商业授权、官方更新与技术支持服务，请以珑大官方支持中心记录为准。
 *
 * @link https://support.loongdom.cn
 * @see  https://www.dberp.com.cn
 */

namespace App\Business\Product;

use App\Models\DberpProduct;
use App\Models\DberpProductSku;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

/**
 * 多规格矩阵重建：在零业务引用前提下清空规格维度与组合，回到单规格后再由用户重新启用多规格。
 */
final class ProductSpecMatrixRebuildService
{
    public function shouldOfferRebuild(DberpProduct $product): bool
    {
        if (! $product->spec_enabled) {
            return false;
        }

        return $this->hasSpecMatrixContent($product);
    }

    /**
     * @throws ValidationException
     */
    public function assertCanRebuild(DberpProduct $product): void
    {
        if (! $product->spec_enabled) {
            throw ValidationException::withMessages([
                'spec_enabled' => (string) __('dberp.validation.product_spec_rebuild_requires_multi_spec'),
            ]);
        }

        if (! $this->hasSpecMatrixContent($product)) {
            throw ValidationException::withMessages([
                'spec_enabled' => (string) __('dberp.validation.product_spec_rebuild_nothing_to_clear'),
            ]);
        }

        $skus = DberpProductSku::query()
            ->where('product_id', $product->getKey())
            ->orderBy('sort_order')
            ->orderBy('id')
            ->get();

        foreach ($skus as $sku) {
            if (ProductSkuReferenceGuard::hasPositiveRealtimeStock((int) $sku->getKey())) {
                throw ValidationException::withMessages([
                    'spec_enabled' => (string) __('dberp.validation.product_spec_rebuild_blocked_has_stock', [
                        'label' => $this->formatSkuLabel($sku),
                    ]),
                ]);
            }

            if (ProductSkuReferenceGuard::isReferencedByOperationalDocuments((int) $sku->getKey())) {
                throw ValidationException::withMessages([
                    'spec_enabled' => (string) __('dberp.validation.product_spec_rebuild_blocked_referenced', [
                        'label' => $this->formatSkuLabel($sku),
                    ]),
                ]);
            }
        }
    }

    /**
     * @throws ValidationException
     */
    public function rebuild(DberpProduct $product): void
    {
        $this->assertCanRebuild($product);

        DB::transaction(function () use ($product): void {
            $productId = (int) $product->getKey();

            DberpProductSku::query()
                ->where('product_id', $productId)
                ->orderBy('id')
                ->each(fn (DberpProductSku $sku): bool => (bool) $sku->delete());

            $product->specGroups()->orderBy('id')->each(
                fn ($group): bool => (bool) $group->delete(),
            );

            $product->forceFill(['spec_enabled' => false])->save();
        });

        app(ProductSkuLifecycleService::class)->enforceSingleSpecMode($product->fresh());
    }

    private function hasSpecMatrixContent(DberpProduct $product): bool
    {
        if ($product->specGroups()->exists()) {
            return true;
        }

        if ($product->skus()->whereHas('skuSpecAssignments')->exists()) {
            return true;
        }

        return $product->skus()->count() > 1;
    }

    private function formatSkuLabel(DberpProductSku $sku): string
    {
        $code = trim((string) ($sku->sku_code ?? ''));
        $spec = trim((string) ($sku->spec_text ?? ''));

        if ($code !== '' && $spec !== '') {
            return $code.' / '.$spec;
        }

        if ($code !== '') {
            return $code;
        }

        if ($spec !== '') {
            return $spec;
        }

        return '#'.$sku->getKey();
    }
}
