package ru.nbch.indicsearchservice.util;

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.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import org.apache.ibatis.cursor.Cursor;
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;

@Component
public class IndicSearchUtils {
    private final ApplicationSettings settings;

    public IndicSearchUtils(ApplicationSettings settings) {
        this.settings = settings;
    }

    public Path writeRowsToFile(String tableName,
                                Set<Integer> fids,
                                Function<Set<Integer>, Cursor<LinkedHashMap<String, Object>>> mapperFunc,
                                UUID taskId) {
        Path resultFile = settings.getStorageDirectory().toPath().resolve(tableName + "_" + taskId + ".csv");

        try (BufferedWriter writer = Files.newBufferedWriter(resultFile, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
             Cursor<LinkedHashMap<String, Object>> cursor = mapperFunc.apply(fids)) {
            for (LinkedHashMap<String, Object> row : cursor) {
                StringBuilder sb = new StringBuilder();
                sb.append(tableName).append(";");

                for (Map.Entry<String, Object> entry : row.entrySet()) {
                    String columnName = entry.getKey();
                    Object columnValue = entry.getValue();

                    sb.append(columnName.toUpperCase()).append(";");

                    if (columnValue != null) {
                        sb.append(columnValue).append(";");
                    } else {
                        sb.append(";");
                    }
                }

                sb.deleteCharAt(sb.length() - 1);
                writer.write(sb.toString());
                writer.newLine();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return resultFile;
    }

    public Set<Integer> getFidsBasedOnDataTypeAndSearchParameter(DataType dataType, SearchParameter searchParameter, String searchValue) {
        Set<Integer> fids = new HashSet<>();

        if (dataType == null || searchParameter == null) {
            return fids;
        }

        if (dataType == DataType.GUTDF || dataType == DataType.RUTDF) {
            if (searchParameter == SearchParameter.FID) {
                return Set.of(Integer.parseInt(searchValue));
            }
        } else if (dataType == DataType.TUTDF) {
            if (searchParameter == SearchParameter.FID) {
                return Set.of(Integer.parseInt(searchValue));
            }
        }

        return fids;
    }
}
