<?php

declare(strict_types=1);

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

namespace App\Tools\Settlement;

use App\Business\Settlement\Enums\SettlementOverdueStatus;
use App\Business\Settlement\SettlementRecordSearchSupport;
use App\Tools\Entity\EntityReferenceSchema;
use App\Tools\Support\ToolCurrency;
use App\Tools\Support\ToolDateSchema;
use App\Tools\Support\ToolListSchema;

/**
 * 应收/应付 Tool 共用 JSON Schema。仅描述已批准字段。
 */
final class SettlementToolSchema
{
    /**
     * @param  list<string>  $sortFields
     * @return array<string, mixed>
     */
    public static function searchInput(string $counterpartyIdField, array $sortFields, string $defaultSort): array
    {
        return [
            'type' => 'object',
            'additionalProperties' => false,
            'properties' => [
                'q' => [
                    'type' => 'string',
                    'minLength' => 1,
                    'maxLength' => 100,
                ],
                $counterpartyIdField => [
                    'type' => 'integer',
                    'minimum' => 1,
                ],
                'status' => [
                    'type' => 'string',
                    'enum' => SettlementRecordSearchSupport::statusValues(),
                ],
                'overdue_status' => [
                    'type' => 'string',
                    'enum' => SettlementOverdueStatus::values(),
                ],
                'date_from' => ToolDateSchema::dateProperty('Inclusive business calendar date Y-m-d.'),
                'date_until' => ToolDateSchema::dateProperty('Inclusive business calendar date Y-m-d.'),
                'period_preset' => ToolDateSchema::periodPresetProperty(),
                'due_date_from' => ToolDateSchema::dateProperty('Inclusive due calendar date Y-m-d.'),
                'due_date_until' => ToolDateSchema::dateProperty('Inclusive due calendar date Y-m-d.'),
                'amount_min' => [
                    'type' => 'number',
                    'minimum' => 0,
                ],
                'amount_max' => [
                    'type' => 'number',
                    'minimum' => 0,
                ],
                ...ToolListSchema::paginationInputProperties($sortFields, $defaultSort),
            ],
        ];
    }

    /**
     * @return array<string, mixed>
     */
    public static function lookupInput(): array
    {
        return [
            'type' => 'object',
            'additionalProperties' => false,
            'properties' => [
                'id' => ['type' => 'integer', 'minimum' => 1],
                'code' => [
                    'type' => 'string',
                    'minLength' => 1,
                    'maxLength' => 64,
                ],
            ],
        ];
    }

    /**
     * @return array<string, mixed>
     */
    public static function listItem(string $counterpartyKey): array
    {
        return EntityReferenceSchema::withRef([
            'type' => 'object',
            'required' => [
                'id',
                'code',
                'status',
                $counterpartyKey,
                'amounts',
            ],
            'additionalProperties' => false,
            'properties' => [
                'id' => ['type' => 'integer'],
                'code' => ['type' => 'string'],
                'status' => ['type' => 'string'],
                'overdue_status' => ['type' => 'string'],
                'is_overdue' => ['type' => 'boolean'],
                'business_date' => ['type' => 'string'],
                'due_date' => ['type' => 'string'],
                $counterpartyKey => EntityReferenceSchema::nestedCounterparty(),
                'source_document_no' => ['type' => 'string'],
                'amounts' => [
                    'type' => 'object',
                    'required' => [
                        'original_amount',
                        'adjusted_amount',
                        'written_off_amount',
                        'remaining_amount',
                    ],
                    'additionalProperties' => false,
                    'properties' => [
                        'original_amount' => ['type' => 'string'],
                        'adjusted_amount' => ['type' => 'string'],
                        'written_off_amount' => ['type' => 'string'],
                        'remaining_amount' => ['type' => 'string'],
                    ],
                ],
            ],
        ]);
    }

    /**
     * @return array<string, mixed>
     */
    public static function detail(string $counterpartyKey): array
    {
        $schema = self::listItem($counterpartyKey);
        $schema['properties']['source_type'] = ['type' => 'string'];
        $schema['properties']['source_document_status'] = ['type' => 'string'];
        $schema['properties']['formed_at'] = ['type' => 'string'];
        $schema['properties']['last_write_off_at'] = ['type' => 'string'];
        $schema['properties']['closed_at'] = ['type' => 'string'];
        $schema['properties']['currency'] = ToolCurrency::outputSchema();
        $schema['required'][] = 'currency';

        return $schema;
    }
}
