<?php

declare(strict_types=1);

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

namespace App\Tools\Support;

use App\Tools\Exceptions\ToolInvalidInputException;
use DateTimeImmutable;
use DateTimeZone;

/**
 * 等长前置对比窗口。当前区间两端闭区间，上一窗为紧邻其前、日历跨度相同的闭区间。
 */
final class ToolPeriodComparison
{
    /**
     * @return array{from: string, until: string, previous_from: string, previous_until: string, span_days: int}
     */
    public static function equalPrecedingWindow(
        mixed $from,
        mixed $until,
        string $fromField = 'date_from',
        string $untilField = 'date_until',
    ): array {
        $range = ToolDateRange::parseOptional($from, $until, $fromField, $untilField);

        if ($range['from'] === null || $range['until'] === null) {
            throw ToolInvalidInputException::forField($fromField, 'Comparison requires both dates.');
        }

        $start = DateTimeImmutable::createFromFormat('!'.ToolBusinessDate::FORMAT, $range['from'], new DateTimeZone('UTC'));
        $end = DateTimeImmutable::createFromFormat('!'.ToolBusinessDate::FORMAT, $range['until'], new DateTimeZone('UTC'));

        if (! $start instanceof DateTimeImmutable || ! $end instanceof DateTimeImmutable) {
            throw ToolInvalidInputException::forField($fromField, 'Date must use Y-m-d.');
        }

        $spanDays = (int) $start->diff($end)->format('%a');
        $previousUntil = $start->modify('-1 day');
        $previousFrom = $previousUntil->modify('-'.$spanDays.' days');

        return [
            'from' => $range['from'],
            'until' => $range['until'],
            'previous_from' => $previousFrom->format(ToolBusinessDate::FORMAT),
            'previous_until' => $previousUntil->format(ToolBusinessDate::FORMAT),
            'span_days' => $spanDays,
        ];
    }
}
