<?php

namespace App\Support;

use App\Models\PlatformOrder;
use App\Models\SiteSubscription;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Str;

/**
 * 订阅激活服务（最小闭环）
 *
 * 目标：当平台订单满足“已支付 + 已生效”时，让站点订阅真正生效或续期。
 *
 * 约束：
 * - 只负责业务层状态/时间的联动，不负责支付回执、异步通知等入口。
 * - 支持两种情况：
 *   1) 订单已绑定 site_subscription_id => 续期/延长该订阅
 *   2) 未绑定 => 创建新订阅并回写订单 site_subscription_id
 */
class SubscriptionActivationService
{
    /**
     * @throws ModelNotFoundException
     */
    public function activateOrder(int $orderId, ?int $adminId = null): SiteSubscription
    {
        /** @var PlatformOrder $order */
        $order = PlatformOrder::query()->findOrFail($orderId);

        // 最小校验：必须已支付 + 已生效
        if ($order->payment_status !== 'paid' || $order->status !== 'activated') {
            throw new \InvalidArgumentException('订单未满足生效条件：需 payment_status=paid 且 status=activated');
        }

        $now = now();
        $months = max(1, (int) $order->period_months) * max(1, (int) ($order->quantity ?? 1));

        // 幂等保护：若该订单已同步过订阅，则直接返回对应订阅（避免重复点击导致无限续期）
        $activationMeta = (array) data_get($order->meta ?? [], 'subscription_activation', []);
        $activatedSubscriptionId = (int) ($activationMeta['subscription_id'] ?? 0);
        if ($activatedSubscriptionId > 0) {
            $subscription = SiteSubscription::query()->find($activatedSubscriptionId);
            if ($subscription) {
                return $subscription;
            }
        }

        // 订阅快照：优先使用订单上记录的 plan_name / billing_cycle / plan_snapshot
        $snapshot = [
            'from_order_id' => $order->id,
            'order_no' => $order->order_no,
            'order_type' => $order->order_type,
            'plan_snapshot' => $order->plan_snapshot,
        ];

        if ($order->site_subscription_id) {
            /** @var SiteSubscription $subscription */
            $subscription = SiteSubscription::query()->findOrFail($order->site_subscription_id);

            // 治理安全阀：订单绑定的订阅必须属于同一站点（merchant），否则拒绝同步，避免误续费/串单。
            if ((int) $subscription->merchant_id !== (int) $order->merchant_id) {
                throw new \InvalidArgumentException('订阅与订单站点不一致：请核对订阅ID与订单站点后再同步');
            }

            // 以 ends_at 为基准续期：
            // - 若 ends_at 为空或已过期 => 从 now 起算
            // - 若仍有效 => 从 ends_at 起算
            $base = $subscription->ends_at && $subscription->ends_at->greaterThan($now)
                ? $subscription->ends_at->copy()
                : $now->copy();

            $newEndsAt = $base->copy()->addMonthsNoOverflow($months);

            // starts_at：若为空则补齐
            $startsAt = $subscription->starts_at ?: $now->copy();

            $subscription->fill([
                'status' => 'activated',
                'plan_id' => $order->plan_id,
                'plan_name' => $order->plan_name,
                'billing_cycle' => $order->billing_cycle,
                'period_months' => (int) $order->period_months,
                'amount' => $order->paid_amount > 0 ? $order->paid_amount : $order->payable_amount,
                'starts_at' => $startsAt,
                'ends_at' => $newEndsAt,
                'activated_at' => $subscription->activated_at ?: $now,
                'snapshot' => array_merge((array) ($subscription->snapshot ?? []), $snapshot),
            ]);
            $subscription->save();

            // 写入订单 meta，标记该订单已完成订阅同步（幂等）
            $meta = (array) ($order->meta ?? []);
            data_set($meta, 'subscription_activation', [
                'subscription_id' => $subscription->id,
                'synced_at' => $now->toDateTimeString(),
                'admin_id' => $adminId,
            ]);
            $order->meta = $meta;
            $order->save();

            return $subscription;
        }

        // 创建新订阅
        $subscriptionNo = 'SUB' . $now->format('YmdHis') . Str::padLeft((string) random_int(1, 9999), 4, '0');

        $subscription = SiteSubscription::query()->create([
            'merchant_id' => $order->merchant_id,
            'plan_id' => $order->plan_id,
            'status' => 'activated',
            'source' => 'platform_order',
            'subscription_no' => $subscriptionNo,
            'plan_name' => $order->plan_name,
            'billing_cycle' => $order->billing_cycle,
            'period_months' => (int) $order->period_months,
            'amount' => $order->paid_amount > 0 ? $order->paid_amount : $order->payable_amount,
            'starts_at' => $now,
            'ends_at' => $now->copy()->addMonthsNoOverflow($months),
            'activated_at' => $now,
            'snapshot' => $snapshot,
            'meta' => [
                'activated_by_admin_id' => $adminId,
            ],
        ]);

        // 回写订单 + 写入 meta 标记同步完成（幂等）
        $order->site_subscription_id = $subscription->id;
        $order->activated_at = $order->activated_at ?: $now;

        $meta = (array) ($order->meta ?? []);
        data_set($meta, 'subscription_activation', [
            'subscription_id' => $subscription->id,
            'synced_at' => $now->toDateTimeString(),
            'admin_id' => $adminId,
        ]);
        $order->meta = $meta;

        $order->save();

        return $subscription;
    }
}
