package com.hdkj.lt.bf.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Sunlit
 * @date 2026/5/20 15:02
 * @description
 **/
@Slf4j
@RestController
@RequestMapping("/api/export")
public class ExportController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @PostMapping("/csv")
    public void exportToCsv(@RequestBody Map<String, String> request,
                            HttpServletResponse response) throws IOException {
        String sql = request.get("sql");
        
        log.info("开始导出CSV，SQL: {}", sql);
        long startTime = System.currentTimeMillis();

        // 设置响应头
        response.setContentType("text/csv;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=export.csv");
        response.setCharacterEncoding("UTF-8");
        response.setBufferSize(8192); // 设置缓冲区大小

        try (PrintWriter writer = response.getWriter()) {
            // 写入BOM解决中文乱码
            writer.write("\uFEFF");

            // 使用流式查询避免内存溢出
            final boolean[] headerWritten = {false};
            final long[] rowCount = {0};

            jdbcTemplate.query(sql, new RowCallbackHandler() {
                @Override
                public void processRow(ResultSet rs) throws SQLException {
                    // 第一次处理时获取列名并写入表头
                    if (!headerWritten[0]) {
                        int columnCount = rs.getMetaData().getColumnCount();
                        List<String> headers = new ArrayList<>(columnCount);
                        
                        for (int i = 1; i <= columnCount; i++) {
                            String columnName = rs.getMetaData().getColumnName(i);
                            headers.add(columnName);
                        }
                        
                        writer.println(String.join(",", headers));
                        headerWritten[0] = true;
                    }

                    // 写入当前行数据
                    int columnCount = rs.getMetaData().getColumnCount();
                    List<String> values = new ArrayList<>(columnCount);
                    
                    for (int i = 1; i <= columnCount; i++) {
                        Object value = rs.getObject(i);
                        String strValue = value != null ? value.toString() : "";
                        
                        // 处理逗号和引号
                        if (strValue.contains(",") || strValue.contains("\"") || strValue.contains("\n")) {
                            strValue = "\"" + strValue.replace("\"", "\"\"") + "\"";
                        }
                        values.add(strValue);
                    }
                    writer.println(String.join(",", values));
                    
                    rowCount[0]++;
                    // 每处理10000行记录一次日志
                    if (rowCount[0] % 10000 == 0) {
                        log.debug("已处理 {} 行数据", rowCount[0]);
                    }
                }
            });
            
            writer.flush();
            
            long endTime = System.currentTimeMillis();
            log.info("CSV导出完成，共处理 {} 行数据，耗时: {} ms", rowCount[0], (endTime - startTime));
        } catch (Exception e) {
            log.error("导出CSV失败", e);
            throw new IOException("导出CSV失败: " + e.getMessage(), e);
        }
    }
}
