package com.tofly.feesapi.sfgl.service.impl;

import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.common.core.util.StringUtil;
import com.tofly.feesapi.common.core.dto.Order;
import com.tofly.feesapi.common.core.dto.PageDto;
import com.tofly.feesapi.common.core.vo.PageResult;
import com.tofly.feesapi.common.exception.FeesErrorCode;
import com.tofly.feesapi.common.exception.FeesException;

import com.tofly.feesapi.common.util.GuidGenerator;
import com.tofly.feesapi.common.znj.ZnjCal;
import com.tofly.feesapi.security.util.SecurityUtils;
import com.tofly.feesapi.sfgl.entity.YyQfmx;
import com.tofly.feesapi.sfgl.entity.YyWyjtz;
import com.tofly.feesapi.sfgl.entity.dto.*;
import com.tofly.feesapi.sfgl.entity.vo.YyQfmxWyjSelect;
import com.tofly.feesapi.sfgl.entity.vo.YyWyjtzVo;
import com.tofly.feesapi.sfgl.service.YyQfmxService;
import com.tofly.feesapi.sfgl.service.YyWyjtzService;
import com.tofly.feesapi.yhgl.entity.YhKhjbxx;
import com.tofly.feesapi.yhgl.service.YhKhjbxxService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.tofly.feesapi.sfgl.mapper.YyWyjtzMapper;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 违约金调整记录表
 */
@Service
public class YyWyjtzServiceImpl extends ServiceImpl<YyWyjtzMapper, YyWyjtz> implements YyWyjtzService {
    @Autowired
    private YhKhjbxxService yhKhjbxxService;
    @Autowired
    private YyQfmxService yyQfmxService;
    @Autowired
    private ZnjCal znjCal;

    @Override
    public Boolean wyjtzSave(YyWyjtzUpdate dto) {
        if (StringUtil.isEmpty(dto.getGdlsbh())) {
            throw new FeesException("工单流水编号不能为空！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (dto.getJmje().compareTo(BigDecimal.ZERO) <= 0) {
            throw new FeesException("减免金额必须大于0！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (StringUtil.isEmpty(dto.getType())) {
            throw new FeesException("减免类型不能为空！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (StringUtil.isEmpty(dto.getJmyj())) {
            throw new FeesException("减免依据不能为空！", FeesErrorCode.BUSINESS_ERROR);
        }
        List<YyWyjtz> wyjtzList = this.lambdaQuery()
                .eq(YyWyjtz::getGdlsbh, dto.getGdlsbh())
                .eq(YyWyjtz::getGdzt, "2")
                .list();
        if (wyjtzList.size() == 0) {
            throw new FeesException("未查询到相关的减免记录！", FeesErrorCode.BUSINESS_ERROR);
        }
        List<YyQfmx> yyQfmxs = yyQfmxService.lambdaQuery()
                .apply(String.format("id in (select qfid from yy_wyjtz where gdlsbh='%s')", dto.getGdlsbh()))
                .list();
        for (YyWyjtz wyjtz : wyjtzList) {
            YyQfmx yyQfmx = yyQfmxs.stream().filter(qf -> qf.getId().equals(wyjtz.getQfid())).findFirst().get();
            if (dto.getType().equals("0")) {
                wyjtz.setTzje(dto.getJmje());
                wyjtz.setTzqje(yyQfmx.getZnj());
                wyjtz.setTzhje(yyQfmx.getZnj().subtract(dto.getJmje()));
            }
            if (dto.getType().equals("1")) {
                wyjtz.setTzje(yyQfmx.getZnj().divide(BigDecimal.valueOf(2), 2, RoundingMode.HALF_UP));
                wyjtz.setTzqje(yyQfmx.getZnj().subtract(wyjtz.getTzje()));
                wyjtz.setTzhje(yyQfmx.getZnj().subtract(wyjtz.getTzje()));
            }
            if (dto.getType().equals("2")) {
                wyjtz.setTzje(yyQfmx.getZnj());
                wyjtz.setTzqje(yyQfmx.getZnj());
                wyjtz.setTzhje(BigDecimal.ZERO);
            }
            wyjtz.setTzyy(dto.getTzyy());
            wyjtz.setType(dto.getType());
            wyjtz.setJmyj(dto.getJmyj());
            wyjtz.setGdzt("3");
            this.updateById(wyjtz);
        }
        znjCal.YyQfmxZnj(yyQfmxs.get(0).getYhbh(), yyQfmxs);
        return true;
    }

    @Override
    @Transactional
    public String wyjtzSave_gd(YyWyjtzGdDto yyWyjtzGdDto) {
        String gdlsbh = GuidGenerator.getGuid();
        for (YyWyjtzDto dto : yyWyjtzGdDto.getYyWyjtzDtoList()) {
            if (StringUtil.isEmpty(dto.getYhbh())) {
                throw new FeesException("存在用户编号为空！", FeesErrorCode.BUSINESS_ERROR);
            }
            if (StringUtil.isEmpty(dto.getQfid())) {
                throw new FeesException("存在欠费ID为空！", FeesErrorCode.BUSINESS_ERROR);
            }
            YhKhjbxx yhKhjbxx = yhKhjbxxService.getById(dto.getYhbh());
            if (StringUtil.isNull(yhKhjbxx)) {
                throw new FeesException(String.format("[%s]用户信息不存在！", dto.getYhbh()), FeesErrorCode.BUSINESS_ERROR);
            }
            List<YyQfmx> yyQfmxs = yyQfmxService.lambdaQuery()
                    .eq(YyQfmx::getId, dto.getQfid())
                    .list();
            if (yyQfmxs.size() == 0) {
                throw new FeesException(String.format("[%s]欠费流水信息不存在！", dto.getQfid()), FeesErrorCode.BUSINESS_ERROR);
            }
            YyWyjtz yyWyjtz = new YyWyjtz();
            BeanUtils.copyProperties(dto, yyWyjtz);
            yyWyjtz.setId(GuidGenerator.getGuid().substring(0, 8));
            yyWyjtz.setCzrybm(String.valueOf(SecurityUtils.getUserId()));
            yyWyjtz.setCzryxm(SecurityUtils.getUser().getRealName());
            yyWyjtz.setSsgs(yyQfmxs.get(0).getSsgs());
            yyWyjtz.setCwrq(yyQfmxs.get(0).getCwrq());
            yyWyjtz.setYsyf(yyQfmxs.get(0).getYsyf());
            yyWyjtz.setCzsj(new Date());
            yyWyjtz.setSfbz("0");
            yyWyjtz.setGdzt("1");//工单状态处理中
            yyWyjtz.setGdlsbh(gdlsbh);
            this.save(yyWyjtz);
        }
        return gdlsbh;
    }

    @Override
    public Boolean wyjtzSaveAll(YyWyjtzDto dto) {
        if (StringUtil.isEmpty(dto.getYhbh())) {
            throw new FeesException("用户编号不能为空！", FeesErrorCode.BUSINESS_ERROR);
        }
        List<YyQfmx> yyQfmxs = yyQfmxService.list(
                new QueryWrapper<YyQfmx>().lambda()
                        .eq(YyQfmx::getYhbh, dto.getYhbh())
                        .eq(YyQfmx::getSfbz, "0")
        );
        for (YyQfmx yyQfmx : yyQfmxs) {
            YyWyjtz yyWyjtz = new YyWyjtz();
            yyWyjtz.setYhbh(yyQfmx.getYhbh());
            yyWyjtz.setQfid(yyQfmx.getId());
            yyWyjtz.setCwrq(yyQfmx.getCwrq());
            yyWyjtz.setYsyf(yyQfmx.getYsyf());
            yyWyjtz.setTzqje(yyQfmx.getZnj());
            yyWyjtz.setTzje(yyQfmx.getZnj().multiply(BigDecimal.valueOf(-1)));
            yyWyjtz.setTzhje(BigDecimal.ZERO);
            yyWyjtz.setTzyy("领导签字同意减免");
            yyWyjtz.setShyj("领导签字同意减免");
            yyWyjtz.setShry(SecurityUtils.getUser().getRealName());
            yyWyjtz.setCzrybm(String.valueOf(SecurityUtils.getUserId()));
            yyWyjtz.setCzryxm(SecurityUtils.getUser().getRealName());
            yyWyjtz.setCzsj(new Date());
            yyWyjtz.setSsgs(yyQfmx.getSsgs());
            yyWyjtz.setSfbz("0");
            this.save(yyWyjtz);
        }
        return true;
    }

    @Override
    public Boolean wyjtzSaveAllOne(YyWyjtzDto dto) {
        if (StringUtil.isEmpty(dto.getYhbh())) {
            throw new FeesException("用户编号不能为空！", FeesErrorCode.BUSINESS_ERROR);
        }
        if (StringUtil.isEmpty(dto.getQfid())) {
            throw new FeesException("欠费ID不能为空！", FeesErrorCode.BUSINESS_ERROR);
        }
        YyQfmx yyQfmx = yyQfmxService.getById(dto.getQfid());
        YyWyjtz yyWyjtz = new YyWyjtz();
        yyWyjtz.setYhbh(yyQfmx.getYhbh());
        yyWyjtz.setQfid(yyQfmx.getId());
        yyWyjtz.setCwrq(yyQfmx.getCwrq());
        yyWyjtz.setYsyf(yyQfmx.getYsyf());
        yyWyjtz.setTzqje(yyQfmx.getZnj());
        yyWyjtz.setTzje(yyQfmx.getZnj().multiply(BigDecimal.valueOf(-1)));
        yyWyjtz.setTzhje(BigDecimal.ZERO);
        yyWyjtz.setTzyy("领导签字同意减免");
        yyWyjtz.setShyj("领导签字同意减免");
        yyWyjtz.setShry(SecurityUtils.getUser().getRealName());
        yyWyjtz.setCzrybm(String.valueOf(SecurityUtils.getUserId()));
        yyWyjtz.setCzryxm(SecurityUtils.getUser().getRealName());
        yyWyjtz.setCzsj(new Date());
        yyWyjtz.setSsgs(yyQfmx.getSsgs());
        yyWyjtz.setSfbz("0");
        return this.save(yyWyjtz);
    }

    @Override
    public Boolean wyjtzSaveHalf(YyWyjtzDto dto) {
        if (StringUtil.isEmpty(dto.getYhbh())) {
            throw new FeesException("用户编号不能为空！", FeesErrorCode.BUSINESS_ERROR);
        }
        List<YyQfmx> yyQfmxs = yyQfmxService.list(
                new QueryWrapper<YyQfmx>().lambda()
                        .eq(YyQfmx::getYhbh, dto.getYhbh())
                        .eq(YyQfmx::getSfbz, "0")
        );
        for (YyQfmx yyQfmx : yyQfmxs) {
            YyWyjtz yyWyjtz = new YyWyjtz();
            yyWyjtz.setYhbh(yyQfmx.getYhbh());
            yyWyjtz.setQfid(yyQfmx.getId());
            yyWyjtz.setCwrq(yyQfmx.getCwrq());
            yyWyjtz.setYsyf(yyQfmx.getYsyf());
            yyWyjtz.setTzqje(yyQfmx.getZnj());
            yyWyjtz.setTzje(yyQfmx.getZnj().divide(BigDecimal.valueOf(2)).multiply(BigDecimal.valueOf(-1)));
            yyWyjtz.setTzhje(yyQfmx.getZnj().subtract(yyQfmx.getZnj().divide(BigDecimal.valueOf(2))));
            yyWyjtz.setTzyy("领导签字同意减免");
            yyWyjtz.setShyj("领导签字同意减免");
            yyWyjtz.setShry(SecurityUtils.getUser().getRealName());
            yyWyjtz.setCzrybm(String.valueOf(SecurityUtils.getUserId()));
            yyWyjtz.setCzryxm(SecurityUtils.getUser().getRealName());
            yyWyjtz.setCzsj(new Date());
            yyWyjtz.setSsgs(yyQfmx.getSsgs());
            yyWyjtz.setSfbz("0");
            this.save(yyWyjtz);
        }
        return true;
    }


    public YyQfmxWyjSelect getPage(PageDto pageDto, YyWyjtzFilter dto) {
        List<Order> orders = pageDto.getOrders();
        if (orders.isEmpty()) {
            orders.add(new Order("a.czsj", false));
        }
        if (orders.size() > 0) {
            orders = orders.stream().map(item -> {
                if (item.getColumn().equals("czsj")) {
                    Order order = new Order();
                    order.setColumn("a.czsj");
                    order.setAsc(item.isAsc());
                    return order;
                }
                return item;
            }).collect(Collectors.toList());
        }
        pageDto.setOrders(orders);
        YyQfmxWyjSelect yyQfmxWyjSelect = this.baseMapper.getWyjhj(dto);
        yyQfmxWyjSelect.setPageResult(this.baseMapper.getPage(pageDto, dto).toVo());
        return yyQfmxWyjSelect;
    }

    @Override
    public List<YyWyjtzVo> getList(YyWyjtzFilter dto) {
        List<YyWyjtzVo> list = this.baseMapper.getPage(dto);
        return list;
    }

    public PageResult<YyWyjtzVo> getGdPage(PageDto pageDto, YyWyjtzFilter dto) {
        List<YyQfmx> list = yyQfmxService.lambdaQuery()
                .eq(YyQfmx::getSfbz, "0")
                .eq(YyQfmx::getChbz, "0")
                .eq(YyQfmx::getSfbc, "0")
                .apply("id in (select qfid from yy_wyjtz where gdzt='2' and sfbz='0')")
                .list();
        if (list.size() > 0) {
            List<String> yhbhList = list.stream()
                    .sorted(Comparator.comparing(YyQfmx::getYhbh))
                    .map(YyQfmx::getYhbh).distinct()
                    .collect(Collectors.toList());
            for (String yhbh : yhbhList) {
                List<YyQfmx> yyQfmxs = list.stream().filter(e -> e.getYhbh().equals(yhbh)).collect(Collectors.toList());
                znjCal.YyQfmxZnj(yhbh, yyQfmxs);
            }
        }

        List<Order> orders = pageDto.getOrders();
        if (orders.isEmpty()) {
            orders.add(new Order("a.gdbh", false));
        }
        if (orders.size() > 0) {
            orders = orders.stream().map(item -> {
                if (item.getColumn().equals("gdbh")) {
                    Order order = new Order();
                    order.setColumn("a.gdbh");
                    order.setAsc(item.isAsc());
                    return order;
                }
                return item;
            }).collect(Collectors.toList());
        }
        pageDto.setOrders(orders);

        return this.baseMapper.getGdPage(pageDto, dto).toVo();
    }

    public YyWyjtzVo getGdWyjInfo(String gdlsbh) {
        YyWyjtzFilter dto = new YyWyjtzFilter();
        dto.setGdlsbh(gdlsbh);
        List<YyWyjtzVo> list = this.baseMapper.getGdPage(dto);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public void gxwyjtzjl(String qfid) {
        LambdaQueryWrapper<YyWyjtz> wrapper = Wrappers.<YyWyjtz>lambdaQuery().eq(YyWyjtz::getQfid, qfid)
                .eq(YyWyjtz::getSfbz, "1");
        YyWyjtz yyWyjtz = baseMapper.selectOne(wrapper);
        if (ObjUtil.isNull(yyWyjtz)) {
            return;
        }

        yyWyjtz.setSfbz("0");
        updateById(yyWyjtz);
    }
}
