package org.jeecg.module.custom.ocr.api.thread.tasks;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.module.custom.ocr.api.entity.FormRecord;
import org.jeecg.module.custom.ocr.api.entity.LivePhoto;
import org.jeecg.module.custom.ocr.dataobject.Task;
import org.jeecg.module.custom.ocr.service.OcrPictureService;
import org.jeecg.module.custom.ocr.service.TaskService;
import org.jeecg.module.custom.ocr.utils.DownloadImgUtil;
import org.jeecg.module.custom.ocr.utils.ImageUtils;
import org.jeecg.module.custom.ocr.utils.SpringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 无量云接口 数据处理队列
 *
 * @author hugh(shuli.yao) 1397940314@qq.com
 * @version 1.0
 * @date 2024/3/14 11:15
 */
@Slf4j
public class PictureImgToLocalTask implements Runnable {
    protected Logger logger = LoggerFactory.getLogger(getClass());

    private final String localPath = System.getProperty("user.dir");

    private final FormRecord pictureImgToLocal;

    public PictureImgToLocalTask(FormRecord pictureImgToLocal) {
        this.pictureImgToLocal = pictureImgToLocal;
    }

    @Override
    public void run() {
        OcrPictureService ocrPictureService = SpringUtils.getBean("ocrPictureService");
//        OcrPicture picture = ocrPictureService.getById(pictureImgToLocal.getId());
        TaskService taskService = SpringUtils.getBean("taskServiceImpl");
        Task task = taskService.getById(pictureImgToLocal.getTaskId());
        //1.开始转储图片
        Boolean result = true;

        Map<String, List<LivePhoto>> stringListMap = extractAttachmentFields(pictureImgToLocal.getDynamicFields());
        stringListMap.forEach((type, livePhotos) -> {
            handlePicture(result, task, ocrPictureService, taskService, livePhotos, type);
        });
    }

    private void handlePicture(Boolean result, Task task, OcrPictureService ocrPictureService, TaskService taskService, List<LivePhoto> livePhotos, String type) {
        if (CollectionUtils.isEmpty(livePhotos)) {
            return;
        }

        for (LivePhoto livePhoto : livePhotos) {
            //检查是否已经存在本地图片，存在则不进行转储了。
            if (ObjectUtil.isNotEmpty(livePhoto)) {
                File file = new File(livePhoto.getFileUrl());
                // pictureImgToLocal.getLivePhoto().getLocalImgUrl()
                if (!file.isFile()) {
                    result = DownloadImgUtil.downloadImage(livePhoto.getFileUrl(), livePhoto.getFileName());
//            result = DownloadImgUtil.downloadImage(pictureImgToLocal.getLivePhoto().getFileUrl(), "D:\\code\\ocr-activity-backend\\1.jpeg");
                }
            }

            if (!result) {
                return;
            }

            if (ObjectUtil.isNotEmpty(task)) {
                try {
                    task.setLocalImageUrl(localPath + "/" + ImageUtils.generateThumbnail(livePhoto.getFileName(), 182));
//                    picture.setServerThumbnailUrl(ocrPictureService.getServerUrl()+ImageUtils.getFileName(picture.getLocalThumbnailUrl()));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

                logger.info("task: {}", task);
                Map<String, String> ocrPictureClassifyAndHash = ocrPictureService.getOcrPictureClassifyAndHash(task.getLocalImageUrl());
                if (ocrPictureClassifyAndHash != null) {
                    task.setImgHash(ocrPictureClassifyAndHash.get("hash"));
                }

                taskService.updateById(task);
                logger.info("图片本地化，回写数据完成!");
                logger.info("开启获取图片信息操作!");
                ocrPictureService.savePicturesInfo(task, livePhoto.getFileName(), livePhoto.getFileUrl(), type);
                logger.info("获取图片信息操作,结束!");
            }
        }
    }

    public static Map<String, List<LivePhoto>> extractAttachmentFields(Map<String, Object> inputMap) {
        Map<String, List<LivePhoto>> result = new HashMap<>();

        // If the input map represents an array (List), take the first map
        Map<String, Object> targetMap = inputMap;
        if (inputMap.values().stream().findFirst().orElse(null) instanceof List) {
            List<Object> list = (List<Object>) inputMap.values().stream().findFirst().get();
            if (!list.isEmpty() && list.get(0) instanceof Map) {
                targetMap = (Map<String, Object>) list.get(0);
            } else {
                return result; // Return empty map if the list is empty or not a map
            }
        }

        // Iterate through all entries in the target map
        for (Map.Entry<String, Object> entry : targetMap.entrySet()) {
            String fieldName = entry.getKey();
            Object fieldValue = entry.getValue();

            // Check if the field is a list
            if (fieldValue instanceof List) {
                List<?> arrayList = (List<?>) fieldValue;
                List<LivePhoto> photoList = new ArrayList<>();

                // Process each item in the list
                for (Object item : arrayList) {
                    if (item instanceof Map) {
                        Map<String, Object> objectMap = (Map<String, Object>) item;

                        // Check if the object has the required fields
                        if (objectMap.containsKey("duration") &&
                                objectMap.containsKey("fileName") &&
                                objectMap.containsKey("fileSize") &&
                                objectMap.containsKey("fileType") &&
                                objectMap.containsKey("fileUrl") &&
                                objectMap.containsKey("md5") &&
                                objectMap.containsKey("url")) {
                            LivePhoto photo = new LivePhoto();
                            photo.setDuration((String) objectMap.get("duration"));
                            photo.setFileName((String) objectMap.get("fileName"));
                            // Handle fileSize as Number to support both Integer and Long
                            Object fileSize = objectMap.get("fileSize");
                            photo.setFileSize(fileSize instanceof Number ? ((Number) fileSize).longValue() : null);
                            photo.setFileType((String) objectMap.get("fileType"));
                            photo.setFileUrl((String) objectMap.get("fileUrl"));
                            photo.setMd5((String) objectMap.get("md5"));
                            photo.setUrl((String) objectMap.get("url"));
                            // localImgUrl and type are not present in the map, so they remain null
                            photoList.add(photo);
                        }
                    }
                }

                // Add to result if the list is not empty
                if (!photoList.isEmpty()) {
                    result.put(fieldName, photoList);
                }
            }
        }

        return result;
    }
}
