package com.weather.modules.weather.dailydata;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.weather.modules.weather.dailydata.dto.ImportProgress;
import com.weather.modules.weather.dailydata.service.WeatherDailyDataService;
import com.weather.modules.weather.dailydata.vo.WeatherExcelVO;
import com.weather.modules.security.user.SecurityUser;
import com.weather.modules.security.user.UserContextHolder;
import com.weather.modules.security.user.UserDetail;
import com.weather.common.redis.RedisKeys;
import com.weather.common.redis.RedisUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Component
@AllArgsConstructor
public class WeatherDataImportManager {

    private final WeatherDailyDataService weatherDailyDataService;
    private final RedisUtils redisUtils;
    private final Map<String, ImportProgress> tasks = new ConcurrentHashMap<>();

    public String submitImport(MultipartFile file) throws IOException {
        File tempFile = File.createTempFile("import_", ".xlsx");
        file.transferTo(tempFile);

        String taskId = UUID.randomUUID().toString();
        ImportProgress progress = new ImportProgress(taskId);
        progress.setStatus("PROCESSING");
        tasks.put(taskId, progress);

        UserDetail user = SecurityUser.getUser();
        CompletableFuture.runAsync(() -> {
            UserContextHolder.set(user);
            try {
                processImport(taskId, tempFile);
            } catch (Exception e) {
                log.error("导入任务 {} 失败", taskId, e);
                ImportProgress p = tasks.get(taskId);
                if (p != null) {
                    p.setStatus("FAILED");
                    p.setErrorMessage(e.getMessage());
                }
            } finally {
                UserContextHolder.remove();
                if (!tempFile.delete()) {
                    tempFile.deleteOnExit();
                }
            }
        });

        return taskId;
    }

    private void processImport(String taskId, File tempFile) {
        ImportProgress progress = tasks.get(taskId);

        AnalysisEventListener<WeatherExcelVO> countListener = new AnalysisEventListener<>() {
            @Override
            public void invoke(WeatherExcelVO data, AnalysisContext context) {
                progress.setTotalRows(progress.getTotalRows() + 1);
            }
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                log.info("任务 {} 共 {} 行", taskId, progress.getTotalRows());
            }
        };
        EasyExcel.read(tempFile, WeatherExcelVO.class, countListener).sheet().doRead();

        EasyExcel.read(tempFile, WeatherExcelVO.class, new WeatherDataListener(weatherDailyDataService, progress))
                .sheet()
                .doRead();

        progress.setStatus("COMPLETED");
        log.info("导入任务 {} 完成，共导入 {} 行", taskId, progress.getProcessedRows().get());

        // 导入完成后清除天气汇总缓存，等待下次定时任务刷新
        try {
            redisUtils.deleteByPattern(RedisKeys.getWeatherSummarizePattern());
            log.info("已清除天气汇总缓存");
        } catch (Exception e) {
            log.warn("清除天气汇总缓存失败", e);
        }
    }

    public ImportProgress getProgress(String taskId) {
        return tasks.get(taskId);
    }
}
