package com.njcn.gather.tool.parsepqdif.service.impl;

import com.njcn.gather.tool.parsepqdif.component.PqdifSecondParseComponent;
import com.njcn.gather.tool.parsepqdif.pojo.vo.PqdifParseResponse;
import com.njcn.gather.tool.parsepqdif.pojo.vo.PqdifRecognizeResultVO;
import com.njcn.gather.tool.parsepqdif.reader.PqdifNativeReader;
import com.njcn.gather.tool.parsepqdif.service.ParsePqdifService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Locale;

@Slf4j
@Service
@RequiredArgsConstructor
public class ParsePqdifServiceImpl implements ParsePqdifService {

    private static final String STATUS_FAILED = "FAILED";
    private static final String DEFAULT_SUFFIX = ".pqd";
    private static final String PQDIF_SUFFIX = ".pqdif";
    private static final String TEMP_DIR_NAME = "cn-tool-pqdif-upload";
    private static final String EMPTY_FILE_MESSAGE = "PQDIF文件不能为空";
    private static final String UNSUPPORTED_FILE_MESSAGE = "仅支持 .pqd 或 .pqdif 格式文件";
    private static final String DEFAULT_FAILED_MESSAGE = "PQDIF解析失败";
    private static final String UNKNOWN_FAILED_REASON = "请检查文件内容或原生解析库状态";

    private final PqdifNativeReader pqdifNativeReader;
    private final PqdifSecondParseComponent pqdifSecondParseComponent;

    @Override
    public PqdifParseResponse parse(MultipartFile pqdifFile) {
        if (pqdifFile == null || pqdifFile.isEmpty()) {
            return failed(null, EMPTY_FILE_MESSAGE);
        }

        String originalFilename = pqdifFile.getOriginalFilename();
        String suffix = getSupportedSuffix(originalFilename);
        if (suffix == null) {
            return failed(originalFilename, UNSUPPORTED_FILE_MESSAGE);
        }

        Path tempFile = null;
        try {
            tempFile = createTempPqdifFile(pqdifFile, suffix);
            return pqdifNativeReader.read(tempFile, originalFilename);
        } catch (Exception e) {
            log.error("PQDIF解析失败，fileName={}", originalFilename, e);
            return failed(originalFilename, buildFailedMessage(e));
        } finally {
            deleteTempFile(tempFile);
        }
    }

    @Override
    public PqdifRecognizeResultVO parseRecognizable(PqdifParseResponse parseResponse) {
        return pqdifSecondParseComponent.parseRecognizableData(parseResponse);
    }

    private Path createTempPqdifFile(MultipartFile pqdifFile, String suffix) throws Exception {
        // 原生解析库只接收文件路径，因此上传内容需先落到系统临时目录。
        Path uploadDir = Paths.get(System.getProperty("java.io.tmpdir"), TEMP_DIR_NAME);
        Files.createDirectories(uploadDir);

        Path tempFile = Files.createTempFile(uploadDir, "parse-pqdif-", suffix);
        try (InputStream inputStream = pqdifFile.getInputStream()) {
            Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
        }
        return tempFile;
    }

    private void deleteTempFile(Path tempFile) {
        if (tempFile == null) {
            return;
        }
        try {
            Files.deleteIfExists(tempFile);
        } catch (Exception e) {
            log.warn("删除PQDIF临时文件失败，path={}", tempFile, e);
        }
    }

    private String getSupportedSuffix(String originalFilename) {
        if (originalFilename == null || originalFilename.trim().isEmpty()) {
            return null;
        }

        int index = originalFilename.lastIndexOf('.');
        if (index < 0 || index == originalFilename.length() - 1) {
            return null;
        }

        String suffix = originalFilename.substring(index).toLowerCase(Locale.ROOT);
        if (DEFAULT_SUFFIX.equals(suffix) || PQDIF_SUFFIX.equals(suffix)) {
            return suffix;
        }
        return null;
    }

    private String resolveErrorMessage(Exception e) {
        String message = e.getMessage();
        if (message == null || message.trim().isEmpty()) {
            return UNKNOWN_FAILED_REASON;
        }
        return message;
    }

    private String buildFailedMessage(Exception e) {
        return DEFAULT_FAILED_MESSAGE + "：" + resolveErrorMessage(e);
    }

    private PqdifParseResponse failed(String fileName, String message) {
        PqdifParseResponse response = new PqdifParseResponse();
        response.setStatus(STATUS_FAILED);
        response.setMessage(message == null ? DEFAULT_FAILED_MESSAGE : message);
        response.setFileName(fileName);
        response.setRecordCount(0L);
        response.setObservationCount(0L);
        response.setSampleValueCount(0);
        response.setRecords(new ArrayList<PqdifParseResponse.RecordInfoVO>());
        response.setObservations(new ArrayList<PqdifParseResponse.ObservationVO>());
        return response;
    }
}
