package easydo.technology.service.impl;

import easydo.technology.model.vo.SalePerformanceVO;
import easydo.technology.model.vo.SalePriceByDayVO;
import easydo.technology.service.SalePerformanceService;
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.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SalePerformanceServiceImpl implements SalePerformanceService {

    @Resource
    private DataSource dataSource;

    @Override
    public SalePerformanceVO getTotalPrice(Map<String, Object> map) throws Exception {
        Object tenantIdObj = map.get("tenantId");
        String tenantId = tenantIdObj != null ? tenantIdObj.toString() : "";
        LocalDate now = LocalDate.now();
        
        // 年度范围
        String beginYear = now.with(TemporalAdjusters.firstDayOfYear()).toString();
        String endYear = now.with(TemporalAdjusters.lastDayOfYear()).toString();
        // 月度范围
        String beginMonth = now.with(TemporalAdjusters.firstDayOfMonth()).toString();
        String endMonth = now.with(TemporalAdjusters.lastDayOfMonth()).toString();

        SalePerformanceVO vo = new SalePerformanceVO();
        try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
            // 1. 年度计划额
            vo.setPlanSalePriceByYear(getSum(stmt, String.format(
                "select ifnull(sum(sale_amount),0) from sale_plan where begin_date = '%s' and end_date = '%s' and type = 'year' and tenant_id = '%s'",
                beginYear, endYear, tenantId)));
            
            // 2. 月度计划额
            vo.setPlanSalePriceByMonth(getSum(stmt, String.format(
                "select ifnull(sum(sale_amount),0) from sale_plan where begin_date = '%s' and end_date = '%s' and type = 'month' and tenant_id = '%s'",
                beginMonth, endMonth, tenantId)));

            // 3. 年度实际额
            vo.setActualSalePriceByYear(getSum(stmt, String.format(
                "select ifnull(sum(actual_price),0) from sale_order where order_date >= '%s' and order_date <= '%s' and tenant_id = '%s'",
                beginYear, endYear, tenantId)));

            // 4. 月度实际额
            vo.setActualSalePriceByMonth(getSum(stmt, String.format(
                "select ifnull(sum(actual_price),0) from sale_order where order_date >= '%s' and order_date <= '%s' and tenant_id = '%s'",
                beginMonth, endMonth, tenantId)));
        }
        return vo;
    }

    @Override
    public SalePerformanceVO getEcharts(Map<String, Object> map) throws Exception {
        String type = (String) map.get("type");
        String beginDate = (String) map.get("beginDate");
        String endDate = (String) map.get("endDate");
        Object tenantIdObj = map.get("tenantId");
        String tenantId = tenantIdObj != null ? tenantIdObj.toString() : "";

        SalePerformanceVO vo = new SalePerformanceVO();
        try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) {
            String planSql = "";
            String actualSql = "";

            if ("month".equals(type)) {
                planSql = String.format("select left(begin_date,7) as datestr, ifnull(sum(sale_amount),0) as price from sale_plan where begin_date >= '%s' and end_date <= '%s' and tenant_id = '%s' and type = 'month' group by begin_date", beginDate, endDate, tenantId);
                actualSql = String.format("select left(order_date,7) as datestr, ifnull(sum(actual_price),0) as price from sale_order where order_date >= '%s' and order_date <= '%s' and tenant_id = '%s' group by order_date", beginDate, endDate, tenantId);
            } else if ("quarter".equals(type)) {
                planSql = String.format("select CONCAT(YEAR(begin_date), '-Q', QUARTER(begin_date)) as datestr, ifnull(sum(sale_amount),0) as price from sale_plan where begin_date >= '%s' and end_date <= '%s' and tenant_id = '%s' and type = 'quarter' group by QUARTER(begin_date),YEAR(begin_date)", beginDate, endDate, tenantId);
                actualSql = String.format("select CONCAT(YEAR(order_date), '-Q', QUARTER(order_date)) as datestr, ifnull(sum(actual_price),0) as price from sale_order where order_date >= '%s' and order_date <= '%s' and tenant_id = '%s' group by QUARTER(order_date),YEAR(order_date)", beginDate, endDate, tenantId);
            } else if ("year".equals(type)) {
                planSql = String.format("select YEAR(begin_date) as datestr, ifnull(sum(sale_amount),0) as price from sale_plan where begin_date >= '%s' and end_date <= '%s' and tenant_id = '%s' and type = 'year' group by YEAR(begin_date)", beginDate, endDate, tenantId);
                actualSql = String.format("select YEAR(order_date) as datestr, ifnull(sum(actual_price),0) as price from sale_order where order_date >= '%s' and order_date <= '%s' and tenant_id = '%s' group by YEAR(order_date)", beginDate, endDate, tenantId);
            } else if ("date".equals(type)) {
                actualSql = String.format("select order_date as date, ifnull(sum(actual_price),0) as price from sale_order where order_date >= '%s' and order_date <= '%s' and tenant_id = '%s' group by order_date", beginDate, endDate, tenantId);
            }

            if (StringUtil.isNotEmpty(planSql)) vo.setPlanList(executeQuery(stmt, planSql, false));
            if (StringUtil.isNotEmpty(actualSql)) vo.setActualList(executeQuery(stmt, actualSql, "date".equals(type)));
        }
        return vo;
    }

    private BigDecimal getSum(Statement stmt, String sql) throws Exception {
        try (ResultSet rs = stmt.executeQuery(sql)) {
            return rs.next() ? rs.getBigDecimal(1) : BigDecimal.ZERO;
        }
    }

    private List<SalePriceByDayVO> executeQuery(Statement stmt, String sql, boolean isDateMode) throws Exception {
        List<SalePriceByDayVO> list = new ArrayList<>();
        try (ResultSet rs = stmt.executeQuery(sql)) {
            while (rs.next()) {
                SalePriceByDayVO item = new SalePriceByDayVO();
                if (isDateMode) {
                    item.setDate(rs.getString("date"));
                } else {
                    item.setDatestr(rs.getString("datestr"));
                }
                item.setPrice(rs.getBigDecimal("price"));
                list.add(item);
            }
        }
        return list;
    }
}

