package easydo.technology.service.impl;

import easydo.technology.components.JdbcClient;
import easydo.technology.enums.MESEnum;
import easydo.technology.exception.BizException;
import easydo.technology.model.SalePlan;
import easydo.technology.service.FlowNoService;
import easydo.technology.service.SalePlanService;
import easydo.technology.utils.SecurityUtils;
import easydo.technology.utils.StringUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import java.util.Map;

@Service
public class SalePlanServiceImpl implements SalePlanService {

    @Resource
    JdbcClient jdbcClient;
    @Resource
    DataSource dataSource;
    @Resource
    FlowNoService flowNoService;

    @Override
    public List<SalePlan> getList(Map<String, Object> map) throws Exception {
        List<SalePlan> list = jdbcClient.getJdbcList(map, SalePlan.class);
        fillTotalActualPrice(list);
        return list;
    }

    @Override
    public Map<String, Object> getPage(Map<String, Object> map) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            Map<String, Object> recordsPage = jdbcClient.getJdbcPage(map, SalePlan.class, connection);
            List<SalePlan> records = (List<SalePlan>) recordsPage.get("records");
            fillTotalActualPrice(records);
            return recordsPage;
        } finally {
            connection.close();
        }
    }

    @Override
    public SalePlan save(SalePlan model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            connection.setAutoCommit(false);

            // 1. 对齐 Go 逻辑：校验计划是否已存在 (BeginDate + EndDate + Type)
            SalePlan existPlan = new SalePlan();
            existPlan.setBeginDate(model.getBeginDate());
            existPlan.setEndDate(model.getEndDate());
            existPlan.setType(model.getType());
            int count = jdbcClient.getJdbcCount(existPlan, connection);
            if (count > 0) {
                throw new BizException("该计划已存在，请勿重复添加");
            }

            // 2. 生成编码
            model.setCode(flowNoService.generateSalePlanCode(model, connection));

            // 3. 设置创建人
            model.setCreateId(SecurityUtils.getCurrentUserId());

            // 4. 保存
            jdbcClient.jdbcInsert(model, connection);

            connection.commit();
            return model;
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            connection.close();
        }
    }

    @Override
    public void update(SalePlan model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            connection.setAutoCommit(false);

            // 1. 校验计划是否已存在 (BeginDate + EndDate + Type)，排除自身
            SalePlan param = new SalePlan();
            param.setBeginDate(model.getBeginDate());
            param.setEndDate(model.getEndDate());
            param.setType(model.getType());
            List<SalePlan> existList = jdbcClient.getJdbcList(param, connection);
            if (existList != null && !existList.isEmpty()) {
                for (SalePlan exist : existList) {
                    if (!exist.getId().equals(model.getId())) {
                        throw new BizException("该计划已存在，请勿重复添加");
                    }
                }
            }

            model.setUpdateId(SecurityUtils.getCurrentUserId());
            jdbcClient.jdbcUpdateById(model, connection);
            connection.commit();
        } catch (Exception e) {
            connection.rollback();
            throw e;
        } finally {
            connection.close();
        }
    }

    @Override
    public void remove(SalePlan model) throws Exception {
        Connection connection = dataSource.getConnection();
        try {
            jdbcClient.jdbcRemoveById(model, connection);
        } finally {
            connection.close();
        }
    }

    private void fillTotalActualPrice(List<SalePlan> records) throws Exception {
        if (records == null || records.isEmpty()) {
            return;
        }
        for (SalePlan model : records) {
            calculateTotalActualPrice(model);
        }
    }

    private void calculateTotalActualPrice(SalePlan model) throws Exception {
        if (model == null) {
            return;
        }
        if (StringUtil.isEmpty(model.getBeginDate()) || StringUtil.isEmpty(model.getEndDate())) {
            model.setTotalActualPrice(BigDecimal.ZERO);
            return;
        }

        String sql = String.format("SELECT sum(actual_price) as actualPrice FROM sale_order where order_date > '%s' and order_date < '%s' and status = '%s'",
                model.getBeginDate(), model.getEndDate(), MESEnum.SALE_ORDER_OF_STATUS_COMPLETE.getValue());

        Connection connection = dataSource.getConnection();
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            statement = connection.createStatement();
            resultSet = statement.executeQuery(sql);
            if (resultSet.next()) {
                BigDecimal total = resultSet.getBigDecimal("actualPrice");
                model.setTotalActualPrice(total != null ? total : BigDecimal.ZERO);
            } else {
                model.setTotalActualPrice(BigDecimal.ZERO);
            }
        } finally {
            if (resultSet != null) resultSet.close();
            if (statement != null) statement.close();
            connection.close();
        }
    }
}

