package com.ruoyi.warehouseBusiness.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.approvalFlow.domain.AuditItems;
import com.ruoyi.approvalFlow.service.impl.AuditItemsServiceImpl;
import com.ruoyi.basicData.domain.TCorps;
import com.ruoyi.basicData.domain.TFees;
import com.ruoyi.basicData.domain.TGoods;
import com.ruoyi.basicData.mapper.TCorpsMapper;
import com.ruoyi.basicData.mapper.TFeesMapper;
import com.ruoyi.basicData.mapper.TGoodsMapper;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.mapper.SysDeptMapper;
import com.ruoyi.warehouseBusiness.domain.BillnoDel;
import com.ruoyi.warehouseBusiness.domain.TWarehouseAgreement;
import com.ruoyi.warehouseBusiness.domain.TWarehouseAgreementitems;
import com.ruoyi.warehouseBusiness.mapper.BillnoDelMapper;
import com.ruoyi.warehouseBusiness.mapper.TWarehouseAgreementMapper;
import com.ruoyi.warehouseBusiness.mapper.TWarehouseAgreementitemsMapper;
import com.ruoyi.warehouseBusiness.service.ITWarehouseAgreementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.*;

/**
 * 仓储费Service业务层处理
 *
 * @author ruoyi
 * @date 2020-12-11
 */
@Service
public class TWarehouseAgreementServiceImpl implements ITWarehouseAgreementService {
    @Autowired
    private TWarehouseAgreementMapper tWarehouseAgreementMapper;

    @Autowired
    private TWarehouseAgreementitemsMapper tWarehouseAgreementitemsMapper;

    @Autowired
    private BillnoSerialServiceImpl billnoSerialServiceImpl;

    @Autowired
    private BillnoDelMapper billnoDelMapper;

    @Autowired
    private TCorpsMapper tCorpsMapper;

    @Autowired
    private TGoodsMapper tGoodsMapper;

    @Autowired
    private TFeesMapper tFeesMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private AuditItemsServiceImpl auditItemsService;


    /**
     * 查询仓储费
     *
     * @param fId 仓储费ID
     * @return 仓储费
     */
    @Override
    public TWarehouseAgreement selectTWarehouseAgreementById(Long fId) {
        return tWarehouseAgreementMapper.selectTWarehouseAgreementById(fId);
    }

    @Override
    public Map<String, Object> selectTWarehouseAgreementById1(Long fId) {
        Map<String, Object> map = new HashMap<>();
        // 查询协议主表数据
        TWarehouseAgreement tWarehouseAgreement = tWarehouseAgreementMapper.selectTWarehouseAgreementById(fId);
        // 客户表
        List<Long> corpsId = new ArrayList<>();
        // 用户表
        List<SysUser> sysUserList = new ArrayList<>();
        // 商品
        List<Long> goodsId = new ArrayList<>();
        // 费用
        List<Long> feesId = new ArrayList<>();
        if (!StringUtils.isNull(tWarehouseAgreement)) {
            corpsId.add(tWarehouseAgreement.getfCorpid());
            goodsId.add(tWarehouseAgreement.getfGoodsid());
            map.put("tWarehouseAgreement", tWarehouseAgreement);
        }
        // 协议从表
        TWarehouseAgreementitems tWarehouseAgreementitems = new TWarehouseAgreementitems();
        tWarehouseAgreementitems.setfPid(fId);
        List<TWarehouseAgreementitems> tWarehouseAgreementitemss = tWarehouseAgreementitemsMapper.selectTWarehouseAgreementitemsList(tWarehouseAgreementitems);
        if (StringUtils.isNotEmpty(tWarehouseAgreementitemss)) {
            for (TWarehouseAgreementitems fees : tWarehouseAgreementitemss) {
                feesId.add(fees.getfFeeid());
            }
        }
        List<TCorps> corpsList = new ArrayList<>();
        List<Long> corpsIdList = StringUtils.integerDeduplication(corpsId);
        for (Long corpId : corpsIdList) {
            TCorps corps = tCorpsMapper.selectTCorpsById(corpId);
            if (StringUtils.isNotNull(corps)) {
                corpsList.add(corps);
            }
        }
        List<TGoods> goodsList = new ArrayList<>();
        List<Long> goodsIdList = StringUtils.integerDeduplication(goodsId);
        for (Long goods : goodsIdList) {
            TGoods tGoods = tGoodsMapper.selectTGoodsById(goods);
            if (StringUtils.isNotNull(tGoods)) {
                goodsList.add(tGoods);
            }
        }
        List<TFees> feesList = new ArrayList<>();
        List<Long> longList = StringUtils.integerDeduplication(feesId);
        for (Long fees : longList) {
            TFees tFees = tFeesMapper.selectTFeesById(fees);
            if (StringUtils.isNotNull(tFees)) {
                feesList.add(tFees);
            }
        }
        map.put("corps", corpsList);
        map.put("goodsList", goodsList);
        map.put("feesList", feesList);
        map.put("tWarehouseAgreementitems", tWarehouseAgreementitemss);
        map.put("dept", sysDeptMapper.selectDeptById(tWarehouseAgreement.getfDeptid()));
        return map;
    }


    /**
     * 查询仓储费列表
     *
     * @param tWarehouseAgreement 仓储费
     * @return 仓储费
     */
    @Override
    public List<Map<String, Object>> selectTWarehouseAgreementList1(TWarehouseAgreement tWarehouseAgreement) {
        return tWarehouseAgreementMapper.selectTWarehouseAgreementList1(tWarehouseAgreement);
    }

    /**
     * 查询仓储费列表
     *
     * @param tWarehouseAgreement 仓储费
     * @return 仓储费
     */
    @Override
    public List<TWarehouseAgreement> selectTWarehouseAgreementList(TWarehouseAgreement tWarehouseAgreement) {
        return tWarehouseAgreementMapper.selectTWarehouseAgreementList(tWarehouseAgreement);
    }


    /**
     * 新增
     *
     * @param agreement
     * @param agreementitems
     * @param loginUser
     * @return
     */
    @Override
    @Transactional
    public AjaxResult insertTWarehouseAgreement(String agreement, String agreementitems, LoginUser loginUser, int fFeetypeid) {
        Long fPid = null;
        Map<String, Object> map = new HashMap<>();
        TWarehouseAgreement tWarehouseAgreement = JSONArray.parseObject(agreement, TWarehouseAgreement.class);
        if (StringUtils.isNull(tWarehouseAgreement.getfId())) {
            // 如果是新数据
            tWarehouseAgreement.setCreateBy(loginUser.getUser().getUserName());
            tWarehouseAgreement.setCreateTime(new Date());
            // 业务编码
            String billNo = billnoSerialServiceImpl.getBillNo("WA", new Date());
            tWarehouseAgreement.setfBillno(billNo);
            tWarehouseAgreement.setfDeptid(loginUser.getUser().getDeptId());
            tWarehouseAgreement.setfFeetypeid((long) fFeetypeid);
            tWarehouseAgreement.setfStatus("1"); // 停用
            tWarehouseAgreement.setfBillstatus("2"); // 暂存
            tWarehouseAgreementMapper.insertTWarehouseAgreement(tWarehouseAgreement);
            fPid = tWarehouseAgreement.getfId();
        } else {
            fPid = tWarehouseAgreement.getfId();
            tWarehouseAgreement.setfBillstatus("2");
            tWarehouseAgreement.setUpdateBy(loginUser.getUser().getUserName());
            tWarehouseAgreement.setUpdateTime(new Date());
            tWarehouseAgreementMapper.updateTWarehouseAgreement(tWarehouseAgreement);
            tWarehouseAgreementitemsMapper.deleteByFPid(fPid);
        }
        //  从表添加
        if (StringUtils.isNotNull(agreementitems) && !"[]".equals(agreementitems)) {
            JSONArray jsonDrArray = JSONArray.parseArray(agreementitems);
            List<TWarehouseAgreementitems> tWarehouseAgreementitemsList = JSONObject.parseArray(jsonDrArray.toJSONString(), TWarehouseAgreementitems.class);
            for (TWarehouseAgreementitems tWarehouseAgreementitems : tWarehouseAgreementitemsList) {
                tWarehouseAgreementitems.setfPid(fPid);
                tWarehouseAgreementitems.setCreateBy(loginUser.getUser().getUserName());
                tWarehouseAgreementitems.setCreateTime(new Date());
                tWarehouseAgreementitemsMapper.insertTWarehouseAgreementitems(tWarehouseAgreementitems);
            }
        }
        TWarehouseAgreementitems tWarehouseAgreementitems = new TWarehouseAgreementitems();
        tWarehouseAgreementitems.setfPid(fPid);
        map.put("tWarehouseAgreement", tWarehouseAgreement);
        map.put("tWarehouseAgreementitems", tWarehouseAgreementitemsMapper.selectTWarehouseAgreementitemsList(tWarehouseAgreementitems));
        return AjaxResult.success("成功", map);
    }

    /**
     * 仓储费请核
     *
     * @param agreement
     * @param agreementitems
     * @param loginUser
     * @param fFeetypeid
     * @return
     */
    @Override
    @Transactional
    public AjaxResult tWarehouseAgreementSubmit(String agreement, String agreementitems, LoginUser loginUser, int fFeetypeid) {
        Long fPid = null;
        TWarehouseAgreement tWarehouseAgreement = JSONArray.parseObject(agreement, TWarehouseAgreement.class);
        if (StringUtils.isNull(tWarehouseAgreement.getfId())) {
            // 如果是新数据
            tWarehouseAgreement.setCreateBy(loginUser.getUser().getUserName());
            // 业务编码
            String billNo = billnoSerialServiceImpl.getBillNo("WA", new Date());
            tWarehouseAgreement.setfBillno(billNo);
            tWarehouseAgreement.setCreateBy(loginUser.getUser().getUserName());
            tWarehouseAgreement.setfDeptid(loginUser.getUser().getDeptId());
            tWarehouseAgreement.setfFeetypeid((long) fFeetypeid);
            tWarehouseAgreement.setfStatus("1"); // 停用
            tWarehouseAgreement.setfBillstatus("4");
            tWarehouseAgreementMapper.insertTWarehouseAgreement(tWarehouseAgreement);
            fPid = tWarehouseAgreement.getfId();
        } else {
            fPid = tWarehouseAgreement.getfId();
            tWarehouseAgreement.setfBillstatus("4");
            tWarehouseAgreement.setUpdateBy(loginUser.getUser().getUserName());
            tWarehouseAgreement.setUpdateTime(new Date());
            tWarehouseAgreementMapper.updateTWarehouseAgreement(tWarehouseAgreement);
            tWarehouseAgreementitemsMapper.deleteByFPid(fPid);
        }
        //  从表添加
        if (StringUtils.isNotNull(agreementitems) && !"[]".equals(agreementitems)) {
            JSONArray jsonDrArray = JSONArray.parseArray(agreementitems);
            List<TWarehouseAgreementitems> tWarehouseAgreementitemsList = JSONObject.parseArray(jsonDrArray.toJSONString(), TWarehouseAgreementitems.class);
            for (TWarehouseAgreementitems tWarehouseAgreementitems : tWarehouseAgreementitemsList) {
                tWarehouseAgreementitems.setfPid(fPid);
                tWarehouseAgreementitems.setCreateBy(loginUser.getUser().getUserName());
                tWarehouseAgreementitems.setCreateTime(new Date());
                tWarehouseAgreementitemsMapper.insertTWarehouseAgreementitems(tWarehouseAgreementitems);
            }
        }
        // 这里加个判断取系统参数来确定是否需要启用审批流
        String key = "";
        boolean isApprove = false;
        long actId = 0L;
        if (fFeetypeid == 0) {
            actId = 310L;
            key = "warehouse.storage.ApprovalFlow";
        } else if (fFeetypeid == 1) {
            actId = 320L;
            key = "warehouse.task.ApprovalFlow";
        }
        SysConfig sysConfig = sysConfigMapper.checkConfigKeyUnique(key);
        if (StringUtils.isNull(sysConfig)) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("系统参数异常，未找到开启审批流参数");
        }
        if ("0".equals(sysConfig.getConfigValue())) {
            isApprove = true;
        }
        if (isApprove) {
            AuditItems auditItems = new AuditItems();
            auditItems.setLevelId(0L);
            auditItems.setBillId(fPid);
            auditItems.setActId(actId);
            auditItems.setIffinalItem("F");
            auditItems.setBillNo(tWarehouseAgreement.getfBillno());
            auditItems.setRefno1(String.valueOf(tWarehouseAgreement.getfCorpid()));
            if (tWarehouseAgreement.getfFeetypeid() == 0) {
                auditItems.setRefno2("CCF");// 存储业务类型（业务类型）
            } else {
                auditItems.setRefno2("ZYF");// 存储业务类型（业务类型）
            }
            auditItems.setSendUserId(loginUser.getUser().getUserId());
            auditItems.setSendName(loginUser.getUsername());
            auditItems.setSendTime(new Date());
            auditItems.setAuditUserId(loginUser.getUser().getUserId());
            auditItems.setAuditItem(new Date());
            auditItems.setAuditOpTime(new Date());
            auditItems.setAuditMsg("提交");
            auditItems.setAuditStatus("O");
            AjaxResult approvalFlow = auditItemsService.createApprovalFlow(auditItems);
            Long code = Long.valueOf(String.valueOf(approvalFlow.get("code"))).longValue();
            if (code.equals(500L)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
            return approvalFlow;
        } else {
            AjaxResult ajaxResult = agreementFollow(fPid, 6L);
            Long code = Long.valueOf(String.valueOf(ajaxResult.get("code"))).longValue();
            return ajaxResult;
        }
    }

    @Override
    public AjaxResult revoke(String agreement, String agreementitems, LoginUser loginUser, int fFeetypeid) {
        Long fPid = null;
        TWarehouseAgreement tWarehouseAgreement = JSONArray.parseObject(agreement, TWarehouseAgreement.class);
        fPid = tWarehouseAgreement.getfId();
        tWarehouseAgreement.setfStatus("1"); // 停用
        tWarehouseAgreement.setfBillstatus("2");// 暂存
        tWarehouseAgreement.setUpdateBy(loginUser.getUser().getUserName());
        tWarehouseAgreement.setUpdateTime(new Date());
        tWarehouseAgreementMapper.updateTWarehouseAgreement(tWarehouseAgreement);
        tWarehouseAgreementitemsMapper.deleteByFPid(fPid);
        //  从表添加
        if (StringUtils.isNotNull(agreementitems) && !"[]".equals(agreementitems)) {
            JSONArray jsonDrArray = JSONArray.parseArray(agreementitems);
            List<TWarehouseAgreementitems> tWarehouseAgreementitemsList = JSONObject.parseArray(jsonDrArray.toJSONString(), TWarehouseAgreementitems.class);
            for (TWarehouseAgreementitems tWarehouseAgreementitems : tWarehouseAgreementitemsList) {
                tWarehouseAgreementitems.setfPid(fPid);
                tWarehouseAgreementitems.setCreateBy(loginUser.getUser().getUserName());
                tWarehouseAgreementitems.setCreateTime(new Date());
                tWarehouseAgreementitemsMapper.insertTWarehouseAgreementitems(tWarehouseAgreementitems);
            }
        }
        return AjaxResult.success();
    }

    /**
     * 根据协议主表id 更新对应明细表状态
     *
     * @param fPid 协议主表id
     * @return 结果
     */
    @Transactional
    public AjaxResult agreementFollow(Long fPid, long fettle) {
        if (StringUtils.isNull(fPid)) {
            return AjaxResult.error("协议更新状态未找到主表信息，请与管理员联系");
        }
        TWarehouseAgreement tWarehouseAgreement = new TWarehouseAgreement();
        tWarehouseAgreement.setfId(fPid);
        tWarehouseAgreement.setfBillstatus(String.valueOf(fettle));
        int tFeeUpdateResult = tWarehouseAgreementMapper.updateTWarehouseAgreement(tWarehouseAgreement);
        if (tFeeUpdateResult <= 0) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("更新协议明细状态失败，请联系管理员");
        }
        return AjaxResult.success();
    }

    /**
     * 修改仓储费
     *
     * @param tWarehouseAgreement 仓储费
     * @return 结果
     */
    @Override
    public int updateTWarehouseAgreement(TWarehouseAgreement tWarehouseAgreement) {
        tWarehouseAgreement.setUpdateTime(DateUtils.getNowDate());
        return tWarehouseAgreementMapper.updateTWarehouseAgreement(tWarehouseAgreement);
    }

    /**
     * 批量删除仓储费
     *
     * @param fIds 需要删除的仓储费ID
     * @return 结果
     */
    @Override
    public int deleteTWarehouseAgreementByIds(Long[] fIds) {
        // 取出业务编号、 放入 billno_del
        for (Long id : fIds) {
            // 1、查询主表信息
            TWarehouseAgreement tWarehouseAgreement = tWarehouseAgreementMapper.selectTWarehouseAgreementById(id);
            // 2、业务编号、客存编号 放入 billno_del
            BillnoDel billnoDel = new BillnoDel();
            billnoDel.setBillType("WA");
            billnoDel.setBillNo(tWarehouseAgreement.getfBillno());
            billnoDelMapper.insertBillnoDel(billnoDel);
        }
        return tWarehouseAgreementMapper.deleteTWarehouseAgreementByIds(fIds);
    }

    /**
     * 删除仓储费信息
     *
     * @param fId 仓储费ID
     * @return 结果
     */
    @Override
    public int deleteTWarehouseAgreementById(Long fId) {
        return tWarehouseAgreementMapper.deleteTWarehouseAgreementById(fId);
    }

    @Override
    public AjaxResult queryRemove(Long fId) {
        // 查询协议主表数据
        TWarehouseAgreement tWarehouseAgreement = tWarehouseAgreementMapper.selectTWarehouseAgreementById(fId);
        TWarehouseAgreementitems tWarehouseAgreementitems = new TWarehouseAgreementitems();
        tWarehouseAgreementitems.setfPid(tWarehouseAgreement.getfId());
        List<TWarehouseAgreementitems> tWarehouseAgreementitemss = tWarehouseAgreementitemsMapper.selectTWarehouseAgreementitemsList(tWarehouseAgreementitems);
        if (StringUtils.isNull(tWarehouseAgreement)) {
            return AjaxResult.success("0");
        } else if (StringUtils.isNotNull(tWarehouseAgreement) && StringUtils.isEmpty(tWarehouseAgreementitemss)) {
            return AjaxResult.success("1");
        } else {
            return AjaxResult.success("2");
        }
    }


    /**
     * 计算存储费用
     *
     * @param fCorpid      出库客户Id
     * @param fGoodsid     物资类型Id
     * @param days         时长天数(需要计算仓储费的时长)
     * @param feeUnitid    计价单位
     * @param itemNums     数量
     * @param earlySumDays 已经计算过仓储费的天数（假设传参80，则阶梯计价时按照80往后的计算）  21.01.14 曹志刚要求新增
     * @return
     * @author shanxin
     */
    public Map<String, Object> getCarryingCost(Long fCorpid,
                                               Long fGoodsid,
                                               Long days,
                                               Long feeUnitid,
                                               BigDecimal itemNums,
                                               Long earlySumDays) {
        Map<String, Object> map = new HashMap<>();
        if (null == fCorpid ||
                null == fGoodsid ||
                null == days ||
                null == feeUnitid ||
                null == itemNums ||
                null == earlySumDays) {
            return null;
        }
        List<TWarehouseAgreementitems> itemList =
                this.tWarehouseAgreementitemsMapper.getItemsBytWarehouseAgreementMsg(fCorpid, fGoodsid, feeUnitid);

        if (CollUtil.isEmpty(itemList)) {
            return null;
        }
        BigDecimal money = new BigDecimal(0);
        Long dayLength = 0L;
        Long feeId = 0L;

        String remark = "";
        for (TWarehouseAgreementitems tWarehouseAgreementitems : itemList) {
            if (days < 1) break;
            if (earlySumDays >= tWarehouseAgreementitems.getfEndays())
                continue; //将已算账的天数 与 计费规则的 最后一天作比较如果 已算10天 > 规则结束  不算帐

            dayLength = tWarehouseAgreementitems.getfEndays() - tWarehouseAgreementitems.getfFromdays() + 1L; //阶梯中的结束-开始日期
            String information = "";

            if (days >= dayLength) {
                feeId = tWarehouseAgreementitems.getfFeeid();
                BigDecimal calculate = this.getCalculate(itemNums, tWarehouseAgreementitems.getfPrice(), dayLength);
                money = money.add(calculate);
                days = days - dayLength;
                information = dayLength + "天*" + tWarehouseAgreementitems.getfPrice() + "元*" + itemNums + " = " + calculate + "元";
                if (StringUtils.isEmpty(remark)) {
                    remark = information;
                } else {
                    remark = remark + "," + information;
                }
            } else {
                feeId = tWarehouseAgreementitems.getfFeeid();
                BigDecimal calculate = this.getCalculate(itemNums, tWarehouseAgreementitems.getfPrice(), days);
                money = money.add(calculate);
//                long day = days - tWarehouseAgreementitems.getfFromdays();
                information = days + "天*" + tWarehouseAgreementitems.getfPrice() + "元*" + itemNums + " = " + calculate + "元";
                if (StringUtils.isEmpty(remark)) {
                    remark = information;
                } else {
                    remark = remark + "," + information;
                }
                break;
            }
        }
        map.put("amt", money);
        map.put("feeId", feeId);
        map.put("remark", remark);
        return map;
    }


    /**
     * 数量 * 单价 * 天数
     *
     * @param itemNumsBig 数量
     * @param unitPrice   单价
     * @param dateLength  天数
     * @return
     */
    public BigDecimal getCalculate(BigDecimal itemNumsBig, BigDecimal unitPrice, Long dateLength) {
        BigDecimal money = new BigDecimal(0);
        BigDecimal bigDaysBig = new BigDecimal(dateLength);
        money = itemNumsBig.multiply(unitPrice).multiply(bigDaysBig);
        return money;
    }


}
