package com.hfkj.service.merchant.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.MD5Util;
import com.hfkj.common.utils.RedisUtil;
import com.hfkj.dao.BsMerchantMapper;
import com.hfkj.entity.BsMerchant;
import com.hfkj.entity.BsMerchantAccount;
import com.hfkj.entity.BsMerchantExample;
import com.hfkj.entity.SecUser;
import com.hfkj.service.agent.BsAgentMerService;
import com.hfkj.service.merchant.BsMerchantAccountService;
import com.hfkj.service.merchant.BsMerchantQrCodeService;
import com.hfkj.service.merchant.BsMerchantService;
import com.hfkj.service.gas.BsGasService;
import com.hfkj.service.sec.SecUserService;
import com.hfkj.sysenum.merchant.MerchantSourceTypeEnum;
import com.hfkj.sysenum.merchant.MerchantStatusEnum;
import com.hfkj.sysenum.SecUserObjectTypeEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @className: BsMerchantServiceImpl
 * @author: HuRui
 * @date: 2024/3/4
 **/
@Service("merchantService")
public class BsMerchantServiceImpl implements BsMerchantService {

    @Resource
    private BsMerchantMapper merchantMapper;
    @Resource
    private SecUserService  secUserService;
    @Resource
    private BsMerchantQrCodeService merchantQrCodeService;
    @Resource
    private BsMerchantAccountService merchantAccountService;
    @Resource
    private BsAgentMerService agentMerService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private BsGasService gasService;
    private final static String CACHE_MER_KEY = "MERCHANT:";

    @Override
    public void editData(BsMerchant merchant) {
        if (merchant.getId() == null) {
            merchant.setCreateTime(new Date());
            merchant.setUpdateTime(new Date());
            merchantMapper.insert(merchant);
        } else {
            merchant.setUpdateTime(new Date());
            merchantMapper.updateByPrimaryKey(merchant);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void createMerchant(BsMerchant merchant) throws Exception {
        merchant.setListShow(true);
        editData(merchant);

        if (secUserService.getDetailByLoginName(merchant.getContactsTel()) != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "手机号已存在，请更换");
        }

        // 自建站
        if (merchant.getSourceType().equals(MerchantSourceTypeEnum.type1.getNumber())) {
            merchant.setMerNo(""+(10000 + merchant.getId()));
            editData(merchant);

            BsMerchantAccount account = new BsMerchantAccount();
            account.setMerId(merchant.getId());
            account.setMerNo(merchant.getMerNo());
            account.setAmount(new BigDecimal("0"));
            account.setAmountConsume(new BigDecimal("0"));
            merchantAccountService.editData(account);
        }

        SecUser secUser = new SecUser();
        secUser.setUserName(merchant.getMerName());
        secUser.setLoginName(merchant.getContactsTel());
        secUser.setPassword(MD5Util.encode("123654".getBytes()));
        secUser.setObjectType(SecUserObjectTypeEnum.type2.getCode());
        secUser.setObjectId(merchant.getId());
        secUser.setRoleId(3L);
        secUser.setStatus(1);
        secUser.setCreateTime(new Date());
        secUser.setUpdateTime(new Date());
        secUserService.editUser(secUser);

        // 生成加油站码库
        merchantQrCodeService.generateMerQrCode(merchant);

        // 加入缓存
        redisUtil.set(CACHE_MER_KEY + merchant.getMerNo(), merchant);
    }

    @Override
    public void updateMerchant(BsMerchant merchant) {
        editData(merchant);
        // 清除商户信息缓存
        redisUtil.set(CACHE_MER_KEY + merchant.getMerNo(), merchant);
        // 清除油站缓存
        gasService.clean(merchant.getMerNo());
    }

    @Override
    public void resetMerPwd(String merNo) throws Exception {
        // 查询商户
        BsMerchant merchant = getMerchant(merNo);
        if (merchant == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知商户");
        }
        // 查询商户登录账户
        SecUser secUser = secUserService.getDetail(SecUserObjectTypeEnum.type2, merchant.getId());
        if (secUser == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知商户登录账户");
        }
        secUser.setPassword(MD5Util.encode("123654".getBytes()));
        secUserService.editUser(secUser);
    }

    @Override
    public void updateMerStatus(String merNo, MerchantStatusEnum merchantStatus) {
        // 查询商户
        BsMerchant merchant = getMerchant(merNo);
        if (merchant == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知商户");
        }
        merchant.setStatus(merchantStatus.getNumber());
        editData(merchant);

        redisUtil.set(CACHE_MER_KEY + merNo, merchant);
    }

    @Override
    public BsMerchant getMerchant(String merNo) {
        Object obj = redisUtil.get(CACHE_MER_KEY + merNo);
        if (obj != null) {
            return (BsMerchant) obj;
        }
        BsMerchantExample example = new BsMerchantExample();
        example.createCriteria().andMerNoEqualTo(merNo).andStatusNotEqualTo(MerchantStatusEnum.status0.getNumber());
        List<BsMerchant> list = merchantMapper.selectByExample(example);
        if (!list.isEmpty()) {
            BsMerchant merchant = list.get(0);
            redisUtil.set(CACHE_MER_KEY + merNo, merchant);
            return merchant;
        }
        return null;
    }

    @Override
    public BsMerchant getMerchant(Long merId) {
        return merchantMapper.selectByPrimaryKey(merId);
    }

    @Override
    public List<BsMerchant> getMerchantList(Map<String, Object> param) {
        BsMerchantExample example = new BsMerchantExample();
        BsMerchantExample.Criteria criteria = example.createCriteria().andStatusNotEqualTo(MerchantStatusEnum.status0.getNumber());

        if (MapUtils.getInteger(param, "sourceType") != null) {
            criteria.andSourceTypeEqualTo(MapUtils.getInteger(param, "sourceType"));
        }
        if (MapUtils.getLong(param, "provinceCode") != null) {
            criteria.andProvinceCodeEqualTo(MapUtils.getLong(param, "provinceCode"));
        }

        if (MapUtils.getLong(param, "cityCode") != null) {
            criteria.andCityCodeEqualTo(MapUtils.getLong(param, "cityCode"));
        }

        if (MapUtils.getLong(param, "chainBrandId") != null) {
            criteria.andChainBrandIdEqualTo(MapUtils.getLong(param, "chainBrandId"));
        }

        if (MapUtils.getLong(param, "areaCode") != null) {
            criteria.andAreaCodeEqualTo(MapUtils.getLong(param, "areaCode"));
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merNo"))) {
            criteria.andMerNoLike("%"+MapUtils.getString(param, "merNo")+"%");
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merName"))) {
            criteria.andMerNameLike("%"+MapUtils.getString(param, "merName")+"%");
        }

        example.setOrderByClause("create_time desc");
        return merchantMapper.selectByExample(example);
    }

}
