package com.erp.dataimport.util;

import com.erp.dataimport.exception.DataImportException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * CSV工具类
 */
@Slf4j
public class CsvUtils {

    private static final String CSV_EXTENSION = ".csv";

    /**
     * 读取CSV文件
     */
    public static List<Map<String, String>> readCsv(InputStream inputStream, int headerRowIndex) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);
            
            List<Map<String, String>> result = new ArrayList<>();
            List<CSVRecord> allRecords = csvParser.getRecords();
            
            if (allRecords.isEmpty()) {
                csvParser.close();
                return result;
            }

            // 跳过表头行
            int startIndex = headerRowIndex;
            if (startIndex >= allRecords.size()) {
                csvParser.close();
                return result;
            }

            // 获取表头
            CSVRecord headerRecord = allRecords.get(0);
            List<String> headers = new ArrayList<>();
            for (int i = 0; i < headerRecord.size(); i++) {
                headers.add(headerRecord.get(i));
            }

            // 读取数据行
            for (int i = startIndex; i < allRecords.size(); i++) {
                CSVRecord record = allRecords.get(i);
                Map<String, String> rowData = new LinkedHashMap<>();
                for (int j = 0; j < headers.size() && j < record.size(); j++) {
                    rowData.put(headers.get(j), record.get(j));
                }
                result.add(rowData);
            }
            
            csvParser.close();
            return result;
        } catch (Exception e) {
            log.error("读取CSV失败", e);
            throw new DataImportException("READ_ERROR", "读取CSV文件失败: " + e.getMessage());
        }
    }

    /**
     * 读取CSV文件（返回列索引映射）
     */
    public static List<Map<Integer, String>> readCsvWithIndex(InputStream inputStream, int headerRowIndex) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            CSVParser csvParser = new CSVParser(reader, CSVFormat.DEFAULT);
            
            List<Map<Integer, String>> result = new ArrayList<>();
            List<CSVRecord> allRecords = csvParser.getRecords();
            
            if (allRecords.isEmpty()) {
                csvParser.close();
                return result;
            }

            int startIndex = headerRowIndex;
            if (startIndex >= allRecords.size()) {
                csvParser.close();
                return result;
            }

            for (int i = startIndex; i < allRecords.size(); i++) {
                CSVRecord record = allRecords.get(i);
                Map<Integer, String> rowData = new LinkedHashMap<>();
                for (int j = 0; j < record.size(); j++) {
                    rowData.put(j, record.get(j));
                }
                result.add(rowData);
            }
            
            csvParser.close();
            return result;
        } catch (Exception e) {
            log.error("读取CSV失败", e);
            throw new DataImportException("READ_ERROR", "读取CSV文件失败: " + e.getMessage());
        }
    }

    /**
     * 写入CSV文件
     */
    public static void writeCsv(OutputStream outputStream, List<String> headers, List<List<Object>> dataList) {
        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
            CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(headers.toArray(new String[0])));
            
            for (List<Object> row : dataList) {
                List<String> rowData = new ArrayList<>();
                for (Object cell : row) {
                    rowData.add(cell != null ? cell.toString() : "");
                }
                csvPrinter.printRecord(rowData);
            }
            
            csvPrinter.flush();
            csvPrinter.close();
        } catch (Exception e) {
            log.error("写入CSV失败", e);
            throw new DataImportException("WRITE_ERROR", "写入CSV文件失败: " + e.getMessage());
        }
    }

    /**
     * 生成CSV文件（从Map列表）
     */
    public static void writeCsvFromMap(OutputStream outputStream, List<String> headers, List<Map<String, Object>> dataList) {
        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
            CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT.withHeader(headers.toArray(new String[0])));
            
            for (Map<String, Object> row : dataList) {
                List<String> rowData = new ArrayList<>();
                for (String header : headers) {
                    Object value = row.get(header);
                    rowData.add(value != null ? value.toString() : "");
                }
                csvPrinter.printRecord(rowData);
            }
            
            csvPrinter.flush();
            csvPrinter.close();
        } catch (Exception e) {
            log.error("写入CSV失败", e);
            throw new DataImportException("WRITE_ERROR", "写入CSV文件失败: " + e.getMessage());
        }
    }

    /**
     * 验证CSV格式
     */
    public static void validateCsvFormat(String fileName) {
        if (fileName == null || !fileName.toLowerCase().endsWith(CSV_EXTENSION)) {
            throw new DataImportException("INVALID_FORMAT", "不支持的文件格式，仅支持CSV");
        }
    }

    /**
     * 获取CSV行数
     */
    public static int getRowCount(InputStream inputStream) {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            int count = 0;
            while (reader.readLine() != null) {
                count++;
            }
            reader.close();
            return count - 1; // 减去表头
        } catch (Exception e) {
            log.error("获取行数失败", e);
            return 0;
        }
    }
}
