package com.hfkj.service.rebate.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.RedisUtil;
import com.hfkj.dao.BsRebateActivityMapper;
import com.hfkj.entity.BsRebateActivity;
import com.hfkj.entity.BsRebateActivityAccount;
import com.hfkj.entity.BsRebateActivityExample;
import com.hfkj.service.rebate.BsRebateActivityAccountService;
import com.hfkj.service.rebate.BsRebateActivityService;
import com.hfkj.sysenum.RebateActivityEndTypeEnum;
import com.hfkj.sysenum.RebateActivityStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @className: BsRebateActivityServiceImpl
 * @author: HuRui
 * @date: 2023/10/18
 **/
@Service("rebateActivityService")
public class BsRebateActivityServiceImpl implements BsRebateActivityService {

    @Resource
    private BsRebateActivityMapper rebateActivityMapper;

    @Resource
    private BsRebateActivityAccountService rebateActivityAccountService;

    @Autowired
    private RedisUtil redisUtil;

    private final static String REBATE_ACTIVITY = "REBATE_ACTIVITY";
    private final static String MER_CURRENT_REBATE_ACTIVITY = "MER_CURRENT_REBATE_ACTIVITY";

    @Override
    public void editData(BsRebateActivity rebateActivity) {
        if (rebateActivity.getId() == null) {
            rebateActivity.setCreateTime(new Date());
            rebateActivity.setUpdateTime(new Date());
            rebateActivityMapper.insert(rebateActivity);

            // 创建活动账户
            BsRebateActivityAccount account = new BsRebateActivityAccount();
            account.setActivityId(rebateActivity.getId());
            account.setActivityNo(rebateActivity.getActivityNo());
            account.setAmount(new BigDecimal("0"));
            account.setStatus(1);
            rebateActivityAccountService.createAccount(account);
        } else {
            rebateActivity.setUpdateTime(new Date());
            rebateActivityMapper.updateByPrimaryKey(rebateActivity);
        }
        redisUtil.set(REBATE_ACTIVITY + ":" +rebateActivity.getActivityNo(), rebateActivity);
    }

    @Override
    public void openActivity(String activityNo) {
        // 活动
        BsRebateActivity activity = getActivityByNo(activityNo);
        if (activity == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到活动");
        }
        if (!activity.getStatus().equals(RebateActivityStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "活动状态错误");
        }
        // 查询当前线上活动
        if (getMerCurrentActivity(activity.getMerNo()) != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "已达到线上活动数量限制，当前已有活动正在进行中");
        }
        activity.setStartTime(new Date());
        activity.setStatus(RebateActivityStatusEnum.status2.getNumber());
        editData(activity);

        // 存入缓存
        redisUtil.set(MER_CURRENT_REBATE_ACTIVITY + ":" + activity.getMerNo(), activity);
    }

    @Override
    public void closeActivity(String activityNo, RebateActivityEndTypeEnum rebateActivityEndTypeEnum) {
        // 活动
        BsRebateActivity activity = getActivityByNo(activityNo);
        if (activity == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到活动");
        }
        if (!activity.getStatus().equals(RebateActivityStatusEnum.status2.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "活动状态错误");
        }
        activity.setStatus(RebateActivityStatusEnum.status3.getNumber());
        activity.setRealityEndType(rebateActivityEndTypeEnum.getNumber());

        if (RebateActivityEndTypeEnum.type1.getNumber().equals(rebateActivityEndTypeEnum.getNumber())) {
            activity.setRealityEndTime(activity.getEndTime());
        } else if (RebateActivityEndTypeEnum.type2.getNumber().equals(rebateActivityEndTypeEnum.getNumber())) {
            activity.setRealityEndTime(new Date());
        }
        editData(activity);

        // 删除缓存
        redisUtil.del(MER_CURRENT_REBATE_ACTIVITY + ":" + activity.getMerNo());
    }

    @Override
    public void updateActivityEndTime(String activityNo, Date newEndTime) {
        // 活动
        BsRebateActivity activity = getActivityByNo(activityNo);
        if (activity == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到活动");
        }
        activity.setEndTime(newEndTime);
        editData(activity);
    }

    @Override
    public BsRebateActivity getActivityByNo(String activityNo) {
        String key = REBATE_ACTIVITY + ":" + activityNo;
        // 获取缓存
        Object obj = redisUtil.get(key);
        if (obj != null) {
            return (BsRebateActivity) obj;
        }
        BsRebateActivityExample example = new BsRebateActivityExample();
        example.createCriteria().andActivityNoEqualTo(activityNo).andStatusNotEqualTo(RebateActivityStatusEnum.status0.getNumber());
        List<BsRebateActivity> list = rebateActivityMapper.selectByExample(example);
        if (list.size() > 0) {
            BsRebateActivity rebateActivity = list.get(0);
            redisUtil.set(REBATE_ACTIVITY + ":" +rebateActivity.getActivityNo(), rebateActivity);
            return rebateActivity;
        }
        return null;
    }

    @Override
    public BsRebateActivity getMerCurrentActivity(String merNo) {
        // 从缓存中读取
        Object obj = redisUtil.get(MER_CURRENT_REBATE_ACTIVITY + ":" + merNo);
        if (obj != null) {
            return (BsRebateActivity) obj;
        } else {
            return null;
        }
    }

    @Override
    public List<BsRebateActivity> getActivityList(Map<String, Object> param) {
        BsRebateActivityExample example = new BsRebateActivityExample();
        BsRebateActivityExample.Criteria criteria = example.createCriteria()
                .andStatusNotEqualTo(RebateActivityStatusEnum.status0.getNumber());

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

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

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

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merAbbreviate"))) {
            criteria.andMerAbbreviateLike(MapUtils.getString(param, "merAbbreviate"));
        }

        if (MapUtils.getLong(param, "endTimeS") != null) {
            criteria.andEndTimeGreaterThanOrEqualTo(new Date(MapUtils.getLong(param, "endTimeS")));
        }

        if (MapUtils.getLong(param, "endTimeE") != null) {
            criteria.andEndTimeLessThanOrEqualTo(new Date(MapUtils.getLong(param, "endTimeE")));
        }


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

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