package ru.nbch.indicsearchservice.aggregator;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import org.apache.commons.lang3.mutable.MutableLong;
import org.springframework.stereotype.Component;
import ru.nbch.indicsearchservice.config.settings.ApplicationSettings;
import ru.nbch.indicsearchservice.model.enums.DataType;
import ru.nbch.indicsearchservice.model.enums.SearchParameter;
import ru.nbch.indicsearchservice.util.IndicSearchCommon;

@Component
public class GutdfFidFileAggregator implements FileAggregator {
    private static final List<String> REQUIRED_TABLES = List.of(
        "RU_UID",
        "RU_APPLICATION",
        "RU_OBLIGPARTTAKE",
        "RU_BANKRUPTCY",
        "RU_SETTLED",
        "RU_OTHERLEGAL",
        "RU_CAPABILITY",
        "RU_DEBT_BURDEN_INFO"
    );

    private final ApplicationSettings settings;
    private final FileAggregatorCommon fileAggregatorCommon;

    public GutdfFidFileAggregator(ApplicationSettings settings,
                                  FileAggregatorCommon fileAggregatorCommon) {
        this.settings = settings;
        this.fileAggregatorCommon = fileAggregatorCommon;
    }

    @Override
    public List<DataType> getSuitableDataTypes() {
        return List.of(DataType.GUTDF, DataType.RUTDF);
    }

    @Override
    public List<SearchParameter> getSuitableSearchParameters() {
        return List.of(SearchParameter.FID);
    }

    @Override
    public List<String> getRequiredTables() {
        return REQUIRED_TABLES;
    }

    @Override
    public Path aggregateFiles(Map<String, Path> tableFileMap, String memberCode, MutableLong rowCounter, UUID taskId) {
        Path aggregatedFile = settings.getStorageDirectory().toPath().resolve("AGGREGATED-" + taskId + ".csv");

        try (BufferedWriter aggregatedFileWriter = Files.newBufferedWriter(aggregatedFile, StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {
            for (String tableName : getRequiredTables()) {
                if (tableName.equals("RU_UID")) {
                    fileAggregatorCommon.aggregateRuUidFiles(aggregatedFileWriter, tableFileMap, memberCode, rowCounter);
                } else if (tableName.equals("RU_BANKRUPTCY")) {
                    fileAggregatorCommon.aggregateBlocksTableFile(tableName, aggregatedFileWriter, tableFileMap, memberCode, rowCounter);
                } else {
                    try (BufferedReader reader = Files.newBufferedReader(tableFileMap.get(tableName))) {
                        String line;

                        while ((line = reader.readLine()) != null) {
                            Optional<String> foundMemberCode = IndicSearchCommon.getRowValue(line, "MEMBER_CODE");

                            if (foundMemberCode.isPresent() && !foundMemberCode.get().startsWith(memberCode)) {
                                continue;
                            }

                            aggregatedFileWriter.write(line);
                            aggregatedFileWriter.newLine();
                            rowCounter.increment();
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }

            aggregatedFileWriter.write("EOF");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return aggregatedFile;
    }
}
