package com.sifang.modules.supply.order.service;


import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.plugin.activerecord.Record;
import com.q7link.openapi.model.ApiParams;
import com.q7link.openapi.model.ApiResponse;
import com.q7link.openapi.model.PostAddAutoSubmitRequest;
import com.q7link.openapi.model.PostAddAutoSubmitResult;
import com.sifang.modules.account.dao.TraderAccountDao;
import com.sifang.modules.customer.dao.CustomerEntryDao;
import com.sifang.modules.customer.entity.CustomerEntry;
import com.sifang.modules.flowable.service.ProcessFlowableService;
import com.sifang.modules.flowable.utils.FormUtils;
import com.sifang.modules.flowpath.constant.BondApplyConstant;
import com.sifang.modules.flowpath.dao.BondApplyDao;
import com.sifang.modules.flowpath.vo.UserApplyVo;
import com.sifang.modules.q7link.utils.OpenapiTemplate;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmTrader;
import com.sifang.modules.sunshine.SystemSetting.service.TraderService;
import com.sifang.modules.sunshine.SystemSetting.utils.Result;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.supply.order.constant.DeliverOrderConstants;
import com.sifang.modules.supply.order.dao.MaterialDeliverDetailDao;
import com.sifang.modules.supply.order.dao.MaterialDeliverOrderMsgDao;
import com.sifang.modules.supply.order.dao.SupplyOrderAuditDao;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialDeliverOrder;
import com.sifang.modules.supply.order.entity.CrmSupplyMaterialDeliverOrderDetail;
import com.sifang.modules.supply.order.request.OrderApproveReq;
import com.sifang.modules.supply.order.request.UpdateSupplyOrderDetailReq;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.util.LayuiPage;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.rmi.CORBA.Util;
import java.math.BigDecimal;
import java.util.*;

import static com.sifang.modules.q7link.utils.OpenapiTemplate.getSdkRequestConfig;
import static com.sifang.modules.q7link.utils.OpenapiTemplate.openapi;

@Service
public class SupplyOrderAuditService extends BaseService {


    @Autowired
    SupplyOrderAuditDao supplyOrderDao;

    @Autowired
    private MaterialDeliverDetailDao materialDeliverDetailDao;

    @Autowired
    private ProcessFlowableService flowableService;

    @Autowired
    private MaterialDeliverOrderMsgDao deliverOrderMsgDao;

    @Autowired
    TaskService taskService;

    @Autowired
    TraderAccountDao accountDao;

    @Autowired
    private BondApplyDao bondApplyDao;

    @Autowired
    private TraderService traderService;

    @Autowired
    private CustomerEntryDao customerEntryDao;

    @Resource
    private CrmSupplyMaterialDeliverOrderService crmSupplyMaterialDeliverOrderService;

    public void listPageDate(LayuiPage page, Map<String, String> map,String formKey){
        User user = UserUtils.getUser();
        List<Record> list=supplyOrderDao.listData(page,map,user,formKey);
        //判断是否有审批权限
        String roleIds=user.getRoleIds();    //用户角色
        if(StringUtil.isNotBlank(roleIds) && list.size()>0){
            for(Record r:list){
                if(DeliverOrderConstants.STATUS_ALLOCATION_REJECT.equals(r.getStr("orderStatus"))){
                    r.set("status",BondApplyConstant.APPLYSTATUS_ZERO);
                }else {
                    r.set("status", r.getStr("order_examine_status"));
                }
            }
         /*   bondApplyDao.checkPermission(list,roleIds,"", FormUtils.SUPPLY_ORDER_APPLICATION);*/
        }
        Long count=supplyOrderDao.listCount(map,user,formKey);
        page.setData(list);
        page.setCount(count);
    }

    //订单详情
    public Record orderDetail(String id){
        Record record=supplyOrderDao.orderDetail(id);
        return record;
    }

    public List<Record> getOrderDetail(String id,String type){
        return supplyOrderDao.getOrderDetail(id,type);
    }

    //物料信息
    public List<Record> getOrderMaterials(String id){
       List<Record> mates=supplyOrderDao.getOrderMaterials(id);
       BigDecimal total=new BigDecimal(0.00);
        for (Record mate : mates) {
            BigDecimal salesPrice=mate.get("sales_price");
            BigDecimal outAmount=mate.get("out_amount");
            if(outAmount!=null&&outAmount.compareTo(BigDecimal.valueOf(0))!=0){
                mate.set("total_price",salesPrice.multiply(outAmount).setScale(2, BigDecimal.ROUND_HALF_UP));
            }else{
                mate.set("total_price","0.00");
            }
            total=total.add(salesPrice.multiply(outAmount));
        }
        if(mates.size()>0){
            mates.get(0).set("all_price",total.setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        return mates;
    }

    //库存信息
    public List<Record> getPlateMaterialsStock(String type ,String spec,String from,String traderId, String qqProjectCode){
        CrmTrader trader = traderService.getById(traderId);
        List<Record> List=supplyOrderDao.getPlateMaterialsStock(type,spec,from,traderId,qqProjectCode);
        return List;
    }

    //根据物料类型 和 物料规格 获取平台对应物料库存
    public List<Record> getBySpecVsType(String type ,String spec){
        List<Record> list=supplyOrderDao.getBySpecVsType(type,spec);
        return list;
    }

    public List<Record> getPlateMaterialsStock2(String type ,String spec,String traderId,String id, String qqProjectCode){
        CrmTrader trader = traderService.getById(traderId);
        CrmSupplyMaterialDeliverOrder order=supplyOrderDao.get(id);
        String province = trader.getProvince();
        String city = trader.getCity();
        if(StringUtil.isNotBlank(order.getProvince())){
            province = province+","+order.getProvince();
        }
      /*  if(StringUtil.isNotBlank(order.getCity())){
            city = city+","+order.getCity();
        }*/

        List<Record> List=supplyOrderDao.getPlateMaterialsStock2(type,spec,province,city,qqProjectCode);
        return List;
    }

    /**
     *  审批通过时，校验该代理商的标准授信额度是否大于当前物料总额，不大于则无法通过；
     */
    @Transactional(rollbackFor = Exception.class)
    public void supplyOrderApprove(OrderApproveReq approveReq){
        logger.info(">>>>>>>>>>>supplyOrderApprove  id:{},from:{}",approveReq.getId(),approveReq.getPageFrom());
        User user = UserUtils.getUser();

        CrmSupplyMaterialDeliverOrder order=supplyOrderDao.get(approveReq.getId());
        logger.info(">>>>>>>>>>>>>>>>supplyOrderApprove   taskName:{}>",order.getTaskName());

        List<CrmSupplyMaterialDeliverOrderDetail> newItems=approveReq.getMaterials(); //页面保存的
        int i=1;
        BigDecimal predictAmount=BigDecimal.ZERO; //预估授信额度
        for(CrmSupplyMaterialDeliverOrderDetail newSet:newItems){
            String materialType=newSet.getMaterialType();
            if(2==approveReq.getSort()){
                if(StringUtil.isBlank(newSet.getMaterialId())){
                    throw new RuntimeException("类型是："+materialType+",规格是："+newSet.getMaterialSpec()+"，没有匹配物料!");
                }

                if(newSet.getSalesPrice()==null){
                    throw new RuntimeException("类型是："+materialType+",规格是："+newSet.getMaterialSpec()+"，没有物料零售价!");
                }

                if(newSet.getOutAmount()==null && "0".equals(newSet.getStatus())){
                    throw new RuntimeException("类型是："+materialType+",规格是："+newSet.getMaterialSpec()+"，没有发货数量!");
                }
                //进入待分配状态 重新计算订单授信额度
                predictAmount=predictAmount.add(newSet.getSalesPrice().multiply(newSet.getOutAmount()));
            }

            if (newSet.getPurchasePrice() == null) {
                newSet.setPurchasePrice(BigDecimal.ZERO);
            }
            newSet.setStatus("0");
            newSet.setSort(i);
            newSet.setMainId(order.getId());
            i++;
        }
        //进入待分配状态 重新计算订单授信额度
        if(2==approveReq.getSort()){
            order.setPredictAmount(predictAmount);
        }
        Date date=new Date();
        //删除原来的物料
        supplyOrderDao.deleteDetails(order.getId());
        materialDeliverDetailDao.save(newItems);
        String formKey = FormUtils.SUPPLY_ORDER_APPLICATION;
        String processName="订单申请";
        if("5".equals(order.getType())){
            formKey = FormUtils.BRACKET_ORDER_APPLY;
            processName="现金下单申请";
        }
        String remark="";
        if("edit".equals(approveReq.getPageFrom()) && DeliverOrderConstants.STATUS_ALLOCATION_REJECT.equals(order.getStatus())){  //分配打回，编辑过来的，那么要重新启动流程审批
              //提交流程
            Record rd = FormUtils.getdefLatest(formKey);
            if(rd == null){
                throw  new RuntimeException("流程未定义，不可发布申请");
            }
            //启动流程
            String processInstanceId=flowableService.startProcessFlowable(user,order.getId(),rd, formKey,date,user.getUserName(),approveReq.getContent(),processName,order.getTraderId());
            order.setProcessInstanceId(processInstanceId);
            order.setProcessDefId(rd.getStr("id"));

            String taskName=FormUtils.getOneStepTaskName(rd.getStr("id"));
            order.setTaskName(taskName);
            order.setOperateUserIds(user.getId()+","+rd.getStr("oneAuditUseId"));

            order.setStatus(DeliverOrderConstants.STATUS_WAIT_AUDIT);
            remark="分配打回，编辑提交。";
        }else{
            //审批通过
           /* flowableService.approveTask(approveReq.getTaskId(),approveReq.getContent(),order.getId(),user,date,FormUtils.SUPPLY_ORDER_APPLICATION,order.getProcessDefId());
            Task vacationApply = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).singleResult();
            if(vacationApply!=null){
                order.setTaskName(vacationApply.getName());
                order.setTaskId(vacationApply.getId());
            }*/
            Task task = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).taskAssignee(user.getId()).singleResult();
            flowableService.approveTask2(task,approveReq.getContent(),order.getId(),user, formKey);
            order.setAuditRemark(approveReq.getContent());
            remark = "同意";
            if (StringUtil.isNotBlank(approveReq.getContent())) {
                remark += "," + approveReq.getContent();
            }
        }
        order.setOperateUserIds(order.getOperateUserIds()+","+user.getId());
       /* order.setOrderExamineStatus(BondApplyConstant.APPLYSTATUS_ONE);*/
        supplyOrderDao.save(order);
        //保存过程信息
        deliverOrderMsgDao.saveOrderOpe(order.getId(),remark,user.getUserName(),user.getId(),DeliverOrderConstants.OPT_AUDIT_APPROVE);

    }







    //审批驳回
    @Transactional(rollbackFor = Exception.class)
    public void backSupplyOrder(UserApplyVo userApplyVo){
        logger.info(">>>>>>>>>>>>>backSupplyOrder  id:{},task:{}",userApplyVo.getId(),userApplyVo.getTaskId());
        User user = UserUtils.getUser();
        CrmSupplyMaterialDeliverOrder order=supplyOrderDao.get(userApplyVo.getId());
        logger.info(">>>>>>>>>>>>>>>>backSupplyOrder   taskName:{}>",order.getTaskName());
        order.setOrderExamineStatus(BondApplyConstant.APPLYSTATUS_TWO);
        String remark=order.getTaskName()+"，驳回。";
        Integer sort=FormUtils.getSortByDefIdName(order.getProcessDefId(),order.getTaskName());
        String formKey = FormUtils.SUPPLY_ORDER_APPLICATION;
        if("5".equals(order.getType())){
            formKey = FormUtils.BRACKET_ORDER_APPLY;
        }
       /* if(sort!=null && 1==sort && !"2".equals(order.getType())){  //第一级审批不通过等同于直接删除订单；
         order.setStatus(DeliverOrderConstants.STATUS_DELETED);
         remark+=" 删除订单。";
         if("1".equals(order.getType()) && StringUtil.isNotBlank(order.getApplyOrderId())){
             //释放订单关联的电站
             for(String id:order.getApplyOrderId().split(",")){
                 CustomerEntry customerEntry = customerEntryDao.get(id);
                 customerEntry.setAcceptFlag("0");
                 customerEntryDao.save(customerEntry);
             }
         }
         //删除流程
         flowableService.deleteApplication(order.getId(),order.getProcessInstanceId(),user.getUserName(),"2",formKey);
        }else{

            *//*flowableService.rejectTask(userApplyVo.getTaskId(),userApplyVo.getContent(),userApplyVo.getId(),user,FormUtils.SUPPLY_ORDER_APPLICATION);
            Task vacationApply = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).singleResult();
            if(vacationApply!=null){
                order.setTaskName(vacationApply.getName());
                order.setTaskId(vacationApply.getId());
            }*//*


        }*/
        order.setAuditRemark(userApplyVo.getContent());
        supplyOrderDao.save(order);
        //保存过程信息
        deliverOrderMsgDao.saveOrderOpe(order.getId(),remark,user.getUserName(),user.getId(),DeliverOrderConstants.OPT_AUDIT_FAIL);
        Task task = taskService.createTaskQuery().processInstanceId(order.getProcessInstanceId()).taskAssignee(user.getId()).singleResult();
        flowableService.rejectTask2(task,userApplyVo.getContent(),order.getId(),user,formKey,order.getCreateBy());
    }


    @Transactional(rollbackFor = Exception.class)
    public void deleteOrder(String orderId,String formKey){
        logger.info(">>>>>>>>>>>>>deleteOrder  id:{}",orderId);
        CrmSupplyMaterialDeliverOrder order=supplyOrderDao.get(orderId);
        order.setStatus(DeliverOrderConstants.STATUS_DELETED);

        User user = UserUtils.getUser();
        //删除流程
        if(StringUtil.isNotBlank(order.getProcessInstanceId())){
            flowableService.deleteApplication(order.getId(),order.getProcessInstanceId(),user.getUserName(),"2",formKey);
        }
        supplyOrderDao.save(order);
        //保存过程信息
        deliverOrderMsgDao.saveOrderOpe(order.getId(),"删除订单",user.getUserName(),user.getId(),DeliverOrderConstants.OPT_DELETE);
        if("1".equals(order.getType()) && StringUtil.isNotBlank(order.getApplyOrderId())){
            //释放订单关联的电站
            for(String id:order.getApplyOrderId().split(",")){
                CustomerEntry customerEntry = customerEntryDao.get(id);
                customerEntry.setAcceptFlag("0");
                customerEntryDao.save(customerEntry);
            }
        }
    }
    //匹配后直接保存匹配物料信息
    @Transactional(rollbackFor = Exception.class)
    public Result updateSupplyOrderDetail(UpdateSupplyOrderDetailReq req){
        CrmSupplyMaterialDeliverOrder order=supplyOrderDao.get(req.getId());
        List<CrmSupplyMaterialDeliverOrderDetail> materials = req.getMaterials();
        int i=1;
        for(CrmSupplyMaterialDeliverOrderDetail newSet:materials){
            if (newSet.getPurchasePrice() == null) {
                newSet.setPurchasePrice(BigDecimal.ZERO);
            }
            newSet.setStatus("0");
            newSet.setSort(i);
            newSet.setMainId(order.getId());
            i++;
        }
        //删除原来的物料
        supplyOrderDao.deleteDetails(order.getId());
        materialDeliverDetailDao.save(materials);
        return Result.ok();
    }
}
