package easydo.technology.controller;

import easydo.technology.components.JdbcClient;
import easydo.technology.enums.MESEnum;
import easydo.technology.exception.BizException;
import easydo.technology.model.Customer;
import easydo.technology.model.ProductMaterial;
import easydo.technology.model.SaleOrder;
import easydo.technology.model.SaleOrderDetail;
import easydo.technology.service.FlowNoService;
import easydo.technology.system.model.SysUser;
import easydo.technology.utils.StringUtil;
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.List;
import java.util.Map;

@RestController
@RequestMapping("/saleOrder")
public class SaleOrderController {
    @Resource
    JdbcClient jdbcClient;
    @Resource
    DataSource dataSource;
    @Resource
    FlowNoService flowNoService;

    @RequestMapping(value = "/getPage")
    public Object getPage(@RequestBody Map<String, Object> map) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            Map<String, Object> recordsPage = jdbcClient.getJdbcPage(map, SaleOrder.class, connection);
            List<SaleOrder> records = (List<SaleOrder>) recordsPage.get("records");
            for (SaleOrder model : records) {
                SaleOrderDetail detailParam = new SaleOrderDetail();
                detailParam.setOrderId(model.getId());
                List<SaleOrderDetail> childrenList = jdbcClient.getJdbcList(detailParam, connection);

                for (SaleOrderDetail detail : childrenList) {
                    ProductMaterial material = new ProductMaterial();
                    material.setCode(detail.getMaterialCode());
                    material = jdbcClient.getJdbcModel(material, connection);
                    detail.setMaterial(material);
                }
                model.setChildrenList(childrenList);

                if (StringUtil.isNotEmpty(model.getManagerId())) {
                    SysUser user = new SysUser();
                    user.setId(model.getManagerId());
                    user = jdbcClient.getJdbcModelById(user, connection);
                    model.setManagerName(user.getNickName());
                }

                Customer customer = new Customer();
                customer.setId(model.getCustomerId());
                customer = jdbcClient.getJdbcModelById(customer, connection);
                model.setCustomerName(customer.getName());

                jdbcClient.getMinioFile(model, connection);

            }

            return new ResponseEntity<>(recordsPage, HttpStatus.OK);
        } catch (Exception e) {
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @RequestMapping(value = "/save")
    public Object save(@RequestBody SaleOrder model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            connection.setAutoCommit(false);
            generateCode(model, connection);
            model.setStatus(MESEnum.SALE_ORDER_OF_STATUS_PENDING.getValue());
            jdbcClient.jdbcInsert(model, connection);

            List<SaleOrderDetail> childrenList = model.getChildrenList();
            for (SaleOrderDetail detail : childrenList) {
                detail.setOrderId(model.getId());
                jdbcClient.jdbcInsert(detail, connection);
            }

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

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

            jdbcClient.jdbcUpdateById(model, connection);

            List<SaleOrderDetail> childrenList = model.getChildrenList();
            if (null != childrenList && !childrenList.isEmpty()) {
                SaleOrderDetail detailParam = new SaleOrderDetail();
                detailParam.setOrderId(model.getId());
                jdbcClient.jdbcRemove(detailParam, connection);

                for (SaleOrderDetail detail : childrenList) {
                    detail.setOrderId(model.getId());
                    jdbcClient.jdbcInsert(detail, connection);
                }
            }

            connection.commit();
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    @RequestMapping(value = "/remove")
    public Object deleteProgram(@RequestBody SaleOrder model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            connection.setAutoCommit(false);
            jdbcClient.jdbcRemoveById(model, connection);

            SaleOrderDetail detailParam = new SaleOrderDetail();
            detailParam.setOrderId(model.getId());
            jdbcClient.jdbcRemove(detailParam, connection);

            connection.commit();
            return new ResponseEntity<>(HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw new BizException(e.getMessage());
        } finally {
            connection.close();
        }
    }

    private synchronized void generateCode(SaleOrder model, Connection connection) throws Exception {
        if (StringUtil.isEmpty(model.getCode())) {
            while (true) {
                String flowNo = flowNoService.getFlowNo(MESEnum.FLOW_NO_TYPE_SALE_ORDER.getValue(), connection);
                SaleOrder param = new SaleOrder();
                param.setCode(flowNo);
                int count = jdbcClient.getJdbcCount(param, connection);
                if (count == 0) {
                    model.setCode(flowNo);
                    break;
                }
            }
        } else {
            SaleOrder param = new SaleOrder();
            param.setCode(model.getCode());
            int count = jdbcClient.getJdbcCount(param, connection);
            if (count > 0) {
                throw new BizException("编号已存在，请重新填写");
            }
        }
    }
}
