package easydo.technology.controller;

import easydo.technology.annotation.WebLog;
import easydo.technology.components.JdbcClient;
import easydo.technology.enums.ChengfaEnum;
import easydo.technology.exception.BizException;
import easydo.technology.model.*;
import easydo.technology.model.vo.DictVo;
import easydo.technology.service.OAService;
import easydo.technology.service.RedisDictService;
import easydo.technology.utils.LocalDateUtil;
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 com.alibaba.fastjson.JSONObject;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Connection;
import java.time.LocalDateTime;
import java.util.*;

@RestController
@RequestMapping("/supplierEvaluate")
public class SupplierEvaluateController {
    @Resource
    JdbcClient jdbcClient;
    @Resource
    DataSource dataSource;
    @Resource
    RedisDictService redisDictService;
    @Resource
    OAService oaService;

    @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, SupplierEvaluate.class, connection);
            List<SupplierEvaluate> list = (List<SupplierEvaluate>) page.get("records");
            for (SupplierEvaluate model : list) {
                Supplier supplier = new Supplier();
                supplier.setId(model.getSupplierId());
                supplier = jdbcClient.getJdbcModelById(supplier, connection);
                model.setSupplier(supplier);

                PurchaseContract contract = new PurchaseContract();
                contract.setId(model.getContractId());
                contract = jdbcClient.getJdbcModelById(contract, connection);
                model.setContract(contract);
            }
            return new ResponseEntity<>(page, 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<SupplierEvaluate> list = jdbcClient.getJdbcList(map, SupplierEvaluate.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 SupplierEvaluate model) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);

            model.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_STATUS_ACTIVE.getValue());
            jdbcClient.jdbcInsert(model, connection);

            List<SupplierEvaluateDetail> detailList = model.getEvaluateDetailList();
            for (SupplierEvaluateDetail detail : detailList) {
                detail.setEvaluateId(model.getId());
                detail.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_ACTIVE.getValue());
                jdbcClient.jdbcInsert(detail, connection);
            }
            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

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

            SupplierEvaluate evaluate = new SupplierEvaluate();
            evaluate.setId(model.getEvaluateId());
            evaluate = jdbcClient.getJdbcModelById(evaluate, connection);
            if (ChengfaEnum.SUPPLIER_EVALUATE_STATUS_ACTIVE.getValue().equals(evaluate.getStatus())) {
                throw new BizException("此供应商评价尚未发起评价,请勿评价");
            }
            if (ChengfaEnum.SUPPLIER_EVALUATE_STATUS_DONE.getValue().equals(evaluate.getStatus())) {
                throw new BizException("此供应商评价已完成评价,请勿重复评价");
            }

            model.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_DONE.getValue());
            model.setEvaluateTime(LocalDateUtil.localDateTimeFormatyMdHms(LocalDateTime.now()));

            DictVo dictVo = redisDictService.getGradeScore(model.getScore());
            model.setGrade(dictVo.getGrade());
            model.setScore(dictVo.getScore().doubleValue());
            jdbcClient.jdbcUpdateById(model, connection);

            SupplierEvaluateDetail detailParam = new SupplierEvaluateDetail();
            detailParam.setEvaluateId(model.getEvaluateId());
            detailParam.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_EVALUATE.getValue());
            int count = jdbcClient.getJdbcCount(detailParam, connection);
            if (count == 0) {
                evaluate.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_STATUS_DONE.getValue());

                detailParam = new SupplierEvaluateDetail();
                detailParam.setEvaluateId(model.getEvaluateId());
                detailParam.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_DONE.getValue());
                List<SupplierEvaluateDetail> detailList = jdbcClient.getJdbcList(detailParam, connection);
                OptionalDouble average = detailList.stream().mapToDouble(SupplierEvaluateDetail::getScore).average();
                if (average.isPresent()) {
                    double score = average.getAsDouble();
                    dictVo = redisDictService.getGradeScore(score);
                    evaluate.setGrade(dictVo.getGrade());
                    evaluate.setScore(dictVo.getScore());
                    evaluate.setEvaluateFinishTime(model.getEvaluateTime());
                }
                jdbcClient.jdbcUpdateById(evaluate, connection);

                Supplier supplier = new Supplier();
                supplier.setId(evaluate.getSupplierId());
                supplier = jdbcClient.getJdbcModelById(supplier, connection);
                SysUser sysUser = new SysUser();
                sysUser.setUserId(evaluate.getCreateId());
                sysUser = jdbcClient.getJdbcModel(sysUser);
                String title = "[招采系统-供应商评价-]" + supplier.getSupplierName() + "]已评价完成，请知悉";
                Message message = new Message();
                message.setReceiveUserId(evaluate.getCreateId());
                message.setReceiveUserName(sysUser.getNickName());
                message.setRefType(ChengfaEnum.MESSAGE_TYPE_SUPPLIER_EVALUATE.getValue());
                message.setRefId(evaluate.getId());
                message.setContent(title);
                jdbcClient.jdbcInsert(message, connection);

                try {
                    oaService.sendMessage(message.getId(), evaluate.getCreateId().toString(),
                            evaluate.getCreateId().toString(), title, "");
                } catch (Exception ee) {
                    ee.printStackTrace();
                }
            }

            try {
                oaService.updateSupplierTodo(model.getId(), 1, 0);
            } catch (Exception ee) {
                ee.printStackTrace();
            }

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

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

            model = jdbcClient.getJdbcModelById(model, connection);
            model.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_EVALUATE.getValue());
            jdbcClient.jdbcUpdateById(model, connection);

            SupplierEvaluate evaluate = new SupplierEvaluate();
            evaluate.setId(model.getEvaluateId());
            evaluate = jdbcClient.getJdbcModelById(evaluate, connection);
            evaluate.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_EVALUATE.getValue());
            jdbcClient.jdbcUpdateById(evaluate, connection);

            Supplier supplier = new Supplier();
            supplier.setId(evaluate.getSupplierId());
            supplier = jdbcClient.getJdbcModelById(supplier, connection);

            String title = "您有一条[招采系统-供应商评价-" + supplier.getSupplierName() + "]被退回，请重新评价";
            String url = "";
            try {
                oaService.updateSupplierTodo(model.getId(), 1, 2);
                JSONObject resObj = oaService.sendSupplierTodo(model.getId(), model.getEvaluatorId().toString(),
                        model.getEvaluateId(), title);
                url = resObj.getString("url");
            } catch (Exception ee) {
                ee.printStackTrace();
            }
            SysUser sysUser = new SysUser();
            sysUser.setUserId(model.getEvaluatorId());
            sysUser = jdbcClient.getJdbcModel(sysUser);
            Message message = new Message();
            message.setReceiveUserId(model.getEvaluatorId());
            message.setReceiveUserName(sysUser.getNickName());
            message.setRefType(ChengfaEnum.MESSAGE_TYPE_SUPPLIER_EVALUATE.getValue());
            message.setRefId(model.getId());
            message.setContent(title);
            jdbcClient.jdbcInsert(message, connection);

            try {
                oaService.sendMessage(message.getId(), model.getEvaluatorId().toString(),
                        model.getEvaluatorId().toString(), title, url);
            } catch (Exception ee) {
                ee.printStackTrace();
            }

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

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

            model = jdbcClient.getJdbcModelById(model);
            model.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_STATUS_EVALUATE.getValue());
            jdbcClient.jdbcUpdateById(model, connection);

            Supplier supplier = new Supplier();
            supplier.setId(model.getSupplierId());
            supplier = jdbcClient.getJdbcModelById(supplier, connection);

            SupplierEvaluateDetail detail = new SupplierEvaluateDetail();
            detail.setEvaluateId(model.getId());
            List<SupplierEvaluateDetail> detailList = jdbcClient.getJdbcList(detail, connection);
            for (SupplierEvaluateDetail detailModel : detailList) {
                detailModel.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_EVALUATE.getValue());
                jdbcClient.jdbcUpdateById(detailModel, connection);

                String title = "您有一条[招采系统-供应商评价-" + supplier.getSupplierName() + "]需要评价，请及时处理";
                String url = "";
                try {
                    JSONObject resObj = oaService.sendSupplierTodo(detailModel.getId(),
                            detailModel.getEvaluatorId().toString(),
                            detailModel.getEvaluateId(), title);
                    url = resObj.getString("url");
                } catch (Exception ee) {
                    ee.printStackTrace();
                }

                SysUser sysUser = new SysUser();
                sysUser.setUserId(detailModel.getEvaluatorId());
                sysUser = jdbcClient.getJdbcModel(sysUser);
                Message message = new Message();
                message.setReceiveUserId(detailModel.getEvaluatorId());
                message.setReceiveUserName(sysUser.getNickName());
                message.setRefType(ChengfaEnum.MESSAGE_TYPE_SUPPLIER_EVALUATE.getValue());
                message.setRefId(detailModel.getId());
                message.setContent(title);
                jdbcClient.jdbcInsert(message, connection);

                try {
                    oaService.sendMessage(message.getId(), detailModel.getEvaluatorId().toString(),
                            detailModel.getEvaluatorId().toString(), title, url);
                } catch (Exception ee) {
                    ee.printStackTrace();
                }
            }
            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 SupplierEvaluate model) throws Exception {
        Connection connection = null;
        try {
            connection = dataSource.getConnection();
            connection.setAutoCommit(false);

            SupplierEvaluate exist = jdbcClient.getJdbcModelById(model, connection);
            if (!ChengfaEnum.SUPPLIER_EVALUATE_STATUS_ACTIVE.getValue().equals(exist.getStatus())) {
                throw new BizException("此供应商评价已经发起评价,请勿编辑");
            }
            jdbcClient.jdbcUpdateById(model, connection);

            SupplierEvaluateDetail detail = new SupplierEvaluateDetail();
            detail.setEvaluateId(model.getId());
            List<SupplierEvaluateDetail> existList = jdbcClient.getJdbcList(detail, connection);
            for (SupplierEvaluateDetail detailModel : existList) {
                if (!ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_ACTIVE.getValue().equals(detailModel.getStatus())) {
                    throw new BizException("此供应商评价已经发起评价,请勿编辑");
                }
                jdbcClient.jdbcRemoveById(detailModel, connection);
            }
            List<SupplierEvaluateDetail> detailList = model.getEvaluateDetailList();
            for (SupplierEvaluateDetail detailModel : detailList) {
                detailModel.setEvaluateId(model.getId());
                detailModel.setStatus(ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_ACTIVE.getValue());
                jdbcClient.jdbcInsert(detailModel, 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 SupplierEvaluate model) throws Exception {
        Map<String, Object> result = new HashMap<>();
        Connection connection = null;
        try {
            connection = dataSource.getConnection();

            model = jdbcClient.getJdbcModelById(model, connection);
            SupplierEvaluateDetail detail = new SupplierEvaluateDetail();
            detail.setEvaluateId(model.getId());
            List<SupplierEvaluateDetail> detailList = jdbcClient.getJdbcList(detail, connection);

            Supplier supplier = new Supplier();
            supplier.setId(model.getSupplierId());
            supplier = jdbcClient.getJdbcModelById(supplier, connection);

            PurchaseContract contract = new PurchaseContract();
            contract.setId(model.getContractId());
            contract = jdbcClient.getJdbcModelById(contract, connection);

            result.put("supplier", supplier);
            result.put("detailList", detailList);
            result.put("evaluate", model);
            result.put("contract", contract);
            return new ResponseEntity<>(result, HttpStatus.OK);
        } catch (Exception e) {
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

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

            SupplierEvaluate exist = jdbcClient.getJdbcModelById(model, connection);
            if (!ChengfaEnum.SUPPLIER_EVALUATE_STATUS_ACTIVE.getValue().equals(exist.getStatus())) {
                throw new BizException("此供应商评价已经发起评价,请勿删除");
            }
            jdbcClient.jdbcRemoveById(model, connection);

            SupplierEvaluateDetail detail = new SupplierEvaluateDetail();
            detail.setEvaluateId(model.getId());
            List<SupplierEvaluateDetail> existList = jdbcClient.getJdbcList(detail, connection);
            for (SupplierEvaluateDetail detailModel : existList) {
                if (!ChengfaEnum.SUPPLIER_EVALUATE_DETAIL_STATUS_ACTIVE.getValue().equals(detailModel.getStatus())) {
                    throw new BizException("此供应商评价已经发起评价,请勿删除");
                }
                jdbcClient.jdbcRemoveById(detailModel, connection);
            }
            connection.commit();
            return new ResponseEntity<>(model, HttpStatus.OK);
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            jdbcClient.finallyExecute(connection);
        }
    }

    @WebLog
    @RequestMapping(value = "/getTongJi")
    public Object getTongJi() throws Exception {
        Map<String, Object> result = new HashMap<>();
        Connection connection = null;
        String sql;
        try {
            connection = dataSource.getConnection();
            sql = "select count(1) commonCount,supplier_type_id from supplier_evaluate group by supplier_type_id";
            List<SupplierEvaluate> supplierTypeCountList = jdbcClient.getJdbcList(new HashMap<>(), sql,
                    SupplierEvaluate.class, connection);

            sql = "select count(1) commonCount,status from supplier_evaluate where status != 'active' group by status";
            List<SupplierEvaluate> supplierStatusCountList = jdbcClient.getJdbcList(new HashMap<>(), sql,
                    SupplierEvaluate.class, connection);

            sql = "select count(1) commonCount,grade from supplier_evaluate where status = 'done' group by grade";
            List<SupplierEvaluate> supplierGradeCountList = jdbcClient.getJdbcList(new HashMap<>(), sql,
                    SupplierEvaluate.class, connection);

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

    @WebLog
    @RequestMapping(value = "/calculate")
    public Object calculate(@RequestBody List<Map<String, BigDecimal>> list) throws Exception {
        List<BigDecimal> result = new ArrayList<>();
        BigDecimal total = BigDecimal.ZERO;
        for (Map<String, BigDecimal> map : list) {
            BigDecimal n1 = StringUtil.isEmpty(map.get("n1")) ? BigDecimal.ZERO : map.get("n1");
            BigDecimal n2 = StringUtil.isEmpty(map.get("n2")) ? BigDecimal.ZERO : map.get("n2");
            BigDecimal number = n1.multiply(n2).setScale(2, RoundingMode.HALF_UP);
            result.add(number);
            total = total.add(number);
        }
        total = total.setScale(2, RoundingMode.HALF_UP);
        result.add(total);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
}
