package cn.com.qmth.examcloud.tool.service.export_exam_capture;

import cn.com.qmth.examcloud.tool.config.SysProperty;
import cn.com.qmth.examcloud.tool.entity.TaskEntity;
import cn.com.qmth.examcloud.tool.service.CommonService;
import cn.com.qmth.examcloud.tool.service.TaskService;
import cn.com.qmth.examcloud.tool.service.export_exam_capture.vo.ExamCaptureInfo;
import cn.com.qmth.examcloud.tool.utils.FileHelper;
import cn.com.qmth.examcloud.tool.utils.FssHelper;
import cn.com.qmth.examcloud.tool.vo.user.User;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class ExportExamCaptureTask implements TaskService {

    private final static Logger log = LoggerFactory.getLogger(ExportExamCaptureTask.class);

    @Autowired
    private SysProperty sysProperty;

    @Autowired
    private CommonService commonService;

    @Override
    public void start(TaskEntity task) {
        // this.execute(loginUser, task);
    }

    public void execute(User loginUser, String exportDir) {
        List<ExamCaptureInfo> captures = this.loadDataFromExcel(exportDir + "/ec_oe_exam_sync_capture.xlsx");
        // List<ExamCaptureInfo> captures = this.loadDataFromExcel(exportDir + "/ec_oe_exam_capture.xlsx");
        this.downloadImages(captures, exportDir);
    }

    private List<ExamCaptureInfo> loadDataFromExcel(String dataFilePath) {
        /*
            select d.id as exam_record_data_id,d.exam_id,d.course_id,c.code as course_code,c.name as course_name,
            d.student_id,d.student_code,s.identity_number,d.student_name,p.file_url,org.id as org_id,org.name as org_name
            from ec_oe_exam_sync_capture p
            -- from ec_oe_exam_capture p
            inner join ec_oe_exam_record_data d on p.exam_record_data_id=d.id
            inner join ec_b_student s on s.id=d.student_id
            inner join ec_b_course c on c.id=d.course_id
            inner join ec_b_org org on org.id=d.org_id
            where d.exam_id in (6169)
            limit 10;
         */

        long startTime = System.currentTimeMillis();
        List<ExamCaptureInfo> list = new ArrayList<>();
        try {
            EasyExcel.read(dataFilePath, ExamCaptureInfo.class, new AnalysisEventListener<ExamCaptureInfo>() {
                        @Override
                        public void invoke(ExamCaptureInfo data, AnalysisContext analysisContext) {
                            list.add(data);
                        }

                        @Override
                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                            // ignore
                        }
                    }
            ).sheet().doRead();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("Excel内容解析错误，请使用标准模板！");
        }

        long cost = System.currentTimeMillis() - startTime;
        log.info("【获取抓拍照】 总数:{} 耗时:{}ms", list.size(), cost);
        return list;
    }

    private void downloadImages(List<ExamCaptureInfo> list, String exportDir) {
        long startTime = System.currentTimeMillis();
        int totalCount = list.size();
        AtomicInteger finishCount = new AtomicInteger(), successCount = new AtomicInteger(), failCount = new AtomicInteger();
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        for (ExamCaptureInfo info : list) {
            executorService.execute(() -> {
                // 路径规则：/capture/考试ID/科目代码_科目名称/考试记录ID/证件号_考生姓名/抓拍照片名称.jpg
                String savePhotoPath = String.format("%s/capture/%s/%s_%s/%s/%s_%s/%s", exportDir, info.getExamId(),
                        info.getCourseCode(), info.getCourseName(), info.getExamRecordDataId(),
                        info.getIdentityNumber(), info.getStudentName(),
                        FileHelper.getFileName(info.getFileUrl()));

                // 路径规则：/capture/20241211/学习中心名称/证件号_考生姓名_考试ID_科目代码_考试记录ID_抓拍照片名称.jpg
                // String savePhotoPath = String.format("%s/capture/20241211/%s/%s_%s_%s_%s_%s_%s", exportDir, info.getOrgName(),
                //         info.getIdentityNumber(), info.getStudentName(), info.getExamId(), info.getCourseCode(),
                //         info.getExamRecordDataId(), FileHelper.getFileName(info.getFileUrl()));

                this.doDownload(info.getFileUrl(), savePhotoPath, successCount, failCount);
                finishCount.incrementAndGet();

                if (finishCount.get() % 100 == 0) {
                    float finishRate = finishCount.get() * 100f / totalCount;
                    long cost = Math.max((System.currentTimeMillis() - startTime) / 1000, 1);
                    float speed = (float) finishCount.get() / cost;
                    log.info("【图片下载】 总数:{} 成功数:{} 失败数:{} 进度:{}% 速度:约{}个每秒 已耗时:{}秒",
                            totalCount, successCount.get(), failCount.get(), finishRate, speed, cost);
                }
            });
        }

        // 停止接受新任务，并等待所有任务完成
        executorService.shutdown();
        while (!executorService.isTerminated()) {
            // ignore
        }

        float finishRate = finishCount.get() * 100f / totalCount;
        long cost = Math.max((System.currentTimeMillis() - startTime) / 1000, 1);
        float speed = (float) finishCount.get() / cost;
        log.info("【图片下载】 总数:{} 成功数:{} 失败数:{} 进度:{}% 速度:约{}个每秒 已耗时:{}秒",
                totalCount, successCount.get(), failCount.get(), finishRate, speed, cost);
    }

    private void doDownload(String photoUrl, String photoPath, AtomicInteger successCount, AtomicInteger failCount) {
        // String urlPrefix = "https://ecs-test-static.qmth.com.cn";
        String urlPrefix = "https://ecs-static.qmth.com.cn";
        photoUrl = FssHelper.finalFileUrl(photoUrl, urlPrefix);

        if (new File(photoPath).exists()) {
            log.debug("【已下载】 {} {}", photoPath, photoUrl);
            successCount.incrementAndGet();
            return;
        }

        try {
            FileHelper.saveImageToFile(photoUrl, photoPath);
            successCount.incrementAndGet();
        } catch (Exception e) {
            log.error("【下载错误】 {} err:{}", photoPath, e.getMessage());
            failCount.incrementAndGet();
        }
    }

}
