package org.jeecg.modules.okki.translate.service;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.okki.translate.dto.RransResultBaidu;
import org.jeecg.modules.okki.translate.dto.TransRresultSigle;
import org.jeecg.modules.okki.translate.dto.TranslateRequestDto;
import org.jeecg.modules.okki.translate.dto.TranslateResults;
import org.jeecg.modules.okki.translate.tools.TransBaiduApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.concurrent.*;

@Slf4j
@Service
public class TranslateService {

    @Autowired
    private TransBaiduApi transBaiduApi;

    public static final Map<String, String> LANGUAGE_MAP;

    private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    public TranslateResults doTranslate(TranslateRequestDto translateRequestDto) throws UnsupportedEncodingException {
        // TODO 站点信息校验

        // 将OK语言码转换为百度语言代码
        translateRequestDto.setToBaiduCode(new ArrayList<>());
        translateRequestDto.setFremBaiduCode(LANGUAGE_MAP.get(translateRequestDto.getFrom()));
        for (int i = 0; i < translateRequestDto.getTo().size(); i++) {
            translateRequestDto.getToBaiduCode().add(LANGUAGE_MAP.get(translateRequestDto.getTo().get(i)));
        }

        String fromLanguage = translateRequestDto.getFrom();
        List<String> targetLanguages = translateRequestDto.getTo();
        Map<String, String> contents = translateRequestDto.getContents();

        TranslateResults results = new TranslateResults();
        Map<String, Map<String, String>> translatedInfo = new ConcurrentHashMap<>();

        List<Future<Void>> futures = new ArrayList<>();

        // 预解码所有内容
        Map<String, String> decodedContents = new HashMap<>();
        for (Map.Entry<String, String> entry : contents.entrySet()) {
            decodedContents.put(entry.getKey(), new String(Base64.getDecoder().decode(entry.getValue())));
        }

        for (String targetLanguage : targetLanguages) {
            for (Map.Entry<String, String> entry : decodedContents.entrySet()) {
                futures.add(executorService.submit(() -> {
                    processTranslation(entry.getKey(), entry.getValue(), fromLanguage, targetLanguage, LANGUAGE_MAP.get(fromLanguage), LANGUAGE_MAP.get(targetLanguage), translatedInfo, contents.get(entry.getKey()));
                    return null;
                }));
            }
        }

        // 等待所有任务完成
        for (Future<Void> future : futures) {
            try {
                future.get();
            } catch (InterruptedException | ExecutionException e) {
                log.error("翻译任务执行出错", e);
                Thread.currentThread().interrupt();  // 处理中断
            }
        }

        results.setMsg("successful");
        results.setData(translatedInfo);

        return results;
    }

    private void processTranslation(String key, String decodedSrc, String fromLanguage, String targetLanguage , String fromLanguageTransCode,  String targetLanguageTransCode, Map<String, Map<String, String>> translatedInfo, String originalValue) {
        try {
            String transObj = transBaiduApi.getTransResult(decodedSrc, fromLanguageTransCode, targetLanguageTransCode);

            RransResultBaidu resultBaidu = JSON.parseObject(transObj, RransResultBaidu.class);

            if (resultBaidu.getErrorCode() == null && !resultBaidu.getTransResult().isEmpty()) {
                for (TransRresultSigle singleResult : resultBaidu.getTransResult()) {
                    String encodedDst = Base64.getEncoder().encodeToString(singleResult.getDst().getBytes());

                    Map<String, String> trans = translatedInfo.computeIfAbsent(key, k -> new HashMap<>());
                    trans.put(targetLanguage, encodedDst);
                    trans.put("_original", originalValue);
                }
            } else {
                log.error("调用百度翻译发生错误！error_code:{} error_msg:{}", resultBaidu.getErrorCode(), resultBaidu.getErrorMsg());
            }
        } catch (Exception e) {
            log.error("处理翻译时发生异常", e);
        }
    }


    static {
        LANGUAGE_MAP = new HashMap<>();
        LANGUAGE_MAP.put("en", "en");
        LANGUAGE_MAP.put("ar", "ara");
        LANGUAGE_MAP.put("bg", "bul");
        LANGUAGE_MAP.put("hr", "hrv");
        LANGUAGE_MAP.put("cs", "cs");
        LANGUAGE_MAP.put("da", "dan");
        LANGUAGE_MAP.put("nl", "nl");
        LANGUAGE_MAP.put("fi", "fin");
        LANGUAGE_MAP.put("fr", "fra");
        LANGUAGE_MAP.put("de", "de");
        LANGUAGE_MAP.put("el", "el");
        LANGUAGE_MAP.put("hi", "hi");
        LANGUAGE_MAP.put("it", "it");
        LANGUAGE_MAP.put("ja", "jp");
        LANGUAGE_MAP.put("ko", "kor");
        LANGUAGE_MAP.put("no", "nor");
        LANGUAGE_MAP.put("pl", "pl");
        LANGUAGE_MAP.put("pt", "pt");
        LANGUAGE_MAP.put("ro", "rom");
        LANGUAGE_MAP.put("ru", "ru");
        LANGUAGE_MAP.put("es", "spa");
        LANGUAGE_MAP.put("sv", "swe");
        LANGUAGE_MAP.put("ca", "cat");
        LANGUAGE_MAP.put("tl", "fil");
        LANGUAGE_MAP.put("iw", "heb");
        LANGUAGE_MAP.put("id", "id");
        LANGUAGE_MAP.put("lv", "lav");
        LANGUAGE_MAP.put("lt", "lit");
        LANGUAGE_MAP.put("sr", "srp");
        LANGUAGE_MAP.put("sk", "sk");
        LANGUAGE_MAP.put("sl", "slo");
        LANGUAGE_MAP.put("uk", "ukr");
        LANGUAGE_MAP.put("vi", "vie");
        LANGUAGE_MAP.put("sq", "alb");
        LANGUAGE_MAP.put("et", "est");
        LANGUAGE_MAP.put("gl", "glg");
        LANGUAGE_MAP.put("hu", "hu");
        LANGUAGE_MAP.put("mt", "mlt");
        LANGUAGE_MAP.put("th", "th");
        LANGUAGE_MAP.put("tr", "tr");
        LANGUAGE_MAP.put("fa", "per");
        LANGUAGE_MAP.put("af", "afr");
        LANGUAGE_MAP.put("ms", "may");
        LANGUAGE_MAP.put("sw", "swa");
        LANGUAGE_MAP.put("ga", "gle");
        LANGUAGE_MAP.put("cy", "wel");
        LANGUAGE_MAP.put("be", "bel");
        LANGUAGE_MAP.put("is", "ice");
        LANGUAGE_MAP.put("mk", "mac");
        LANGUAGE_MAP.put("yi", "yid");
        LANGUAGE_MAP.put("hy", "arm");
        LANGUAGE_MAP.put("az", "aze");
        LANGUAGE_MAP.put("eu", "baq");
        LANGUAGE_MAP.put("ka", "geo");
        LANGUAGE_MAP.put("ht", "ht");
        LANGUAGE_MAP.put("ur", "urd");
        LANGUAGE_MAP.put("bn", "ben");
        LANGUAGE_MAP.put("bs", "bos");
        LANGUAGE_MAP.put("ceb", "ceb");
        LANGUAGE_MAP.put("eo", "epo");
        LANGUAGE_MAP.put("gu", "guj");
        LANGUAGE_MAP.put("ha", "hau");
        LANGUAGE_MAP.put("hmn", "hmn");
        LANGUAGE_MAP.put("ig", "ibo");
        LANGUAGE_MAP.put("jw", "jav");
        LANGUAGE_MAP.put("kn", "kan");
        LANGUAGE_MAP.put("km", "hkm");
        LANGUAGE_MAP.put("lo", "lao");
        LANGUAGE_MAP.put("la", "lat");
        LANGUAGE_MAP.put("mi", "mao");
        LANGUAGE_MAP.put("mr", "mar");
        LANGUAGE_MAP.put("mn", "mn");
        LANGUAGE_MAP.put("ne", "nep");
        LANGUAGE_MAP.put("pa", "pan");
        LANGUAGE_MAP.put("so", "som");
        LANGUAGE_MAP.put("ta", "tam");
        LANGUAGE_MAP.put("te", "tel");
        LANGUAGE_MAP.put("yo", "yor");
        LANGUAGE_MAP.put("zu", "zul");
        LANGUAGE_MAP.put("my", "bur");
        LANGUAGE_MAP.put("ny", "nya");
        LANGUAGE_MAP.put("kk", "NAN");
        LANGUAGE_MAP.put("mg", "NAN");
        LANGUAGE_MAP.put("ml", "mal");
        LANGUAGE_MAP.put("si", "sin");
        LANGUAGE_MAP.put("st", "sot");
        LANGUAGE_MAP.put("su", "NAN");
        LANGUAGE_MAP.put("tg", "tgk");
        LANGUAGE_MAP.put("uz", "NAN");
        LANGUAGE_MAP.put("am", "amh");
        LANGUAGE_MAP.put("co", "cos");
        LANGUAGE_MAP.put("haw", "haw");
        LANGUAGE_MAP.put("ku", "kur");
        LANGUAGE_MAP.put("ky", "kir");
        LANGUAGE_MAP.put("lb", "ltz");
        LANGUAGE_MAP.put("ps", "pus");
        LANGUAGE_MAP.put("sm", "sm");
        LANGUAGE_MAP.put("gd", "gla");
        LANGUAGE_MAP.put("sn", "sna");
        LANGUAGE_MAP.put("sd", "snd");
        LANGUAGE_MAP.put("fy", "fry");
        LANGUAGE_MAP.put("xh", "xho");
    }
}
