package com.engine.htsc.payment.web;

import com.alibaba.fastjson.JSONObject;
import com.engine.common.util.ParamUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.htsc.payment.enums.Sequences;
import com.engine.htsc.payment.pojo.BudgetReqDto;
import com.engine.htsc.payment.service.PaymentService;
import com.engine.htsc.payment.service.impl.HeadPaymentBudgetCommand;
import com.engine.htsc.payment.service.impl.PaymentServiceImpl;
import com.engine.htsc.payment.util.CoWfUtil;
import com.engine.htsc.trip.util.AjaxResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author K1810012
 * 通用付款
 */
public class GeneralPaymentAction {

  public GeneralPaymentAction() {
  }

  /**
   * 预算service
   *
   * @return BudgetService
   */
  private PaymentService getServices() {
    return ServiceUtil.getService(PaymentServiceImpl.class);
  }

  @GET
  @Path("/getWorkflowInfos")
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<Map<String, String>> getWorkflowInfos(@QueryParam("requestmark") String lcbh) {
    try {
      Map<String, String> resp = new HashMap<>();
      Validate.notEmpty(lcbh, "流程编号为空");
      String sql = "SELECT REQUESTID,WORKFLOWID,REQUESTNAME FROM workflow_requestbase WHERE requestmark=?";
      RecordSet rs = new RecordSet();
      rs.executeQuery(sql, lcbh);
      if (rs.next()) {
        resp.put("REQUESTID", Util.null2String(rs.getString("REQUESTID")));
        resp.put("WORKFLOWID", Util.null2String(rs.getString("WORKFLOWID")));
        resp.put("REQUESTNAME", Util.null2String(rs.getString("REQUESTNAME")));
      }
      if (resp.isEmpty()) {
        return AjaxResult.failed("单号不存在或已删除！");
      }
      return AjaxResult.ok(resp);
    } catch (Exception e) {
      return AjaxResult.error("获取流程信息,发生异常:" + e.getMessage());
    }
  }

  @GET
  @Path("/check/requestMark")
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<String> checkRequestMark(@QueryParam("lcbh") String lcbh,
                                              @QueryParam("type") String type,
                                              @QueryParam("unNumber") String unNumber) {
    try {
      //检查流程编号唯一性
      String newRequestMark = this.getServices().checkRequestMark(lcbh, type, unNumber);
      return AjaxResult.ok(newRequestMark);
    } catch (Exception e) {
      return AjaxResult.error("生成流程编号失败,发生异常:" + e.getMessage());
    }
  }

  @GET
  @Path("/create/requestMark")
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<String> createReqMark(@QueryParam("unNumber") String unNumber,
                                          @QueryParam("type") String type) {
    try {
      Sequences sequences = null;
      if ("zb".equalsIgnoreCase(type)) {
        sequences = Sequences.NET_REI_WORKFLOW_SEQ_ZB;
      } else if ("fz".equalsIgnoreCase(type)) {
        sequences = Sequences.NET_REI_WORKFLOW_SEQ_FZ;
      } else if ("zgs".equalsIgnoreCase(type)) {
        sequences = Sequences.NET_REI_WORKFLOW_SEQ_ZGS;
      } else {
        throw new Exception("流程类型没有匹配");
      }
      String requestMarkByUnNumber = CoWfUtil.getRequestMarkByUnNumber(unNumber, sequences);
      return AjaxResult.ok(requestMarkByUnNumber);
    } catch (Exception e) {
      return AjaxResult.error("生成流程编号失败,发生异常:" + e.getMessage());
    }
  }

  /**
   * @param bgReq
   * @return
   */
  @POST
  @Path("/travel/controlBudget")
  @Consumes(MediaType.APPLICATION_JSON)
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<Map<String, String>> travelControlBudget(BudgetReqDto bgReq) {
    try {
      Map<String, String> resp = this.getServices().controlBudget(bgReq);
      return AjaxResult.ok(resp);
    } catch (Exception e) {
      return AjaxResult.error("总部差旅报销超预算控制,发生异常:" + e.getMessage());
    }
  }


  /**
   * 流程终止取消预算
   *
   * @return msg
   */
  @POST
  @Path("/doBudget/terminate")
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<String> wfCancelBudgetWhenTermination(@Context HttpServletRequest request) {
    try {
      Map<String, Object> reqParams = ParamUtil.request2Map(request);
      String requestNo = (String) reqParams.getOrDefault("requestNo", "");
      HeadPaymentBudgetCommand command = new HeadPaymentBudgetCommand();
      String reject = command.reject(requestNo);
      return AjaxResult.ok(reject); //f1001成功
    } catch (Exception e) {
      return AjaxResult.error("总部差旅报销超预算控制,发生异常:" + e.getMessage());
    }
  }

  /**
   * 出纳付款,付款明细导出状态修改
   *
   * @return msg
   */
  @POST
  @Path("/doExport")
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<String> doExport(@Context HttpServletRequest request) {
    try {
      Map<String, Object> request2Map = ParamUtil.request2Map(request);
      String id = (String) request2Map.getOrDefault("id", "");
      String type = (String) request2Map.getOrDefault("type", "");
      String msg = getServices().doExport(id, type);
      return AjaxResult.ok(msg);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("catch exception:" + e);
    }
  }

  /**
   * 出纳付款,点击手动付款按钮更新状态
   *
   * @return ContractInfoVo
   */
  @GET
  @Path("/doManualPayment")
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<String> doPaymentByManual(@QueryParam("id") String id) {
    try {
      String resultStr = getServices().updateManualPaymentStatus(id);
      return AjaxResult.ok(resultStr);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("catch exception:" + e);
    }
  }


  /**
   * 通用付款流程，对应流程生成流程编号
   * 调用时确保为创建 isCreate=1
   *
   * @return ContractInfoVo
   */
  @GET
  @Path("/generator/requestMark")
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<String> getGeneratedRequestMark(@Context HttpServletRequest request) {
    try {
      String mark = getServices().generateRequestMark(request);
      return AjaxResult.ok(mark);
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("catch exception:" + e);
    }
  }

  /**
   * 通用付款流程，核算接口调用
   *
   * @return 核算接口返回值
   */
  @POST
  @Path("/cost/account")
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<Map<String, String>> doCostAccounting(@Context HttpServletRequest request) {
    try {
      String res = "";
      Map<String, Object> request2Map = ParamUtil.request2Map(request);
      String ids = Util.null2String(request2Map.get("ids")); //勾选核算id
      if (StringUtils.isNotBlank(ids)) {
        List<Map<String, String>> maps = getServices().doCostAccount(ids);
        return AjaxResult.ok(mergeValue(maps), "核算接口返回成功");
      } else {
        throw new Exception("请勾选相关流程进行核算");
      }
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("catch exception: " + e);
    }
  }

  /**
   * 通用付款流程，付款接口调用 付款=预算+核算
   *
   * @return 付款接口返回值
   */
  @POST
  @Path("/doPayment")
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<Map<String, String>> doPayment(@Context HttpServletRequest request) {
    try {
      List<Map<String, String>> res = new ArrayList<>();
      Map<String, Object> request2Map = ParamUtil.request2Map(request);
      String ids = Util.null2String(request2Map.get("ids")); //勾选核算id
      if (StringUtils.isNotBlank(ids)) {
        res = getServices().doPayment(ids);
      } else {
        throw new Exception("请勾选相关流程进行核算");
      }
      return AjaxResult.ok(mergeValue(res), "付款接口返回成功");
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("catch exception: " + e);
    }
  }

  @POST
  @Path("/doBudget")
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<Map<String, String>> doBudget(@Context HttpServletRequest request) {
    try {
      Map<String, Object> param = ParamUtil.request2Map(request);
      String ids = Util.null2String(param.getOrDefault("ids", ""));
      String discard = Util.null2String(param.getOrDefault("discard", ""));
      List<Map<String, String>> resp = new ArrayList<>();
      Map<String, String> mp = this.getServices().doBudget(ids, discard);
      resp.add(mp);
      //汇总list
      return AjaxResult.ok(mergeValue(resp));
    } catch (Exception e) {
      return AjaxResult.error("发生异常,请联系管理员,异常信息" + e.getMessage() + "");
    }
  }

  /**
   * 通用付款流程功能
   * 判断部门等级,
   * =1, 取当前部门负责人
   * =2, 取上级部门负责人
   *
   * @return 负责人 浏览按钮
   */
  @GET
  @Path("/check/deptLevel/{id}")
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  @Produces(MediaType.APPLICATION_JSON)
  public AjaxResult<Map<String, Object>> checkDeptLevel(@PathParam("id") String id) {
    Map<String, Object> res = new HashMap<>();
    try {
      ResourceComInfo rc = new ResourceComInfo();
      RecordSet rs = new RecordSet();
      String deptLevel = "";
      String deptDirectors = "";
      rs.executeQuery("select DEPTDEPTH,DEPTDIRECTORS\n" +
              " from hrmdepartmentdefined m\n" +
              " where DEPTID = " + id);
      if (rs.next()) {
        deptLevel = Util.null2String(rs.getString("DEPTDEPTH"));
        deptDirectors = Util.null2String(rs.getString("DEPTDIRECTORS"));
      }
      List<Map<String, String>> specialObj = new ArrayList<>();
      if ("1".equals(deptLevel)) {
        //当前部门等级为1级,直接取 deptDirectors
        res.put("value", deptDirectors);
        String[] directors = deptDirectors.split(",");
        for (String director : directors) {
          Map<String, String> map = new HashMap<>();
          map.put("id", director);
          map.put("name", rc.getLastname(director));
          specialObj.add(map);
        }
        res.put("specialobj", specialObj);
      } else if ("2".equals(deptLevel)) {
        //当前部门等级为2级,取上级 deptDirectors
        rs.executeQuery("select DEPTDIRECTORS\n" +
                " from hrmdepartmentdefined m\n" +
                " where m.deptid in (select t.SUPDEPID\n" +
                " from hrmdepartment t\n" +
                " where t.id = " + id + ")");
        if (rs.next()) {
          deptDirectors = Util.null2String(rs.getString("DEPTDIRECTORS"));
        }
        res.put("value", deptDirectors);
        String[] directors = deptDirectors.split(",");
        for (String director : directors) {
          Map<String, String> map = new HashMap<>();
          map.put("id", director);
          map.put("name", rc.getLastname(director));
          specialObj.add(map);
        }
        res.put("specialobj", specialObj);

      } else {
        res.put("value", "");
        res.put("specialobj", specialObj);
      }
      return AjaxResult.ok(res, "判断部门等级,联动负责人");
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("catch exception: " + e);
    }
  }

  public static Map<String, String> mergeValue(List<Map<String, String>> sources) {
    return sources.stream()
            .flatMap(m -> m.entrySet().stream())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> String.join(";", a, b)));
  }

  /*
   * 总部付款建模付款成功后同步更新流程主表中的付款状态流程
   * 目前只针对总部IT付款流程
   * */
  @POST
  @Path("/upitmainfkzt")
  public String upItMainFKZT(@Context HttpServletRequest request){
    BaseBean bb = new BaseBean();
    bb.writeLog("=================付款成功，准备同步更新主表的付款状态字段为0=============");
    Map<String,Object> result;
    Map<String,Object> paramsMap = new HashMap<>();
    paramsMap.put("ids",Util.null2String(request.getParameter("ids")));
    result = getServices().upMainFKZT(paramsMap);
    return JSONObject.toJSONString(result);
  }
}


