package com.yingpaipay.business.service.impl;

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.yingpaipay.business.domain.bo.AppletScanBo;
import com.yingpaipay.business.domain.dto.TextInR;
import com.yingpaipay.business.service.ITextInService;
import com.yingpaipay.common.file.config.TextInConfig;
import com.yingpaipay.setting.domain.vo.TextinSettingVo;
import com.yingpaipay.setting.service.ITextinSettingService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.message.Message;
import org.dromara.common.core.exception.BusinessException;
import org.dromara.common.core.utils.MessageUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.jspecify.annotations.NonNull;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

@Service
@RequiredArgsConstructor
@Slf4j
public class TextInServiceImpl implements ITextInService {

    private final TextInConfig config;

    private final ITextinSettingService settingService;

    private HttpResponse getResponse(HttpRequest request) {
        TextinSettingVo setting = settingService.query();
        HttpResponse response = request.header("x-ti-app-id", setting.getAppId())
            .header("x-ti-secret-code", setting.getSecretCode())
            .execute();
        return response;
    }

    @Override
    public String imageToPdf(AppletScanBo bo) {

        HttpResponse response = getResponse(
            HttpRequest.post(config.getImageToPdf()).body(JsonUtils.toJsonString(bo))
        );

        TextInR result = getR(response);

        return result.getResult().toString();

    }

    private static @NonNull TextInR getR(HttpResponse response) {
        if (response.getStatus() != 200) {
            throw new BusinessException(MessageUtils.message("textin.networkerror"));
        }
        String body = response.body();
        TextInR result = JsonUtils.parseObject(body, TextInR.class);
        if (result == null) {
            throw new BusinessException(MessageUtils.message("textin.recognitionfail"));
        }
        if (result.getCode() != 200) {
            throw new RuntimeException(result.getMessage());
        }
        return result;
    }

    @Override
    public String imageToWord(String image) {

        HttpResponse response = getResponse(
            HttpRequest.post(config.getImageToWord())
                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                .body(Base64.getDecoder().decode(image))
        );

        TextInR result = getR(response);

        return JsonUtils.parseMap(JsonUtils.toJsonString(result.getResult())).getStr("docx");
    }

    @Override
    public String wordToImage(String docx) {

        HttpResponse response = getResponse(
            HttpRequest.post(config.getWordToImage())
                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                .body(docx)
        );

        TextInR result = getR(response);
        String zipBase64 = result.getResult().toString();

        if (zipBase64.contains(",")) {
            zipBase64 = zipBase64.substring(zipBase64.indexOf(",") + 1);
        }

        try {
            byte[] zipData = Base64.getDecoder().decode(zipBase64);

            Path tempDir = Files.createTempDirectory("word_to_image_");

            try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipData))) {
                ZipEntry entry;
                while ((entry = zis.getNextEntry()) != null) {
                    String name = entry.getName();
                    if (name.contains("..")) {
                        continue; // 跳过非法路径
                    }

                    Path filePath = tempDir.resolve(name).normalize();

                    Files.createDirectories(filePath.getParent());

                    if (!entry.isDirectory()) {
                        try (OutputStream fos = Files.newOutputStream(filePath)) {
                            byte[] buffer = new byte[8192];
                            int len;
                            while ((len = zis.read(buffer)) > 0) {
                                fos.write(buffer, 0, len);
                            }
                        }
                    }
                    zis.closeEntry();
                }
            }

        } catch (IllegalArgumentException e) {
            throw new RuntimeException("BASE64 格式无效", e);
        } catch (IOException e) {
            throw new RuntimeException("解压失败", e);
        }

        return "";
    }

    @Override
    public String wordToPdf(String docx) {

        HttpResponse response = getResponse(
            HttpRequest.post(config.getWordToPdf())
                .header(Header.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
                .body(Base64.getDecoder().decode(docx))
        );

        TextInR result = getR(response);

        return result.getResult().toString();
    }

}
