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 GutdfFidPassportOgrnFileAggregator 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 GutdfFidPassportOgrnFileAggregator(ApplicationSettings settings,
                                              FileAggregatorCommon fileAggregatorCommon) {
        this.settings = settings;
        this.fileAggregatorCommon = fileAggregatorCommon;
    }

    @Override
    public Path aggregateFiles(UUID taskId,
                               DataType dataType,
                               SearchParameter searchParameter,
                               String searchValue,
                               String memberCode,
                               Map<String, Path> tableFileMap,
                               MutableLong rowCounter) {
        if (dataType == DataType.GUTDF || dataType == DataType.RUTDF) {
            if (searchParameter == SearchParameter.FID || searchParameter == SearchParameter.OGRN || searchParameter == SearchParameter.PASSPORT) {
                Path aggregatedFile = settings.getStorageDirectory().toPath().resolve("AGGREGATED-" + taskId + ".csv");

                try (BufferedWriter aggregatedFileWriter = Files.newBufferedWriter(aggregatedFile, StandardOpenOption.CREATE, StandardOpenOption.APPEND)) {
                    for (String tableName : REQUIRED_TABLES) {
                        if (tableName.equals("RU_UID")) {
                            fileAggregatorCommon.aggregateRuUidFiles(aggregatedFileWriter, tableFileMap, memberCode, null, null, 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;
            }
        }

        return null;
    }
}
