package com.hzs.bonus.bonus.controller.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hzs.bonus.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.bonus.base.service.ICuMemberService;
import com.hzs.bonus.bonus.param.RetailAreaParam;
import com.hzs.bonus.bonus.service.ICuMemberSpeRetailService;
import com.hzs.common.core.annotation.Log;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.msg.ConfigMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.poi.ExcelUtil;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.member.bonus.CuMemberSpeRetail;
import com.hzs.common.domain.member.ext.CuMemberExt;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.util.TransactionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 注水盒数 前端控制器
 */
@RestController
@RequestMapping("/manage/special")
public class CuMemberSpeRetailController extends BaseController {

    @Autowired
    private ICuMemberService iCuMemberService;
    @Autowired
    private ICuMemberSpeRetailService iCuMemberSpeRetailService;
    @Autowired
    private ICuMemberSettlePeriodService iCuMemberSettlePeriodService;

    /**
     * 注水列表
     **/
    @Log(module = EOperationModule.SPECIAL_BUSINESS, business = EOperationBusiness.INJECT_RETAIL_ACHIEVEMENT, method = EOperationMethod.SELECT)
    @GetMapping("/list")
    public TableDataInfo list(RetailAreaParam retailAreaParam) {
        startPage();
        retailAreaParam.setSystemType(SecurityUtils.getSystemType());
        retailAreaParam.setPkCountry(SecurityUtils.getPkCountry());
        List<RetailAreaParam> list = iCuMemberSpeRetailService.getCuMemberSpeRetail(retailAreaParam);
        return getDataTable(list);
    }

    /**
     * 新增注水
     **/
    @PostMapping("/save")
    @RepeatSubmitSimple
    @Log(module = EOperationModule.SPECIAL_BUSINESS, business = EOperationBusiness.INJECT_RETAIL_ACHIEVEMENT, method = EOperationMethod.INSERT)
    public AjaxResult saveCuBonusExpand(@RequestBody RetailAreaParam retailAreaParam) {
        if (StringUtils.isEmpty(retailAreaParam.getMemberCode())) {
            return AjaxResult.error("会员信息不存在");
        }
        //校验团队总盒数大于小区盒数
//        if (retailAreaParam.getTeamBoxNum() < retailAreaParam.getSmallBoxNum()) {
        if (retailAreaParam.getTeamBoxNum().compareTo(retailAreaParam.getSmallBoxNum()) < 0) {
            return AjaxResult.error("团队盒数需大于小区盒数");
        }
        //校验结算日期是否为空
        if (StringUtils.isNull(retailAreaParam.getSettleDate())) {
            return AjaxResult.error("结算日期不能为空");
        }
        if (iCuMemberSpeRetailService.checkCuMemberActivate(retailAreaParam.getMemberCode()) == 0) {
            return AjaxResult.error("会员未激活，不可注水");
        }
        Integer systemType = SecurityUtils.getSystemType();
        CuMemberExt me = iCuMemberService.getMemberByCode(retailAreaParam.getMemberCode());
        if (null == me || me.getCategory() != ECategory.NORMAL.getValue()) {
            return AjaxResult.error("会员信息不存在或已撤单");
        }

        if (DateUtils.compareDateBefore(retailAreaParam.getSettleDate(), me.getCreationTime())) {
            return AjaxResult.error("注水日期不能在会员创建之前");
        }
        if (!DateUtils.isLatestWeek(retailAreaParam.getSettleDate(), new Date())) {
            return AjaxResult.error("只能注水7天以内");
        }

        //查询最新期数
        String datestr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, retailAreaParam.getSettleDate());
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                DateUtils.parseDateToStr(datestr)).getPkId();
        retailAreaParam.setPeriod(period);

        //校验是否已经注水
        LambdaUpdateWrapper<CuMemberSpeRetail> cmsrQw = new LambdaUpdateWrapper<>();
        cmsrQw.eq(CuMemberSpeRetail::getMemberCode, retailAreaParam.getMemberCode());
        cmsrQw.eq(CuMemberSpeRetail::getPeriod, period);
        cmsrQw.eq(CuMemberSpeRetail::getSystemType, systemType);
        int check = iCuMemberSpeRetailService.count(cmsrQw);
        if (check > 0) {
            return AjaxResult.error("会员已注水");
        }
        CuMemberSpeRetail cmsr = BeanUtil.copyProperties(retailAreaParam, CuMemberSpeRetail.class);
        cmsr.setCreationTime(new Date());
        cmsr.setPkCreator(SecurityUtils.getUserId());
        cmsr.setPkCountry(SecurityUtils.getPkCountry());
        cmsr.setPeriodDate(DateUtils.getStartTime(retailAreaParam.getSettleDate()));
        cmsr.setSystemType(systemType);
        return AjaxResult.success(iCuMemberSpeRetailService.save(cmsr));
    }

    /**
     * 批量添加秒接日志记录表
     **/
    @Log(module = EOperationModule.SPECIAL_BUSINESS, business = EOperationBusiness.INJECT_RETAIL_ACHIEVEMENT, method = EOperationMethod.IMPORT)
    @PostMapping("/importData")
    @RepeatSubmitSimple
    public AjaxResult importData(MultipartFile file) throws Exception {
        ExcelUtil<RetailAreaParam> util = new ExcelUtil<>(RetailAreaParam.class);
        Integer pkCountry = SecurityUtils.getPkCountry();
        Integer systemType = SecurityUtils.getSystemType();
        Long pkCreator = SecurityUtils.getUserId();
        List<RetailAreaParam> list = util.importExcel(file.getInputStream());
        List<RetailAreaParam> memberList = new ArrayList<>();
        List<RetailAreaParam> errorlist = new ArrayList<>();
        //去重
        Set<String> seenMemberCodesRepeat = new HashSet<>();
        List<RetailAreaParam> uniqueList = list.stream()
                .filter(p -> seenMemberCodesRepeat.add(p.getMemberCode())) // 如果Set中不存在则保留
                .collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(list)) {
            Set<String> seenMemberCodes = new HashSet<>();
            for (RetailAreaParam cma : uniqueList) {
                cma.setSystemType(systemType);
                if (StringUtils.isNotEmpty(cma.getMemberCode())) {
                    //校验结算日期是否为空
                    if (StringUtils.isNull(cma.getSettleDate())) {
                        cma.setMsg("结算日期不能为空");
                        errorlist.add(cma);
                        continue;
                    }
                    //校验团队总盒数大于小区盒数
//                    if (cma.getTeamBoxNum() < cma.getSmallBoxNum()) {
                    if (cma.getTeamBoxNum().compareTo(cma.getSmallBoxNum()) < 0) {
                        cma.setMsg("团队盒数需大于小区盒数");
                        errorlist.add(cma);
                        continue;
                    }
                    if (!DateUtils.isLatestWeek(cma.getSettleDate(), new Date())) {
                        return AjaxResult.error("只能注水7天以内");
                    }
                    if (iCuMemberSpeRetailService.checkCuMemberActivate(cma.getMemberCode()) == 0) {
                        cma.setMsg("会员未激活，不可注水");
                        errorlist.add(cma);
                        continue;
                    }
                    //查询最新期数
                    String datestr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, cma.getSettleDate());
                    int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                            DateUtils.parseDateToStr(datestr)).getPkId();
                    cma.setPeriod(period);
                    cma.setPeriodDate(DateUtils.getStartTime(cma.getSettleDate()));
                    // 遍历传入的RetailAreaParam列表
                    if (!seenMemberCodes.add(cma.getMemberCode())) {
                        // 如果memberCode已经在映射中存在，则表示这是一个重复项
                        // 将之前存储的对象加入错误列表
                        cma.setMsg("会员编号重复");
                        // 并且也将当前对象加入错误列表
                        errorlist.add(cma);
                        continue;
                    }
                    CuMemberExt me = iCuMemberService.getMemberByCode(cma.getMemberCode());
                    if (null == me || me.getCategory() != ECategory.NORMAL.getValue()) {
                        cma.setMsg("会员信息不存在或已撤单");
                        errorlist.add(cma);
                        continue;
                    }
                    if (DateUtils.compareDateBefore(cma.getSettleDate(), me.getCreationTime())) {
                        cma.setMsg("注水日期不能在会员创建之前");
                        errorlist.add(cma);
                        continue;
                    }
                    //校验是否已经注水
                    LambdaUpdateWrapper<CuMemberSpeRetail> cmsr = new LambdaUpdateWrapper<>();
                    cmsr.eq(CuMemberSpeRetail::getMemberCode, cma.getMemberCode());
                    cmsr.eq(CuMemberSpeRetail::getPeriod, period);
                    cmsr.eq(CuMemberSpeRetail::getSystemType, systemType);
                    int check = iCuMemberSpeRetailService.count(cmsr);
                    if (check > 0) {
                        cma.setMsg("会员已注水");
                        errorlist.add(cma);
                        continue;
                    }
                    memberList.add(cma);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(memberList)) {
            iCuMemberSpeRetailService.batchSpeRetail(memberList, pkCountry, pkCreator);
        }
        if (CollectionUtil.isNotEmpty(errorlist)) {
            return AjaxResult.error(504, TransactionUtils.getContent(ConfigMsgConstants.MEMBER_DATA_ERROR), errorlist);
        }
        return AjaxResult.success();
    }

    /**
     * 下载模板
     **/
    @Log(module = EOperationModule.SPECIAL_BUSINESS, business = EOperationBusiness.INJECT_RETAIL_ACHIEVEMENT, method = EOperationMethod.EXPORT)
    @PostMapping("/download")
    public void download(HttpServletResponse response) {
        List<RetailAreaParam> list = new ArrayList<>();
        ExcelUtil<RetailAreaParam> util = new ExcelUtil<>(RetailAreaParam.class);
        util.exportExcel(response, list, "新零售注水");
    }

    /**
     * 查询单条新零售注水信息
     **/
    @GetMapping("/getOne/{pkId}")
    public AjaxResult getOne(@PathVariable Long pkId) {
        RetailAreaParam param = new RetailAreaParam();
        param.setPkId(pkId);
        List<RetailAreaParam> retailAreaParam = iCuMemberSpeRetailService.getCuMemberSpeRetail(param);
        if (!DateUtils.isLatestWeek(retailAreaParam.get(0).getSettleDate(), new Date())) {
            return AjaxResult.error("只能修改7天以内注水");
        }
        if (CollectionUtil.isNotEmpty(retailAreaParam)) {
            return AjaxResult.success(retailAreaParam.get(0));
        } else {
            return AjaxResult.success();
        }
    }

    /**
     * 修改注水
     **/
    @Log(module = EOperationModule.SPECIAL_BUSINESS, business = EOperationBusiness.INJECT_RETAIL_ACHIEVEMENT, method = EOperationMethod.UPDATE)
    @PostMapping("/update")
    public AjaxResult update(@RequestBody RetailAreaParam retailAreaParam) {
        if (StringUtils.isEmpty(retailAreaParam.getMemberCode())) {
            return AjaxResult.error("会员信息不存在");
        }
        //校验团队总盒数大于小区盒数
//        if (retailAreaParam.getTeamBoxNum() < retailAreaParam.getSmallBoxNum()) {
        if (retailAreaParam.getTeamBoxNum().compareTo(retailAreaParam.getSmallBoxNum()) < 0) {
            return AjaxResult.error("团队盒数需大于小区盒数");
        }
        //校验结算日期是否为空
        if (StringUtils.isNull(retailAreaParam.getSettleDate())) {
            return AjaxResult.error("结算日期不能为空");
        }

        if (!DateUtils.isLatestWeek(retailAreaParam.getSettleDate(), new Date())) {
            return AjaxResult.error("只能注水7天以内");
        }
        CuMemberExt me = iCuMemberService.getMemberByCode(retailAreaParam.getMemberCode());
        if (null == me || me.getCategory() != ECategory.NORMAL.getValue()) {
            return AjaxResult.error("会员信息不存在或已撤单");
        }
        if (DateUtils.compareDateBefore(retailAreaParam.getSettleDate(), me.getCreationTime())) {
            return AjaxResult.error("注水日期不能在会员创建之前");
        }
        //查询最新期数
        String datestr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, retailAreaParam.getSettleDate());
        int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(
                DateUtils.parseDateToStr(datestr)).getPkId();
        retailAreaParam.setPeriod(period);

        //校验是否已经注水
        LambdaUpdateWrapper<CuMemberSpeRetail> cmsrQw = new LambdaUpdateWrapper<>();
        cmsrQw.eq(CuMemberSpeRetail::getMemberCode, retailAreaParam.getMemberCode());
        cmsrQw.eq(CuMemberSpeRetail::getPeriod, period);
        cmsrQw.ne(CuMemberSpeRetail::getPkId, retailAreaParam.getPkId());
        int check = iCuMemberSpeRetailService.count(cmsrQw);
        if (check > 0) {
            return AjaxResult.error("会员已注水");
        }
        CuMemberSpeRetail cmsr = BeanUtil.copyProperties(retailAreaParam, CuMemberSpeRetail.class);
        cmsr.setPeriodDate(DateUtils.getStartTime(retailAreaParam.getSettleDate()));
        cmsr.setPkModified(SecurityUtils.getUserId());
        cmsr.setModifiedTime(new Date());
        return AjaxResult.success(iCuMemberSpeRetailService.updateById(cmsr));
    }

    /**
     * 删除注水
     **/
    @Log(module = EOperationModule.SPECIAL_BUSINESS, business = EOperationBusiness.INJECT_RETAIL_ACHIEVEMENT, method = EOperationMethod.DELETE)
    @DeleteMapping("/{pkId}")
    public AjaxResult delete(@PathVariable Long pkId) {
        RetailAreaParam param = new RetailAreaParam();
        param.setPkId(pkId);
        List<RetailAreaParam> retailAreaParam = iCuMemberSpeRetailService.getCuMemberSpeRetail(param);
        if (!DateUtils.isLatestWeek(retailAreaParam.get(0).getSettleDate(), new Date())) {
            return AjaxResult.error("只能删除7天以内注水");
        }
        LambdaUpdateWrapper<CuMemberSpeRetail> cmsrQw = new LambdaUpdateWrapper<>();
        cmsrQw.eq(CuMemberSpeRetail::getPkId, pkId);
        cmsrQw.set(CuMemberSpeRetail::getDelFlag, EDelFlag.DELETE.getValue());
        cmsrQw.set(CuMemberSpeRetail::getPkModified, SecurityUtils.getUserId());
        cmsrQw.set(CuMemberSpeRetail::getModifiedTime, new Date());
        return AjaxResult.success(iCuMemberSpeRetailService.update(cmsrQw));
    }

}
