package com.hai.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.BankNumberUtil;
import com.hai.dao.HighMerchantAccountMapper;
import com.hai.entity.*;
import com.hai.enum_type.MerAccountMarketingType;
import com.hai.enum_type.MerAmountSourceTypeEnum;
import com.hai.enum_type.MerAmountTypeEnum;
import com.hai.model.HighMerchantModel;
import com.hai.model.HighMerchantStoreModel;
import com.hai.model.UserInfoModel;
import com.hai.service.HighMerchantAccountMarketingService;
import com.hai.service.HighMerchantAccountRecordService;
import com.hai.service.HighMerchantAccountService;
import com.hai.service.HighMerchantService;
import org.apache.commons.collections4.MapUtils;
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.Date;
import java.util.List;
import java.util.Map;

@Service("merchantAccountService")
public class HighMerchantAccountServiceImpl implements HighMerchantAccountService {

    @Resource
    private HighMerchantAccountMapper merchantAccountMapper;

    @Resource
    private HighMerchantService merchantService;

    @Resource
    private HighMerchantAccountRecordService merchantAccountRecordService;

    @Resource
    private HighMerchantAccountMarketingService marketingService;

    @Resource
    private UserCenter userCenter;

    @Override
    public void editMerchantAccount(HighMerchantAccount merchantAccount) {
        if (merchantAccount.getId() == null) {
            merchantAccount.setAccountNo(BankNumberUtil.getBrankNumber("6"));
            merchantAccount.setCreateTime(new Date());
            merchantAccount.setUpdateTime(new Date());
            merchantAccount.setStatus(1);
            merchantAccountMapper.insert(merchantAccount);
        } else {
            merchantAccount.setUpdateTime(new Date());
            merchantAccountMapper.updateByPrimaryKey(merchantAccount);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void recharge(Long merId, BigDecimal amount, Map<String, Object> marketingParam, Map<String, Object> otherParam) {
        UserInfoModel userInfoModel = userCenter.getSessionModel(UserInfoModel.class);

        // 查询商户
        HighMerchant merchant = merchantService.getDetailById(merId);
        if (merchant == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
        }
        // 是否开通了账户
        HighMerchantAccount account = getMerAccountDetail(merId);
        if (account == null) {
            account = new HighMerchantAccount();
            account.setMerId(merId);
            account.setAmounts(new BigDecimal("0"));
        }

        // 本次交易金额
        BigDecimal tradePrice = amount;

        HighMerchantAccountRecord accountRecord = new HighMerchantAccountRecord();
        accountRecord.setMarketingStatus(MapUtils.getBoolean(marketingParam, "marketingStatus"));

        // 营销活动
        if (MapUtils.getBoolean(marketingParam, "marketingStatus") == true) {
            if (MapUtils.getInteger(marketingParam, "marketingType").equals(MerAccountMarketingType.type1.getType())) {
                accountRecord.setMarketingType(MerAccountMarketingType.type1.getType());
                accountRecord.setMarketingPrice(new BigDecimal(MapUtils.getString(marketingParam, "marketingPrice")));
                accountRecord.setMarketingTradePrice(new BigDecimal(MapUtils.getString(marketingParam, "marketingPrice")));
                tradePrice = tradePrice.add(accountRecord.getMarketingTradePrice());
            }

            if (MapUtils.getInteger(marketingParam, "marketingType").equals(MerAccountMarketingType.type2.getType())) {
                accountRecord.setMarketingType(MerAccountMarketingType.type2.getType());
                accountRecord.setMarketingPrice(new BigDecimal(MapUtils.getString(marketingParam, "marketingPrice")));
                accountRecord.setMarketingTradePrice(amount.multiply(new BigDecimal(MapUtils.getString(marketingParam, "marketingPrice")).setScale(BigDecimal.ROUND_HALF_DOWN)));
                tradePrice = tradePrice.add(accountRecord.getMarketingTradePrice());
            }

            if (MapUtils.getInteger(marketingParam, "marketingType").equals(MerAccountMarketingType.type3.getType())) {
                HighMerchantAccountMarketing accountMarketing = marketingService.getDetailByMerAndType(merId, MerAccountMarketingType.type3.getType());
                if (accountMarketing == null) {
                    accountMarketing = new HighMerchantAccountMarketing();
                    accountMarketing.setType(MerAccountMarketingType.type3.getType());
                    accountMarketing.setMerId(merId);
                    accountMarketing.setMerAccountId(account.getId());
                    JSONArray oilNoData = (JSONArray) marketingParam.get("marketingOilNoData");
                    accountMarketing.setOilNoReliefPrice(oilNoData.toJSONString());
                    marketingService.insert(accountMarketing);
                } else {
                    JSONArray oilNoData = (JSONArray) marketingParam.get("marketingOilNoData");
                    accountMarketing.setOilNoReliefPrice(oilNoData.toJSONString());
                    marketingService.update(accountMarketing);
                }
            }
        }

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

        accountRecord.setMerAmountId(account.getId());
        accountRecord.setMerId(merchant.getId());
        accountRecord.setMerName(merchant.getMerchantName());
        accountRecord.setType(MerAmountTypeEnum.type1.getType());
        accountRecord.setAmount(amount);
        accountRecord.setTradePrice(tradePrice);
        accountRecord.setBeforeAmount(beforeAmount);
        accountRecord.setAfterAmount(afterAmount);
        accountRecord.setSourceType(MerAmountSourceTypeEnum.type1.getType());
        accountRecord.setOpUserId(userInfoModel.getSecUser().getId());
        accountRecord.setOpUserName(userInfoModel.getSecUser().getUserName());
        merchantAccountRecordService.insert(accountRecord);
    }

    @Override
    public HighMerchantAccount getMerAccountDetail(Long merId) {
        HighMerchantAccountExample example = new HighMerchantAccountExample();
        example.createCriteria().andStatusEqualTo(1).andMerIdEqualTo(merId);
        List<HighMerchantAccount> list = merchantAccountMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BigDecimal countMerGasOilAmount(Long merId) {
        return merchantAccountMapper.countMerGasOilAmount(merId);
    }

    @Override
    public List<Map<String, Object>> getStoreGasOilAmountByMer(Long merId) {
        return merchantAccountMapper.selectStoreGasOilAmountByMer(merId);
    }
}
