import { DistLockV2Service } from '../scheduler/DistLockV2Service';
import { logger } from '../../utils/logger';

/**
 * [BIZ_INF_105] 分布式幂等锁 (DistributedLockDecorator)
 * @description 核心逻辑：提供方法级的分布式锁装饰器。
 * 针对高频交易、重复点击、资源竞争等场景实现自动互斥。
 * 支持通过函数动态生成锁 Key。
 */
export function DistributedLock(options: {
  lockKey: string | ((...args: any[]) => string);
  ttl?: number;
  errorMessage?: string;
}) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = async function (...args: any[]) {
      // 1. 动态生成最终锁 Key
      const key = typeof options.lockKey === 'function' 
        ? options.lockKey(...args) 
        : options.lockKey;

      const finalKey = `distributed_lock:${key}`;
      const ttl = options.ttl || 10000; // 默认锁 10 秒

      // 2. 尝试抢占分布式锁
      const lockId = await DistLockV2Service.lock(finalKey, ttl);

      if (!lockId) {
        logger.warn(`[DistributedLock] Operation ${propertyKey} locked for key ${finalKey}`);
        // 抢锁失败抛出业务异常，建议前端捕获并提示“请勿重复提交”
        throw new Error(options.errorMessage || `OPERATION_LOCKED:${finalKey}`);
      }

      try {
        // 3. 执行核心业务逻辑
        logger.debug(`[DistributedLock] Executing ${propertyKey} under lock ${finalKey}`);
        return await originalMethod.apply(this, args);
      } finally {
        // 4. 原子释放锁，确保不阻塞后续操作
        await DistLockV2Service.unlock(finalKey, lockId);
      }
    };

    return descriptor;
  };
}
