package com.hai.service.impl;

import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.security.UserCenter;
import com.hai.common.utils.RedisUtil;
import com.hai.dao.ApiAmountRecordMapper;
import com.hai.dao.ApiMerchantsMapper;
import com.hai.dao.ApiProductConfigMapper;
import com.hai.entity.*;
import com.hai.model.ApiProductConfigModel;
import com.hai.model.UserInfoModel;
import com.hai.service.ApiMerchantsService;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service("apiMerchantsService")
public class ApiMerchantsServiceImpl implements ApiMerchantsService {

    @Resource
    private ApiMerchantsMapper apiMerchantsMapper;

    @Resource
    private UserCenter userCenter;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private ApiAmountRecordMapper apiAmountRecordMapper;

    @Resource
    private ApiProductConfigMapper apiProductConfigMapper;

    @Override
    public void insertApiMerchants(ApiMerchants apiMerchants) {
        apiMerchantsMapper.insert(apiMerchants);
    }

    @Override
    public synchronized void updateApiMerchants(ApiMerchants apiMerchants) {
        apiMerchantsMapper.updateByPrimaryKey(apiMerchants);
    }

    @Override
    public List<ApiMerchants> getListApiMerchants(Map<String, Object> map) {
        ApiMerchantsExample example = new ApiMerchantsExample();
        ApiMerchantsExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getString(map, "merchantName") != null) {
            criteria.andMerchantNameLike("%" +  MapUtils.getString(map, "merchantName") + "%");
        }
        if (MapUtils.getString(map, "phone") != null) {
            criteria.andPhoneEqualTo(MapUtils.getString(map, "phone"));
        }
        if (MapUtils.getString(map, "mchId") != null) {
            criteria.andMchIdEqualTo(MapUtils.getString(map, "mchId"));
        }

        if (MapUtils.getLong(map, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(map, "status"));
        }
        return apiMerchantsMapper.selectByExample(example);
    }

    @Override
    public ApiMerchants findById(Long id) {
        return apiMerchantsMapper.selectByPrimaryKey(id);
    }

    @Override
    public ApiMerchants findByMchId(String mchId) {
        ApiMerchantsExample example = new ApiMerchantsExample();
        example.createCriteria().andMchIdEqualTo(mchId).andStatusEqualTo(100);

        List<ApiMerchants> list = apiMerchantsMapper.selectByExample(example);
        if (list.size() > 0) {
           return apiMerchantsMapper.selectByExample(example).get(0);
        }
        return  null;
    }

    @Override
    @Transactional(rollbackFor=Exception.class,isolation = Isolation.SERIALIZABLE,propagation= Propagation.REQUIRES_NEW)
    public void recharge(Long merchantId, BigDecimal amount, Map<String, Object> otherParam) {

        // 查询商户
        ApiMerchants apiMerchants = apiMerchantsMapper.selectByPrimaryKey(merchantId);
        if (apiMerchants == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
        }
        // 操作人
        UserInfoModel sessionModel = userCenter.getSessionModel(UserInfoModel.class);
        if (sessionModel == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知用户");
        }
        if ( sessionModel.getSecRole().getRoleType() != 1) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "权限不足");
        }
        if (apiMerchants.getStatus() != 100) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户被禁用");
        }

        // 变更前金额
        BigDecimal beforeAmount = apiMerchants.getAmounts();
        // 计算金额
        apiMerchants.setAmounts(apiMerchants.getAmounts().add(amount));
        // 变更后金额
        BigDecimal afterAmount = apiMerchants.getAmounts();

        updateApiMerchants(apiMerchants);

        ApiAmountRecord apiAmountRecord = new ApiAmountRecord();

        apiAmountRecord.setCreateTime(new Date());
        apiAmountRecord.setUpdateTime(new Date());
        apiAmountRecord.setMchId(apiMerchants.getMchId());
        apiAmountRecord.setOperatorId(sessionModel.getSecUser().getId());
        apiAmountRecord.setOperatorName(sessionModel.getSecUser().getUserName());
        apiAmountRecord.setStatus(100);
        apiAmountRecord.setAmount(amount);
        apiAmountRecord.setAfterAmount(afterAmount);
        apiAmountRecord.setBeforeAmount(beforeAmount);
        apiAmountRecord.setAmountType(1);
        apiAmountRecord.setSourceType(MapUtils.getInteger(otherParam, "sourceType"));
        apiAmountRecord.setSourceId(MapUtils.getLong(otherParam, "sourceId"));
        apiAmountRecord.setSourceContent(apiMerchants.getMerchantName() + MapUtils.getString(otherParam, "sourceContent"));

        apiAmountRecordMapper.insert(apiAmountRecord);

        redisUtil.del("COMPANY_AMOUNT_RECHARGE_SMS_CODE");

    }

    @Override
    public List<ApiAmountRecord> getMerchRechargeData(Long merchantId) {

        ApiMerchants apiMerchants = apiMerchantsMapper.selectByPrimaryKey(merchantId);

        ApiAmountRecordExample example = new ApiAmountRecordExample();
        example.createCriteria().andMchIdEqualTo(apiMerchants.getMchId());
        return apiAmountRecordMapper.selectByExample(example);
    }

    @Override
    public List<ApiProductConfigModel> getListMerchProduct(Long merchantId) {
        return apiProductConfigMapper.getListMerchProduct(merchantId);
    }

    @Override
    public List<ApiProductConfigModel> getMerchProduct(Long merchantId , Integer rechargeType) {
        return apiProductConfigMapper.getMerchProduct(merchantId , rechargeType);
    }


}
