package shop.alien.dining.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import shop.alien.dining.config.BaseRedisService;
import shop.alien.dining.service.OrderLockService;

/**
 * 订单锁定服务实现类
 *
 * @author system
 * @since 2025-01-XX
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OrderLockServiceImpl implements OrderLockService {

    private static final String ORDER_LOCK_KEY_PREFIX = "order:lock:table:";
    private static final String SETTLEMENT_LOCK_KEY_PREFIX = "settlement:lock:order:";
    private static final int ORDER_LOCK_EXPIRE_SECONDS = 300; // 5分钟过期

    private final BaseRedisService baseRedisService;

    @Override
    public boolean lockOrder(Integer tableId, Integer userId) {
        log.info("锁定订单, tableId={}, userId={}", tableId, userId);

        String lockKey = ORDER_LOCK_KEY_PREFIX + tableId;
        String existingLock = baseRedisService.getString(lockKey);
        if (StringUtils.hasText(existingLock)) {
            // 已锁定，检查是否是当前用户
            if (existingLock.equals(String.valueOf(userId))) {
                // 刷新过期时间
                baseRedisService.setString(lockKey, existingLock, (long) ORDER_LOCK_EXPIRE_SECONDS);
                return true;
            } else {
                // 被其他用户锁定
                return false;
            }
        }

        // 设置锁定
        baseRedisService.setString(lockKey, String.valueOf(userId), (long) ORDER_LOCK_EXPIRE_SECONDS);
        return true;
    }

    @Override
    public void unlockOrder(Integer tableId, Integer userId) {
        log.info("解锁订单, tableId={}, userId={}", tableId, userId);

        String lockKey = ORDER_LOCK_KEY_PREFIX + tableId;
        String existingLock = baseRedisService.getString(lockKey);
        if (StringUtils.hasText(existingLock) && existingLock.equals(String.valueOf(userId))) {
            baseRedisService.delete(lockKey);
        }
    }

    @Override
    public Integer checkOrderLock(Integer tableId) {
        String lockKey = ORDER_LOCK_KEY_PREFIX + tableId;
        String lockUserId = baseRedisService.getString(lockKey);
        if (StringUtils.hasText(lockUserId)) {
            try {
                return Integer.parseInt(lockUserId);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    @Override
    public boolean lockSettlement(Integer orderId, Integer userId) {
        log.info("锁定订单结算, orderId={}, userId={}", orderId, userId);

        String lockKey = SETTLEMENT_LOCK_KEY_PREFIX + orderId;
        String existingLock = baseRedisService.getString(lockKey);
        if (StringUtils.hasText(existingLock)) {
            if (existingLock.equals(String.valueOf(userId))) {
                baseRedisService.setString(lockKey, existingLock, (long) ORDER_LOCK_EXPIRE_SECONDS);
                return true;
            } else {
                return false;
            }
        }

        baseRedisService.setString(lockKey, String.valueOf(userId), (long) ORDER_LOCK_EXPIRE_SECONDS);
        return true;
    }

    @Override
    public void unlockSettlement(Integer orderId, Integer userId) {
        log.info("解锁订单结算, orderId={}, userId={}", orderId, userId);

        String lockKey = SETTLEMENT_LOCK_KEY_PREFIX + orderId;
        String existingLock = baseRedisService.getString(lockKey);
        if (StringUtils.hasText(existingLock) && existingLock.equals(String.valueOf(userId))) {
            baseRedisService.delete(lockKey);
        }
    }

    @Override
    public Integer checkSettlementLock(Integer orderId) {
        String lockKey = SETTLEMENT_LOCK_KEY_PREFIX + orderId;
        String lockUserId = baseRedisService.getString(lockKey);
        if (StringUtils.hasText(lockUserId)) {
            try {
                return Integer.parseInt(lockUserId);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }
}
