<?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\SettlementAgingReadQuery;
use App\Tools\Contracts\Tool;
use App\Tools\Entity\EntityReferenceSchema;
use App\Tools\Enums\ToolRisk;
use App\Tools\Support\ToolCurrency;
use App\Tools\Support\ToolDateSchema;
use App\Tools\ToolExecutionContext;
use App\Tools\ToolMetadata;
use App\Tools\ToolPermission;

final class SettlementAgingTool implements Tool
{
    public function __construct(
        private readonly SettlementAgingReadQuery $query,
    ) {}

    public function metadata(): ToolMetadata
    {
        $bucketProperties = [
            'current_amount' => ['type' => 'string'],
            'bucket_1_30_amount' => ['type' => 'string'],
            'bucket_31_60_amount' => ['type' => 'string'],
            'bucket_61_90_amount' => ['type' => 'string'],
            'bucket_91_plus_amount' => ['type' => 'string'],
            'total_amount' => ['type' => 'string'],
        ];
        $bucketRequired = array_keys($bucketProperties);

        return new ToolMetadata(
            name: 'settlement.aging',
            version: 1,
            description: '应收/应付账龄分析（只读），分桶口径与现有账龄分析报表一致。往来明细分页，合计始终覆盖全部匹配记录。',
            permission: ToolPermission::report('settlement-aging-analysis'),
            risk: ToolRisk::ReadOnly,
            inputSchema: [
                'type' => 'object',
                'additionalProperties' => false,
                'properties' => [
                    'settlement_side' => [
                        'type' => 'string',
                        'enum' => ['receivable', 'payable'],
                    ],
                    'as_of_date' => ToolDateSchema::dateProperty('As-of calendar date Y-m-d (inclusive).'),
                    'counterparty_id' => [
                        'type' => 'integer',
                        'minimum' => 1,
                    ],
                    'page' => [
                        'type' => 'integer',
                        'minimum' => 1,
                        'maximum' => 10000,
                        'default' => 1,
                        'description' => '1-based page index for counterparties. Totals always cover every matching record.',
                    ],
                    'per_page' => [
                        'type' => 'integer',
                        'minimum' => 1,
                        'maximum' => 100,
                        'default' => 20,
                        'description' => 'Counterparty page size. Maximum 100.',
                    ],
                ],
            ],
            outputSchema: [
                'type' => 'object',
                'required' => [
                    'settlement_side',
                    'as_of_date',
                    'as_of_timezone',
                    'currency',
                    'totals',
                    'counterparties',
                    'page',
                    'per_page',
                    'total',
                    'has_more',
                ],
                'additionalProperties' => false,
                'properties' => [
                    'settlement_side' => ['type' => 'string'],
                    'as_of_date' => ['type' => 'string'],
                    'as_of_timezone' => ['type' => 'string'],
                    'currency' => ToolCurrency::outputSchema(),
                    'totals' => [
                        'type' => 'object',
                        'required' => $bucketRequired,
                        'additionalProperties' => false,
                        'properties' => $bucketProperties,
                    ],
                    'counterparties' => [
                        'type' => 'array',
                        'items' => EntityReferenceSchema::withRef([
                            'type' => 'object',
                            'required' => [
                                'counterparty_id',
                                'counterparty_name',
                                'record_count',
                                ...$bucketRequired,
                            ],
                            'additionalProperties' => false,
                            'properties' => [
                                'counterparty_id' => ['type' => 'integer'],
                                'counterparty_name' => ['type' => 'string'],
                                'record_count' => ['type' => 'integer'],
                                ...$bucketProperties,
                            ],
                        ]),
                    ],
                    'page' => ['type' => 'integer'],
                    'per_page' => ['type' => 'integer'],
                    'total' => ['type' => 'integer'],
                    'has_more' => ['type' => 'boolean'],
                ],
            ],
            owner: 'core',
        );
    }

    /**
     * @param  array<string, mixed>  $input
     * @return array<string, mixed>
     */
    public function execute(ToolExecutionContext $context, array $input): array
    {
        return $this->query->analyze($context, $input);
    }
}
