package com.erp.service;

import com.erp.common.BaseService;
import com.erp.util.DecimalUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
@Slf4j
public class SalesReportService extends BaseService {

    private static final String NS = "salesReport.";
    private final CommonService commonService;

    public Map<String, Object> getSalesReportList(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        commonService.applyPagination(params);
        int totalCount = sqlSession.selectOne(NS + "getSalesReportListCnt", params);
        List<Map<String, Object>> list = sqlSession.selectList(NS + "getSalesReportList", params);
        for (Map<String, Object> row : list) {
            row.put("unit_price", DecimalUtils.toBigDecimal(row.get("unit_price")));
            row.put("order_amt", DecimalUtils.toBigDecimal(row.get("order_amt")));
            row.put("order_qty", DecimalUtils.toBigDecimal(row.get("order_qty")));
            row.put("ship_qty", DecimalUtils.toBigDecimal(row.get("ship_qty")));
        }
        return commonService.buildListResponse(list, totalCount, params);
    }

    public Map<String, Object> getSalesReportSummary(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        Map<String, Object> summary = sqlSession.selectOne(NS + "getSalesReportSummary", params);
        if (summary != null) {
            summary.put("total_amount", DecimalUtils.toBigDecimal(summary.get("total_amount")));
            summary.put("avg_unit_price", DecimalUtils.toBigDecimal(summary.get("avg_unit_price")));
            summary.put("total_qty", DecimalUtils.toBigDecimal(summary.get("total_qty")));
            summary.put("total_ship_qty", DecimalUtils.toBigDecimal(summary.get("total_ship_qty")));
        }
        return summary;
    }

    public Map<String, Object> getSalesReportData(Map<String, Object> params) {
        commonService.applyCompanyCodeFilter(params);
        List<Map<String, Object>> rows = sqlSession.selectList(NS + "getSalesReportDataRows", params);
        for (Map<String, Object> row : rows) {
            row.put("unit_price", DecimalUtils.toBigDecimal(row.get("unit_price")));
            row.put("order_amt", DecimalUtils.toBigDecimal(row.get("order_amt")));
            row.put("order_qty", DecimalUtils.toBigDecimal(row.get("order_qty")));
            row.put("ship_qty", DecimalUtils.toBigDecimal(row.get("ship_qty")));
        }
        List<Map<String, Object>> customers = sqlSession.selectList(NS + "getSalesReportCustomers", params);
        List<Map<String, Object>> statuses = sqlSession.selectList(NS + "getSalesReportStatuses", params);

        // 데이터에서 품목 목록 추출 (중복 제거)
        Map<String, String> itemSet = new LinkedHashMap<>();
        for (Map<String, Object> row : rows) {
            Object partCode = row.get("part_code");
            if (partCode != null && !itemSet.containsKey(partCode.toString())) {
                Object item = row.get("item");
                itemSet.put(partCode.toString(), item != null ? item.toString() : partCode.toString());
            }
        }
        List<Map<String, Object>> items = new ArrayList<>();
        for (Map.Entry<String, String> entry : itemSet.entrySet()) {
            Map<String, Object> itemMap = new HashMap<>();
            itemMap.put("value", entry.getKey());
            itemMap.put("label", entry.getValue());
            items.add(itemMap);
        }

        Map<String, Object> filterOptions = new HashMap<>();
        filterOptions.put("customers", customers);
        filterOptions.put("items", items);
        filterOptions.put("statuses", statuses);

        Map<String, Object> result = new HashMap<>();
        result.put("rows", rows);
        result.put("filter_options", filterOptions);
        result.put("total_count", rows.size());
        return result;
    }
}
