package com.campus.activity.util;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.campus.activity.entity.Activity;
import com.campus.activity.entity.CheckIn;
import com.campus.activity.entity.Registration;
import com.campus.activity.entity.Review;
import com.campus.activity.mapper.CheckInMapper;
import com.campus.activity.mapper.RegistrationMapper;
import com.campus.activity.mapper.ReviewMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class CsvUtil {

    private final RegistrationMapper registrationMapper;
    private final CheckInMapper checkInMapper;
    private final ReviewMapper reviewMapper;

    public byte[] exportActivityData(Activity activity) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        
        try {
            // 写入BOM头，正确识别UTF-8编码
            outputStream.write(0xEF);
            outputStream.write(0xBB);
            outputStream.write(0xBF);

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            
            // 写入表头
            StringBuilder header = new StringBuilder();
            header.append("活动ID,活动名称,开始时间,结束时间,活动地点,报名人数上限,报名人数,签到人数,签到率,评价人数,平均评分,1星,2星,3星,4星,5星");
            outputStream.write(header.toString().getBytes(StandardCharsets.UTF_8));
            outputStream.write("\n".getBytes(StandardCharsets.UTF_8));
            
            // 统计数据
            long registeredCount = registrationMapper.selectCount(
                new LambdaQueryWrapper<Registration>()
                    .eq(Registration::getActivityId, activity.getId())
                    .in(Registration::getStatus, 1, 2)
            );
            
            List<CheckIn> checkIns = checkInMapper.selectList(
                new LambdaQueryWrapper<CheckIn>()
                    .eq(CheckIn::getActivityId, activity.getId())
            );
            long checkedInCount = checkIns.size();
            
            double checkInRate = registeredCount > 0 ? (double) checkedInCount / registeredCount : 0.0;
            
            List<Review> reviews = reviewMapper.selectList(
                new LambdaQueryWrapper<Review>()
                    .eq(Review::getActivityId, activity.getId())
            );
            long reviewCount = reviews.size();
            
            double averageRating = reviews.isEmpty() ? 0.0 :
                reviews.stream().mapToInt(Review::getRating).average().orElse(0.0);
            
            // 评分分布
            Map<Integer, Long> ratingDistribution = new java.util.HashMap<>();
            for (int i = 1; i <= 5; i++) {
                final int rating = i;
                long count = reviews.stream().filter(r -> r.getRating() == rating).count();
                ratingDistribution.put(rating, count);
            }
            
            // 写入数据行
            StringBuilder dataLine = new StringBuilder();
            dataLine.append(escapeCsv(String.valueOf(activity.getId()))).append(",");
            dataLine.append(escapeCsv(activity.getTitle())).append(",");
            dataLine.append(escapeCsv(activity.getStartTime() != null ? activity.getStartTime().format(formatter) : "")).append(",");
            dataLine.append(escapeCsv(activity.getEndTime() != null ? activity.getEndTime().format(formatter) : "")).append(",");
            dataLine.append(escapeCsv(activity.getLocation())).append(",");
            dataLine.append(escapeCsv(String.valueOf(activity.getMaxParticipants()))).append(",");
            dataLine.append(escapeCsv(String.valueOf(registeredCount))).append(",");
            dataLine.append(escapeCsv(String.valueOf(checkedInCount))).append(",");
            dataLine.append(escapeCsv(String.format("%.2f%%", checkInRate * 100))).append(",");
            dataLine.append(escapeCsv(String.valueOf(reviewCount))).append(",");
            dataLine.append(escapeCsv(String.format("%.1f", averageRating))).append(",");
            dataLine.append(escapeCsv(String.valueOf(ratingDistribution.getOrDefault(1, 0L)))).append(",");
            dataLine.append(escapeCsv(String.valueOf(ratingDistribution.getOrDefault(2, 0L)))).append(",");
            dataLine.append(escapeCsv(String.valueOf(ratingDistribution.getOrDefault(3, 0L)))).append(",");
            dataLine.append(escapeCsv(String.valueOf(ratingDistribution.getOrDefault(4, 0L)))).append(",");
            dataLine.append(escapeCsv(String.valueOf(ratingDistribution.getOrDefault(5, 0L))));
            
            outputStream.write(dataLine.toString().getBytes(StandardCharsets.UTF_8));

            return outputStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("导出CSV失败: " + e.getMessage(), e);
        } finally {
            try {
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private String escapeCsv(String value) {
        if (value == null) {
            return "";
        }
        // 如果包含逗号、引号或换行符，需要用引号包裹并转义
        if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
            return "\"" + value.replace("\"", "\"\"") + "\"";
        }
        return value;
    }
}