<?php

namespace App\Support;

use Carbon\Carbon;
use Illuminate\Validation\ValidationException;

/** 账期起止边界：开账时规范化写入，关账/聚合/流水筛选共用同一对 UTC 时刻。 */
final class AgentSettlementPeriodWindow
{
    /**
     * @return array{0: Carbon, 1: Carbon}
     */
    public static function bounds(string $periodStart, string $periodEnd): array
    {
        return [
            Carbon::parse($periodStart)->utc(),
            Carbon::parse($periodEnd)->utc(),
        ];
    }

    /**
     * @return array{0: string, 1: string}
     */
    public static function boundStrings(string $periodStart, string $periodEnd): array
    {
        [$start, $end] = self::bounds($periodStart, $periodEnd);

        return [$start->toDateTimeString(), $end->toDateTimeString()];
    }

    /**
     * 开账 API：支持 `Y-m-d` 或带时刻字符串；前者按 UTC 自然日扩界，后者按 UTC 解释。
     *
     * @return array{0: string, 1: string}
     */
    public static function normalizeInputBounds(string $periodStart, string $periodEnd): array
    {
        $startRaw = trim($periodStart);
        $endRaw = trim($periodEnd);

        if ($startRaw === '' || $endRaw === '') {
            throw ValidationException::withMessages([
                'period_start' => ['required'],
            ]);
        }

        $startAt = self::isDateOnly($startRaw)
            ? Carbon::parse($startRaw.' 00:00:00', 'UTC')
            : Carbon::parse($startRaw)->utc();

        $endAt = self::isDateOnly($endRaw)
            ? Carbon::parse($endRaw.' 23:59:59', 'UTC')
            : Carbon::parse($endRaw)->utc();

        if ($endAt->lessThan($startAt)) {
            throw ValidationException::withMessages([
                'period_end' => ['after:period_start'],
            ]);
        }

        return [$startAt->toDateTimeString(), $endAt->toDateTimeString()];
    }

    private static function isDateOnly(string $value): bool
    {
        return (bool) preg_match('/^\d{4}-\d{2}-\d{2}$/', $value);
    }
}
