package com.ruoyi.web.modules.store.support;

import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.web.modules.store.constant.ShopConstants;
import com.ruoyi.web.modules.store.domain.BizMerchantAccount;
import com.ruoyi.web.modules.store.domain.BizShop;
import com.ruoyi.web.modules.store.mapper.BizMerchantAccountMapper;
import com.ruoyi.web.modules.store.mapper.BizShopMapper;

/**
 * 商家端店铺上下文校验
 */
@Component
public class SellerShopContextSupport
{
    @Autowired
    private BizMerchantAccountMapper merchantAccountMapper;

    @Autowired
    private BizShopMapper shopMapper;

    @Autowired
    private RedisCache redisCache;

    @Value("${token.expireTime}")
    private int tokenExpireMinutes;

    public BizMerchantAccount requireSellerAccount(Long userId)
    {
        BizMerchantAccount account = merchantAccountMapper.selectByUserId(userId);
        if (account == null)
        {
            throw new ServiceException(ShopConstants.MSG_NOT_SELLER_USER);
        }
        return account;
    }

    public Long resolveDefaultShopId(BizMerchantAccount account)
    {
        if (account.getShopId() != null)
        {
            return account.getShopId();
        }
        BizShop shop = shopMapper.selectEarliestByMerchantId(account.getMerchantId());
        return shop != null ? shop.getShopId() : null;
    }

    /**
     * 解析当前店铺：优先当前登录会话上次所选，无效则回退默认店铺
     */
    public Long resolveCurrentShopId(String sessionToken, BizMerchantAccount account)
    {
        Long selected = getSelectedShopId(sessionToken);
        if (selected != null && isShopAccessible(account, selected))
        {
            refreshSelectedShopId(sessionToken, selected);
            return selected;
        }
        if (selected != null)
        {
            clearSelectedShopId(sessionToken);
        }
        return resolveDefaultShopId(account);
    }

    public void saveSelectedShopId(String sessionToken, Long shopId)
    {
        requireSessionToken(sessionToken);
        redisCache.setCacheObject(buildSelectedShopKey(sessionToken), shopId, tokenExpireMinutes, TimeUnit.MINUTES);
    }

    public Long getSelectedShopId(String sessionToken)
    {
        if (StringUtils.isEmpty(sessionToken))
        {
            return null;
        }
        return redisCache.getCacheObject(buildSelectedShopKey(sessionToken));
    }

    public void clearSelectedShopId(String sessionToken)
    {
        if (StringUtils.isEmpty(sessionToken))
        {
            return;
        }
        redisCache.deleteObject(buildSelectedShopKey(sessionToken));
    }

    public boolean isShopAccessible(BizMerchantAccount account, Long shopId)
    {
        if (shopId == null || shopId <= 0)
        {
            return false;
        }
        if (account.getShopId() != null && !shopId.equals(account.getShopId()))
        {
            return false;
        }
        return shopMapper.countByShopIdAndMerchantId(shopId, account.getMerchantId()) > 0;
    }

    public void assertShopAccessible(BizMerchantAccount account, Long shopId)
    {
        if (!isShopAccessible(account, shopId))
        {
            if (shopId == null || shopId <= 0)
            {
                throw new ServiceException(ShopConstants.MSG_SHOP_CONTEXT_REQUIRED);
            }
            throw new ServiceException(ShopConstants.MSG_SHOP_CONTEXT_INVALID);
        }
    }

    public boolean isMerchantAdmin(BizMerchantAccount account)
    {
        return account.getShopId() == null;
    }

    private void refreshSelectedShopId(String sessionToken, Long shopId)
    {
        redisCache.setCacheObject(buildSelectedShopKey(sessionToken), shopId, tokenExpireMinutes, TimeUnit.MINUTES);
    }

    private void requireSessionToken(String sessionToken)
    {
        if (StringUtils.isEmpty(sessionToken))
        {
            throw new ServiceException("登录会话无效", com.ruoyi.common.constant.HttpStatus.UNAUTHORIZED);
        }
    }

    private String buildSelectedShopKey(String sessionToken)
    {
        return ShopConstants.REDIS_SELLER_SHOP_CONTEXT_PREFIX + sessionToken;
    }
}
