package easydo.technology.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import easydo.technology.model.vo.GLDApproveVo;
import easydo.technology.service.FlowNoService;
import easydo.technology.service.GLDApproveService;
import easydo.technology.service.GLDCostService;
import easydo.technology.util.HttpClientUtil;
import easydo.technology.annotation.WebLog;
import easydo.technology.components.JdbcClient;
import easydo.technology.enums.ChengfaEnum;
import easydo.technology.exception.BizException;
import easydo.technology.model.Purchase;
import easydo.technology.model.PurchasePlan;
import easydo.technology.utils.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/purchasePlan")
public class PurchasePlanController {
    @Resource
    JdbcClient jdbcClient;
    @Resource
    DataSource dataSource;
    @Resource
    GLDApproveService gldApproveService;
    @Resource
    GLDCostService gldCostService;
    @Resource
    FlowNoService flowNoService;

    @WebLog
    @RequestMapping(value = "/getPage")
    public Object getPage(@RequestBody Map<String, Object> map) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            Map<String, Object> page = jdbcClient.getJdbcPage(map, PurchasePlan.class, connection);
            return new ResponseEntity<>(page, HttpStatus.OK);
        } catch (Exception e) {
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/getSelectPage")
    public Object getSelectPage(@RequestBody Map<String, Object> map)throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            int current = (int) map.get("current");
            int size = (int) map.get("size");
            map.remove("current");
            map.remove("size");
            List<PurchasePlan> planList = jdbcClient.getJdbcList(map, PurchasePlan.class, connection);

            List<Purchase> purchaseList = jdbcClient.getJdbcList(new HashMap<>(), Purchase.class, connection);
            List<String> planIdList = purchaseList.stream().map(Purchase::getPlanId).collect(Collectors.toList());

            planList = planList.stream().filter(model -> !planIdList.contains(model.getId()))
                    .collect(Collectors.toList());
            long total = planList.size();
            planList = planList.stream().skip((current - 1) * size).limit(size).collect(Collectors.toList());

            Page<PurchasePlan> planPage = new Page<>();
            planPage.setRecords(planList);
            planPage.setTotal(total);

            return new ResponseEntity<>(planPage, HttpStatus.OK);
        } catch (Exception e) {
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/getTongji")
    public Object getTongji(@RequestBody Map<String, Object> map) throws Exception{
        Map<String, Object> result = new HashMap<>();
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            String sql = "select sum(budget_amount) as budget_amount from purchase_plan";

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("createTimeBegin", map.get("yearCreateTimeBegin"));
            paramMap.put("createTimeEnd", map.get("yearCreateTimeEnd"));
            PurchasePlan purchasePlan = jdbcClient.getJdbcModelByMap(paramMap, sql, PurchasePlan.class, connection);
            result.put("yearBudgetAmount", purchasePlan.getBudgetAmount());

            paramMap.clear();
            paramMap.put("createTimeBegin", map.get("monthCreateTimeBegin"));
            paramMap.put("createTimeEnd", map.get("monthCreateTimeEnd"));
            purchasePlan = jdbcClient.getJdbcModelByMap(paramMap, sql, PurchasePlan.class, connection);
            result.put("monthBudgetAmount", purchasePlan.getBudgetAmount());

            return new ResponseEntity<>(result, HttpStatus.OK);
        } catch (Exception e) {
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/getList")
    public Object getList(@RequestBody Map<String, Object> map) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();

            List<PurchasePlan> list = jdbcClient.getJdbcList(map, PurchasePlan.class, connection);
            return new ResponseEntity<>(list, HttpStatus.OK);
        } catch (Exception e) {
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/save")
    public Object save(@RequestBody PurchasePlan model) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);

            model.setBusinessNo(flowNoService.getFlowNo(ChengfaEnum.FLOWNO_TYPE_PURCHASE_PLAN.getValue(), connection));
            jdbcClient.jdbcInsert(model, connection);

            if (StringUtil.isNotEmpty(model.getContractPlanId())) {
                gldCostService.updateState(model.getContractPlanId(), ChengfaEnum.CONTRACT_PLAN_USE_STATE_PRE_USE.getValue());
            }

            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/saveApprove")
    public Object saveApprove(@RequestBody PurchasePlan model) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);
            if (StringUtil.isEmpty(model.getId())) {
                if (StringUtil.isNotEmpty(model.getContractPlanId())) {
                    gldCostService.updateState(model.getContractPlanId(), ChengfaEnum.CONTRACT_PLAN_USE_STATE_PRE_USE.getValue());
                }
                model.setBusinessNo(flowNoService.getFlowNo(ChengfaEnum.FLOWNO_TYPE_PURCHASE_PLAN.getValue(), connection));
                jdbcClient.jdbcInsert(model, connection);
            } else {
                jdbcClient.jdbcUpdateById(model, connection);
            }
            GLDApproveVo vo = new GLDApproveVo();
            vo.setTargetId(0);
            vo.setTargetType(ChengfaEnum.BUS_APPROVE_TYPE_PURCHASE_PLAN.getValue());
            vo.setTemplateId(model.getTemplateId());
            String taskId = gldApproveService.startApprove(vo);
            vo.setTaskId(taskId);
            vo = gldApproveService.getApproveInfo(vo);

            model.setProcessInstanceId(vo.getInstanceId());
            model.setProcessState(vo.getState());
            model.setProcessTaskId(vo.getTaskId());
            model.setProcessTemplateId(vo.getTemplateId());

            model.setStatus(ChengfaEnum.PURCHASE_PALN_STATUS_APPROVE.getValue());
            jdbcClient.jdbcUpdateById(model, connection);

            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/resubmit")
    public Object resubmit(@RequestBody PurchasePlan model) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);

            GLDApproveVo vo = new GLDApproveVo();
            vo.setTargetId(0);
            vo.setTargetType(ChengfaEnum.BUS_APPROVE_TYPE_PURCHASE_PLAN.getValue());
            vo.setTemplateId(model.getTemplateId());
            vo.setTaskId(model.getProcessTaskId());
            String taskId = gldApproveService.restartApprove(vo);
            vo.setTaskId(taskId);
            vo = gldApproveService.getApproveInfo(vo);

            model.setProcessInstanceId(vo.getInstanceId());
            model.setProcessState(vo.getState());
            model.setProcessTaskId(vo.getTaskId());
            model.setProcessTemplateId(vo.getTemplateId());

            model.setStatus(ChengfaEnum.PURCHASE_PALN_STATUS_APPROVE.getValue());
            jdbcClient.jdbcUpdateById(model, connection);

            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/update")
    public Object update(@RequestBody PurchasePlan model) throws Exception {
        if (!ChengfaEnum.PURCHASE_PALN_STATUS_ACTIVE.getValue().equals(model.getStatus()) &&
                StringUtil.isNotEmpty(model.getStatus())) {
            throw new BizException("此采购计划已经发起审批，请勿变更");
        }
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);

            jdbcClient.jdbcUpdateById(model, connection);
            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/getById")
    public Object getById(@RequestBody PurchasePlan model) throws Exception {
        Map<String, Object> result = new HashMap<>();
        Connection connection = null;
        try {
            connection = dataSource.getConnection();

            model = jdbcClient.getJdbcModelById(model, connection);
            result.put("plan", model);
            return new ResponseEntity<>(result, HttpStatus.OK);
        } catch (Exception e) {
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/remove")
    public Object remove(@RequestBody PurchasePlan model) throws Exception {

        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);

            model = jdbcClient.getJdbcModelById(model, connection);
            if (StringUtil.isNotEmpty(model.getStatus())) {
                throw new BizException("此采购计划已经发起审批，请勿删除");
            }
            jdbcClient.jdbcRemoveById(model, connection);
            if (StringUtil.isNotEmpty(model.getContractPlanId())) {
                gldCostService.updateState(model.getContractPlanId(), ChengfaEnum.CONTRACT_PLAN_USE_STATE_NO_USE.getValue());
            }
            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

}
