<?php

declare(strict_types=1);

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

namespace App\Business\MasterData;

use App\Business\MasterData\Enums\WarehouseType;
use App\Models\DberpWarehouse;
use App\Tools\Entity\EntityReference;
use App\Tools\Entity\EntityType;
use App\Tools\Support\ToolPagedQuery;
use Illuminate\Database\Eloquent\Builder;

/**
 * 仓库档案只读检索。不暴露地址、电话、备注或地区快照。
 */
final class WarehouseSearchQuery
{
    public const SORTABLE = ['id', 'code', 'name', 'sort_order', 'warehouse_type'];

    public const DEFAULT_SORT = 'sort_order';

    /**
     * @param  array<string, mixed>  $input
     * @return array{items: list<array<string, mixed>>, page: int, per_page: int, total: int}
     */
    public function search(array $input): array
    {
        $query = DberpWarehouse::query()->with('manager');

        $keyword = trim((string) ($input['q'] ?? ''));
        if ($keyword !== '') {
            $like = '%'.$keyword.'%';
            $query->where(function (Builder $builder) use ($like): void {
                $builder
                    ->where('code', 'like', $like)
                    ->orWhere('name', 'like', $like);
            });
        }

        if (array_key_exists('is_enabled', $input) && $input['is_enabled'] !== null) {
            $query->where('is_enabled', (bool) $input['is_enabled']);
        }

        if (array_key_exists('is_default', $input) && $input['is_default'] !== null) {
            $query->where('is_default', (bool) $input['is_default']);
        }

        $type = trim((string) ($input['warehouse_type'] ?? ''));
        if ($type !== '') {
            $query->where('warehouse_type', $type);
        }

        $page = ToolPagedQuery::paginate(
            $query,
            $input,
            self::SORTABLE,
            self::DEFAULT_SORT,
            'asc',
        );

        return [
            'items' => $page['rows']
                ->map(fn (mixed $warehouse): array => $this->mapSummary($warehouse))
                ->values()
                ->all(),
            ...ToolPagedQuery::meta($page),
        ];
    }

    /**
     * @return list<string>
     */
    public static function warehouseTypeValues(): array
    {
        return array_map(
            static fn (WarehouseType $type): string => $type->value,
            WarehouseType::cases(),
        );
    }

    /**
     * @return array<string, mixed>
     */
    public function mapSummary(mixed $warehouse): array
    {
        if (! $warehouse instanceof DberpWarehouse) {
            return [];
        }

        return EntityReference::attach([
            'id' => (int) $warehouse->getKey(),
            'code' => (string) $warehouse->code,
            'name' => (string) $warehouse->name,
            'warehouse_type' => (string) $warehouse->warehouse_type,
            'is_enabled' => (bool) $warehouse->is_enabled,
            'is_default' => (bool) $warehouse->is_default,
            'manager_employee_id' => $warehouse->manager_employee_id === null ? null : (int) $warehouse->manager_employee_id,
            'manager_name' => $this->nullableString($warehouse->manager?->name),
            'sort_order' => (int) ($warehouse->sort_order ?? 0),
        ], EntityType::Warehouse, (int) $warehouse->getKey(), (string) $warehouse->code, (string) $warehouse->name);
    }

    private function nullableString(mixed $value): ?string
    {
        if ($value === null) {
            return null;
        }

        $normalized = trim((string) $value);

        return $normalized === '' ? null : $normalized;
    }
}
