package com.sifang.modules.flowpath.web;

import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.customer.utils.EmployeRoleUtils;
import com.sifang.modules.flowable.service.ProcessFlowableService;
import com.sifang.modules.flowable.utils.FormUtils;
import com.sifang.modules.flowpath.entity.ExamineInfo;
import com.sifang.modules.flowpath.service.CashOutApplyService;
import com.sifang.modules.flowpath.service.DistributionGoodsApplyService;
import com.sifang.modules.flowpath.service.ExamineInfoService;
import com.sifang.modules.flowpath.vo.CashOutVo;
import com.sifang.modules.flowpath.vo.UserApplyVo;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmTrader;
import com.sifang.modules.sunshine.SystemSetting.service.TraderService;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.Result;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.common.utils.Arith;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.web.BaseExceptionController;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Controller
@RequestMapping(value = "${adminPath}/apply/outCash")
public class CashOutApplyController extends BaseExceptionController {

    Logger logger= LoggerFactory.getLogger(getClass());

    @Autowired
    private CashOutApplyService cashOutApplyService;

    @Autowired
    private DistributionGoodsApplyService distributionGoodsApplyService;

    @Autowired
    private ExamineInfoService examineInfoService;

    @Autowired
    TraderService traderService;

    @Autowired
    private ProcessFlowableService flowableService;


    //页面
    @RequestMapping(value = "applyPage")
    public String warrantyListPage(Model model) {
        User user = UserUtils.getUser();
        model.addAttribute("userId",user.getId());
        model.addAttribute("formId", FormUtils.CASH_OUT_APPLY);
        model.addAttribute("userType",user.getUserType());
        return "modules/flowpath/cashOutApplyPage";
    }

    @ResponseBody
    @RequestMapping(value = "cashOutApplyList")
    public String cashOutApplyList(HttpServletRequest request){
        Map<String, String> map = getParams(request);
        LayuiPage page = new LayuiPage(request);
        User user = UserUtils.getUser();
        String traderId="";
        if (User.USER_TYPE_KJ.equals(user.getUserType()) || User.USER_TYPE_ADVISOR.equals(user.getUserType())) {  //代理商
            traderId = CrmUtils.getUserRelId(user);
        }else if (User.USER_TYPE_WXG.equals(user.getUserType())) {
            //平台人员
            EmployeRoleUtils.getUserDataAuthority(user.getId(),map);
        }
        map.put("traderId",traderId);
        cashOutApplyService.cashOutApplyList(page, map);
        return page.renderJson();
    }

    /**
     * 新增申请页面
     * 请款申请修改为从结算明细勾选数据提交，不走提交申请按钮输入金额，系统会自动扣减电站扣款的金额，并且需要校验体现总额不能超过总结算金额。能准确知道具体是哪个电站扣减结算。固定每月5/15/25号才可请款操作。
     */
    @RequestMapping(value = "addCashOutApplyPage")
    public String addCashOutApplyPage(Model model,HttpServletRequest request,BigDecimal outAmount){
        List<Record> list=distributionGoodsApplyService.getTrader();
        model.addAttribute("traders",list);
        User user = UserUtils.getUser();
        String traderId=request.getParameter("traderId");
        CrmTrader trader=null;
        String settleId=request.getParameter("settleId");
        String objType=request.getParameter("objType");
        logger.info("addCashOutApplyPage settleId:{},outAmount:{},objType:{} ",settleId,outAmount,objType);
        //统计一下 金额
        BigDecimal staticAmount=cashOutApplyService.getStaticSettleAmount(settleId);
        if(staticAmount.compareTo(outAmount)!=0){
            model.addAttribute("error","金额统计有误!");
            model.addAttribute("code",205);
            return "modules/flowpath/addCashOutApplyPage";
        }
        //获取结算明细
        List<Record> settleDetails= cashOutApplyService.getSettleDetails(settleId);
        model.addAttribute("settleDetails",settleDetails);
       /* //判断一下
        if(User.USER_TYPE_ADVISOR.equals(user.getUserType())){
            traderId = CrmUtils.getUserRelId(user);
            trader=traderService.getById(traderId);
        }else if(User.USER_TYPE_KJ.equals(user.getUserType())){
             trader = traderService.getTraderBuserId(user.getId());
            traderId=trader.getId();
        }*/
        trader=traderService.getById(traderId);
        model.addAttribute("trader",trader);
        model.addAttribute("traderId",traderId);
        model.addAttribute("settleId",settleId);
        model.addAttribute("objType",objType);
        Long count= cashOutApplyService.countSettleNoCash(objType, settleId,traderId);
        model.addAttribute("code",200);
        if(count>0){
           model.addAttribute("error","请先请款整改数据的金额!");
           model.addAttribute("code",205);
            return "modules/flowpath/addCashOutApplyPage";
        }
        if(outAmount.compareTo(BigDecimal.ZERO)<=0){
            model.addAttribute("error","请款金额必须大于0!");
            model.addAttribute("code",205);
            return "modules/flowpath/addCashOutApplyPage";
        }
        if("0".equals(objType) && outAmount.compareTo(BigDecimal.ZERO)>0){
            //根据结算明细判断，电站对应的有没有扣款金额，扣款金额是多少,以及扣款申请的id
            Record noDeductApply=cashOutApplyService.getNoDeduct(settleId);
            BigDecimal noDeduct=noDeductApply.getBigDecimal("reduceAmount");  //需要扣减的金额
            outAmount=outAmount.subtract(noDeduct);
            /*if(outAmount.compareTo(BigDecimal.ZERO)<=0){
                throw new BusinessException("结算金额抵扣扣减金额后，还有"+outAmount+",不足以请款!");
            }*/
            String adjustmentApplyIds=noDeductApply.getStr("adjustmentApplyIds");
            model.addAttribute("adjustmentApplyIds",adjustmentApplyIds);
        }
        logger.info(">>>>>>>>>>>addCashOutApplyPage  traderId:{},outAmount:{}",traderId,outAmount);
        Record  caseAccount=cashOutApplyService.getTraderCanOutCash(traderId);
        BigDecimal bzjAmount = caseAccount.getBigDecimal("bzj_amount");
        if (caseAccount.getBigDecimal("yk_bzj_amount") != null) {
            bzjAmount =  Arith.add(bzjAmount, caseAccount.getBigDecimal("yk_bzj_amount"))
                    .setScale(2, RoundingMode.HALF_UP);
            caseAccount.set("bzj_amount", bzjAmount);
        }
        BigDecimal amount=BigDecimal.ZERO;
        if(caseAccount!=null){
            if("1".equals(objType)){
                amount=caseAccount.getBigDecimal("qa_amount_usable");
            }else{
                amount=caseAccount.getBigDecimal("settle_amount");
            }
            logger.info(">>>>>>>>>>>addCashOutApplyPage  caseAccount:{},{}",caseAccount.getBigDecimal("qa_amount_usable"),caseAccount.getBigDecimal("settle_amount"));
        }
        if(outAmount.compareTo(amount)>0){
            model.addAttribute("error","账户金额不足，不能请款！");
            model.addAttribute("code",205);
            return "modules/flowpath/addCashOutApplyPage";
        }
        model.addAttribute("outAmount",outAmount);
        model.addAttribute("caseAccount",caseAccount);
        model.addAttribute("imgsCount", 0);
        //电站结算时，添加保证金扣除  结算费扣除保证金：结算费*20%，大于（保证金额度-已实缴保证金）时，按照（保证金额度-已实缴保证金）扣除
        if("0".equals(objType)){ //待结算账户
            //抵扣的保证金
            BigDecimal offsetBondAmount=outAmount.multiply(new BigDecimal("0.2")).setScale(2, RoundingMode.HALF_UP);   //抵消保证金的金额
            BigDecimal differenceAmount=caseAccount.getBigDecimal("bond_amount_limit").subtract(bzjAmount);
            if(offsetBondAmount.compareTo(differenceAmount)>0){
                offsetBondAmount=differenceAmount;
            }
            model.addAttribute("offsetBondAmount",offsetBondAmount);
            model.addAttribute("payAmount",outAmount.subtract(offsetBondAmount));

        }
        return "modules/flowpath/addCashOutApplyPage";
    }

    //获取代理商的可请款金额
    @ResponseBody
    @RequestMapping(value = "getTraderCanOutCash")
    public Result getTraderCanOutCash(String traderId){
        return Result.success(cashOutApplyService.getTraderCanOutCash(traderId));
    }

    //新建/修改申请

    /**
     *请款申请修改为从结算明细勾选数据提交，不走提交申请按钮输入金额，系统会自动扣减电站扣款的金额，并且需要校验体现总额不能超过总结算金额。
     * 能准确知道具体是哪个电站扣减结算。固定每月5/15/25号才可请款操作。
     */
    @ResponseBody
    @RequestMapping(value = "saveCashOutApply")
    public Result saveCashOutApply(@RequestBody CashOutVo vo){
        try{
            cashOutApplyService.saveCashOutApply(vo);
            return Result.ok();
        }catch (RuntimeException r){
            r.printStackTrace();
            return Result.fail(r.getMessage());
        }catch (Exception e){
            e.printStackTrace();
            logger.error(">>>>>>>>>>>saveCashOutApply e:{}",e);
        }
        return Result.fail("保存失败");
    }

    //编辑页面
    @RequestMapping(value = "editCashOutApplyPage")
    public String editCashOutApplyPage(String id,Model model){
        Record apply=cashOutApplyService.getDetailById(id);
        model.addAttribute("apply",apply);
        Record account=cashOutApplyService.getTraderCanOutCash(apply.getStr("trader_id"));
        BigDecimal canOutCash=BigDecimal.ZERO;
        if(account!=null){
            if("0".equals(apply.getStr("obj_type"))){
                  canOutCash=account.getBigDecimal("settle_amount");
            }else{
                canOutCash=account.getBigDecimal("qa_amount_usable");
            }
        }
        model.addAttribute("caseAccount",account);
        model.addAttribute("canOutCash",canOutCash);
        List<Record> list=distributionGoodsApplyService.getTrader();
        model.addAttribute("traders",list);
        model.addAttribute("objType",apply.getStr("obj_type"));
        model.addAttribute("outAmount",apply.get("out_cash"));
        if("0".equals(apply.getStr("obj_type"))){
            model.addAttribute("offsetBondAmount",apply.getBigDecimal("offset_bond_amount"));
            model.addAttribute("payAmount",apply.getBigDecimal("pay_amount"));
        }
        int imgsCount = 0;
        if (StringUtils.isNotBlank(apply.getStr("voucher"))) {
            String[] imgArr = apply.getStr("voucher").split(",");
            imgsCount = imgArr.length;
            List<String> imglist = Arrays.asList(imgArr);
            model.addAttribute("imglist", imglist);
        }
        model.addAttribute("settleId", apply.getStr("settle_ids"));
        model.addAttribute("code",200);
        model.addAttribute("imgsCount", imgsCount);
        //获取结算明细
        List<Record> settleDetails= cashOutApplyService.getSettleDetails(apply.getStr("settle_ids"));
        model.addAttribute("settleDetails",settleDetails);
        return "modules/flowpath/addCashOutApplyPage";
    }

    // 详情/审核 页面 from = audit 那么就是审批操作  否则就是查看
    @RequestMapping(value = "cashOutDetailPage")
    public String cashOutDetailPage(String id,String from,Model model){
        model.addAttribute("from",from);
        Record apply=cashOutApplyService.getDetailById(id);
        model.addAttribute("apply",apply);
        List<ExamineInfo> infos=examineInfoService.getByApplyId(id,FormUtils.CASH_OUT_APPLY);
        model.addAttribute("infos",infos);
        int imgsCount = 0;
        if (StringUtils.isNotBlank(apply.getStr("voucher"))) {
            String[] imgArr = apply.getStr("voucher").split(",");
            imgsCount = imgArr.length;
            List<String> imglist = Arrays.asList(imgArr);
            model.addAttribute("imglist", imglist);
        }
        model.addAttribute("imgsCount", imgsCount);
        User user = UserUtils.getUser();
        model.addAttribute("userType",user.getUserType());
        if(!"audit".equals(from)){
            flowableService.readApplication(apply.getStr("process_instance_id"),FormUtils.CASH_OUT_APPLY,id,user);
        }
        //获取结算明细
        List<Record> settleDetails= cashOutApplyService.getSettleDetails(apply.getStr("settle_ids"));
        model.addAttribute("settleDetails",settleDetails);
        return "modules/flowpath/cashOutDetailPage";
    }

    //删除申请
    @ResponseBody
    @RequestMapping(value = "deleteCashOutApply")
    public Result deleteCashOutApply(HttpServletRequest request){
        String id=request.getParameter("id");
        try{
            cashOutApplyService.deleteCashOutApply(id);
            return Result.ok();
        }catch (RuntimeException r){
            r.printStackTrace();
            return Result.fail(r.getMessage());
        }catch (Exception e){
            logger.error(">>>>>>>>>>>>>>deleteCashOutApply e:{}",e);
            e.printStackTrace();
            return Result.fail("删除失败！");
        }
    }

    //审核通过
    @ResponseBody
    @RequestMapping(value = "examineCashOutApplyApprove")
    public Result examineCashOutApplyApprove(UserApplyVo userApplyVo,String voucher){
        try{
            cashOutApplyService.examineCashOutApplyApprove(userApplyVo.getId(),userApplyVo.getTaskId(),userApplyVo.getContent(),voucher);
            return Result.ok();
        }catch (Exception e){
            logger.error(">>>>>>>>>>>>>>examineCashOutApplyApprove e:{}",e);
            return Result.fail("审核失败！");
        }
    }

    //审核驳回
    @ResponseBody
    @RequestMapping(value = "rejectCashOutApplyTask")
    public Result rejectCashOutApplyTask(@Valid UserApplyVo userApplyVo){
        try{
            cashOutApplyService.rejectCashOutApplyTask(userApplyVo.getId(),userApplyVo.getTaskId(),userApplyVo.getContent());
            return Result.ok();
        }catch (Exception e){
            logger.error(">>>>>>>>>>>>>>rejectCashOutApplyTask e:{}",e);
            return Result.fail("审核失败！");
        }
    }
}
