/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package com.unis.basic.info.modular.grainPriceCollect.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.unis.basic.info.modular.grainPriceCollect.entity.GrainPriceCollect;
import com.unis.basic.info.modular.grainPriceCollect.mapper.GrainPriceCollectMapper;
import com.unis.basic.info.modular.grainPriceCollect.param.GrainPriceCollectAddParam;
import com.unis.basic.info.modular.grainPriceCollect.param.GrainPriceCollectEditParam;
import com.unis.basic.info.modular.grainPriceCollect.param.GrainPriceCollectIdParam;
import com.unis.basic.info.modular.grainPriceCollect.param.GrainPriceCollectPageParam;
import com.unis.basic.info.modular.grainPriceCollect.service.GrainPriceCollectService;
import com.unis.basic.info.modular.grainPriceCollectCategory.entity.GrainPriceCollectCategory;
import com.unis.basic.info.modular.grainPriceCollectCategory.param.GrainPriceCollectCategoryAddParam;
import com.unis.basic.info.modular.grainPriceCollectCategory.param.GrainPriceCollectCategoryEditParam;
import com.unis.basic.info.modular.grainPriceCollectCategory.service.GrainPriceCollectCategoryService;
import com.unis.basic.info.modular.grainPriceCollectCitySum.entity.GrainPriceCollectCitySum;
import com.unis.basic.info.modular.grainPriceCollectCitySum.service.GrainPriceCollectCitySumService;
import com.unis.basic.info.modular.remindcycle.entity.RemindCycle;
import com.unis.basic.info.modular.remindcycle.service.RemindCycleService;
import com.unis.common.enums.CommonSortOrderEnum;
import com.unis.common.exception.CommonException;
import com.unis.common.page.CommonPageRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId; 
import java.time.LocalTime;
import java.util.*;

/**
 * 粮食价格采集Service接口实现类
 *
 * @author TS
 * @date  2024/04/03 10:44
 **/
@Service
public class GrainPriceCollectServiceImpl extends ServiceImpl<GrainPriceCollectMapper, GrainPriceCollect> implements GrainPriceCollectService {
    @Resource
    private  GrainPriceCollectMapper grainPriceCollectMapper;

    @Resource
    private RemindCycleService remindCycleService;

    @Autowired
    private GrainPriceCollectCategoryService grainPriceCollectCategoryService;

    @Autowired
    private GrainPriceCollectCitySumService grainPriceCollectCitySumService;
    @Override
    public Page<GrainPriceCollect> page(GrainPriceCollectPageParam grainPriceCollectPageParam) {
        QueryWrapper<GrainPriceCollect> queryWrapper = new QueryWrapper<>();
        if(ObjectUtil.isAllNotEmpty(grainPriceCollectPageParam.getSortField(), grainPriceCollectPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(grainPriceCollectPageParam.getSortOrder());
            queryWrapper.orderBy(true, grainPriceCollectPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(grainPriceCollectPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(GrainPriceCollect::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(GrainPriceCollectAddParam grainPriceCollectAddParam) {
        GrainPriceCollect grainPriceCollect = BeanUtil.toBean(grainPriceCollectAddParam, GrainPriceCollect.class);
        List<RemindCycle>  remindCycles =   remindCycleService.list();
        RemindCycle re=remindCycles.get(0);
        // 获取当前时间
        Date date  = new Date();
        // 将 Date 转换为 Instant
        Instant instant = date.toInstant();
        // 将 Instant 转换为 LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        // 从 LocalDateTime 中提取 LocalTime
        LocalTime sfmday = localDateTime.toLocalTime();

        //开始时间
        Instant sta =remindCycles.get(0).getStartTime().toInstant();
        LocalDateTime star = LocalDateTime.ofInstant(sta, ZoneId.systemDefault());
        LocalTime start = star.toLocalTime();

        //结束时间
        Instant e =remindCycles.get(0).getEndTime().toInstant();
        LocalDateTime en = LocalDateTime.ofInstant(e, ZoneId.systemDefault());
        LocalTime end = star.toLocalTime();
        if(DateUtil.dayOfWeek(date) % 7 + 1 == remindCycles.get(0).getDayOfWeek()){
            if(sfmday.isAfter(start) && sfmday.isBefore(end)){
                grainPriceCollect.setIsInRemindCycle(1);
            }else {
                grainPriceCollect.setIsInRemindCycle(0);
            }
        }else {
            grainPriceCollect.setIsInRemindCycle(0);
        }
        grainPriceCollect.setUserCollectDate(date);
        grainPriceCollect.setUserCollectDateCount(1);
        //得到品种价格采集信息
        this.saveOrUpdate(grainPriceCollect);
        //价格采集主键id
        String id = grainPriceCollect.getId();
        //检测是否有备注
        Boolean isRemark = StringUtils.isBlank(grainPriceCollect.getRemark()); //
        List<GrainPriceCollectCategoryAddParam>  categoryAddParamList = grainPriceCollectAddParam.getCategoryAddParamList();
        List<GrainPriceCollectCategory> categoryList = new ArrayList<>();
        for (int i = 0; i <categoryAddParamList.size() ; i++) {
            //得到价格品种数据
            GrainPriceCollectCategory category =  BeanUtil.toBean(categoryAddParamList.get(i),GrainPriceCollectCategory.class);
            category.setTypeId(id);
            //没有备注，进行检测
            if (isRemark) {
                boolean isOver = comparePrice(grainPriceCollect, category);
                if (isOver){
                    throw new CommonException("本周/月汇总粮食平均价超出上周/月汇总粮食平均价5%以上，需要填报备注说明，否则不能上报");
                }
            }
            categoryList.add(category);
        }
        grainPriceCollectCategoryService.saveOrUpdateBatch(categoryList);
    }
    //得到最新相同相同监测点，同品种，同价格类型的价格采集时间最近的一条数据
    private boolean comparePrice(GrainPriceCollect grainPriceCollect, GrainPriceCollectCategory category) {

        List<Map<String,Object>> categoryList1 = grainPriceCollectMapper.getOffPrice(grainPriceCollect.getId(),grainPriceCollect.getPriceMonitorId().toString(),category.getType().toString(),
                category.getPriceType().toString(),
                category.getFirstLevel().toString(),
                category.getSecondLevel().toString(),
                category.getThreeLevel().toString()
        );
        //未查到最新一条数据，表示是第一次录入，直接检测通过
        BigDecimal offPrice ;
        if (categoryList1.size() == 1){
            //得到上一期间价格
            offPrice  = NumberUtil.toBigDecimal(categoryList1.get(0).get("offPrice").toString());
        }else{
            return  false;
        }
        //得到本期价格
        BigDecimal avgPrice  = category.getPrice();
        //与上周同期比 =（本期间平价价格-上期间平价价格）/本期间平价价格
        BigDecimal weekRate  =  NumberUtil.div(NumberUtil.sub(avgPrice,offPrice),avgPrice);
//        本周/月汇总粮食平均价超出上周/月汇总粮食平均价5%以上，需要填报备注说明，否则不能上报。
//        如果今日汇总粮食平均价超出上日粮食平均价2%以上，需要填报备注说明，否则不能上报。
        return NumberUtil.compare(weekRate.doubleValue(),NumberUtil.parseDouble("0.05")) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(GrainPriceCollectEditParam grainPriceCollectEditParam) {
        GrainPriceCollect grainPriceCollect = this.queryEntity(grainPriceCollectEditParam.getId());
        if(ObjectUtil.isEmpty(grainPriceCollect)) {
            throw new CommonException("粮食价格采集不存在，id值为：{}", grainPriceCollect.getId());
        }

        //表示已经审核
        if(grainPriceCollect.getAuditStatus() == 1 ) {
            throw new CommonException("粮食价格采集已审核，id值为：{}", grainPriceCollect.getId());
        }
        List<GrainPriceCollectCategoryEditParam>  categoryEditParamList = grainPriceCollectEditParam.getCategoryEditParamList();
        if(categoryEditParamList ==null || categoryEditParamList.size() <= 0) {
            throw new CommonException("粮食价格采集价格不能为空，id值为：{}", grainPriceCollect.getId());
        }
        grainPriceCollectEditParam.setUserCollectDateCount(grainPriceCollect.getUserCollectDateCount()+1);
        BeanUtil.copyProperties(grainPriceCollectEditParam, grainPriceCollect);
        this.updateById(grainPriceCollect);

        //检测是否有备注
        Boolean isRemark = StringUtils.isBlank(grainPriceCollect.getRemark()); //
        //得到采集价格品种
        String id = grainPriceCollect.getId();
        //先删除历史数据
        QueryWrapper<GrainPriceCollectCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type_id",id);
        List<GrainPriceCollectCategory> categoryList = new ArrayList<>();
        if ( grainPriceCollectCategoryService.remove(queryWrapper)){
            for (int i = 0; i <categoryEditParamList.size() ; i++) {
                //得到价格品种数据
                GrainPriceCollectCategory category =  BeanUtil.toBean(categoryEditParamList.get(i),GrainPriceCollectCategory.class);
                category.setTypeId(id);
                //没有备注，进行检测
                if (isRemark) {
                    boolean isOver = comparePrice(grainPriceCollect, category);
                    if (isOver){
                        throw new CommonException("本周/月汇总粮食平均价超出上周/月汇总粮食平均价5%以上，需要填报备注说明，否则不能上报");
                    }
                }
            }
            grainPriceCollectCategoryService.saveOrUpdateBatch(categoryList);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(GrainPriceCollectIdParam grainPriceCollectIdParam) {
        GrainPriceCollect grainPriceCollect = this.queryEntity(grainPriceCollectIdParam.getId());
        if(ObjectUtil.isEmpty(grainPriceCollect)) {
            throw new CommonException("粮食价格采集不存在，id值为：{}", grainPriceCollect.getId());
        }
        //表示已经审核
        if(grainPriceCollect.getAuditStatus() == 1) {
            throw new CommonException("粮食价格采集已审核，id值为：{}", grainPriceCollect.getId());
        }
            // 执行删除
        this.removeById(grainPriceCollectIdParam.getId());
        //删除采集价格品种数据
        QueryWrapper<GrainPriceCollectCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type_id",grainPriceCollectIdParam.getId());
        grainPriceCollectCategoryService.remove(queryWrapper);
    }

    @Override
    public GrainPriceCollect detail(GrainPriceCollectIdParam grainPriceCollectIdParam) {
        return this.queryEntity(grainPriceCollectIdParam.getId());
    }

    @Override
    public GrainPriceCollect queryEntity(String id) {
        GrainPriceCollect grainPriceCollect = this.getById(id);
        if(ObjectUtil.isEmpty(grainPriceCollect)) {
            throw new CommonException("粮食价格采集不存在，id值为：{}", id);
        }
        //得到采集价格品种
        QueryWrapper<GrainPriceCollectCategory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type_id",id);
        List<GrainPriceCollectCategory> collectCategoryList  = grainPriceCollectCategoryService.list(queryWrapper);
        grainPriceCollect.setCollectCategoryList(collectCategoryList);
        return grainPriceCollect;
    }

    /**
     * 获取粮监测点信息
     * * @author TS
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getMonitorInfo(String userId) {
        List<Map<String, Object>> monitorInfos = grainPriceCollectMapper.getMonitorInfo(userId);
        return monitorInfos;
    }

    /**
     * 获取当前用户最近粮监测点信息
     *
     * @param userId
     * @param point
     * @return
     */
    @Override
    public Map<String, Object> getMonitorInfoByPoint(String userId, String point) {
        Map<String, Object> monitorInfo = grainPriceCollectMapper.getMonitorInfoByPoint(userId,point);
        return monitorInfo;
    }

    /**
     * 获取自定义粮食价格采集分页
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<Map<String, Object>> findPage(GrainPriceCollectPageParam pageParam) {
        //条形查询器
        QueryWrapper<GrainPriceCollectCitySum> queryWrapper = new QueryWrapper<>();
        //分页相关
        if(StringUtils.isNotBlank(pageParam.getMonitorName())){
            queryWrapper.like("b.name",pageParam.getMonitorName() );
        }
        if(pageParam.getStatus() != null && pageParam.getStatus() >= 0){
            queryWrapper.eq("a.status",pageParam.getStatus() );
        }
        //app列表只展示当天数据
        if(pageParam.getIsApp() != null && pageParam.getIsApp() == 1){
            queryWrapper.apply(" DATE_FORMAT(ifnull(a.user_collect_date,NOW()),'%Y-%m-%d') =  DATE_FORMAT(NOW(),'%Y-%m-%d')");
        }
        Page<GrainPriceCollectCitySum> p =new Page<>(pageParam.getCurrent(),pageParam.getSize());

        IPage<Map<String,Object>> page = grainPriceCollectMapper.selectMyMapsPage(p,queryWrapper);
        return page;
    }

    /**
     * 审核粮食价格采集
     *
     * @param idParam
     * @return
     */
    @Override
    public String audit(GrainPriceCollectIdParam idParam) {
        GrainPriceCollect grainPriceCollect = this.getById(idParam.getId());
        if(ObjectUtil.isEmpty(grainPriceCollect)) {
            throw new CommonException("粮食价格采集不存在，id值为：{}", grainPriceCollect.getId());
        }
        //表示已经审核,并且不能再次审核
        if(grainPriceCollect.getAuditStatus() == 1 && idParam.getAuditStatus() == 1) {
            throw new CommonException("粮食价格采集已审核，id值为：{}", grainPriceCollect.getId());
        }
        if(idParam.getAuditStatus() == 2){ //表示是驳回
            if(grainPriceCollect.getAuditStatus() == 2) {
                throw new CommonException("粮食价格采集已驳回，id值为：{}", grainPriceCollect.getId());
            }
            //检测省级是否汇总.如果省级已经汇总，则必须市级已处于驳回并且删除省级汇总才行
            if (grainPriceCollect.getGrainPriceCollectCityId() != null && grainPriceCollect.getGrainPriceCollectCityId() >0){

                GrainPriceCollectCitySum citySum =  grainPriceCollectCitySumService.getById(grainPriceCollect.getGrainPriceCollectCityId());
                if (ObjectUtil.isNotEmpty(citySum)){
                    if (citySum.getGrainPriceCollectProvinceSumId() != null ){
                        throw new CommonException("市级汇总必须驳回后才可进行价格采集驳回！");
                    }
                }
            }
            if(StringUtils.isBlank(idParam.getAuditRejectAdvice())){
                throw new CommonException("驳回必须填写驳回意见！");
            }
        }
        grainPriceCollect.setAuditStatus(idParam.getAuditStatus());
        if (StringUtils.isNotBlank(idParam.getAuditRejectAdvice())){
            grainPriceCollect.setAuditRejectAdvice(idParam.getAuditRejectAdvice());
        }
        return this.updateById(grainPriceCollect)?"处理成功":"处理失败";
    }

}
