package ru.nbch.indicsearchservice.loader;

import java.io.IOException;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.ibatis.cursor.Cursor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import ru.nbch.indicsearchservice.model.enums.DataType;
import ru.nbch.indicsearchservice.model.enums.SearchParameter;
import ru.nbch.indicsearchservice.util.MapperHolder;

@Component
public class IdTableLoader implements FirstLevelTableLoader {
    private final MapperHolder mapperHolder;
    private final List<TableLoaderForId> tableLoaders;

    public IdTableLoader(MapperHolder mapperHolder,
                         List<TableLoaderForId> tableLoaders) {
        this.mapperHolder = mapperHolder;
        this.tableLoaders = tableLoaders;
    }

    @Override
    public String getTableName() {
        return "ID";
    }

    @Override
    @Transactional(readOnly = true)
    public void searchBy(UUID taskId, DataType dataType, SearchParameter searchParameter, String searchValue, String memberCode, Map<String, Path> tableFileMap) {
        if (dataType == DataType.GUTDF || dataType == DataType.RUTDF) {
            if (searchParameter == SearchParameter.OGRN || searchParameter == SearchParameter.PASSPORT) {
                Set<Integer> foundFids = new HashSet<>();

                try (Cursor<LinkedHashMap<String, Object>> cursor = searchParameter == SearchParameter.OGRN ?
                    mapperHolder.getIndicMapper().findFidsByOgrnFromId(searchValue) :
                    mapperHolder.getIndicMapper().findFidsByPassportFromId(searchValue)) {
                    for (LinkedHashMap<String, Object> row : cursor) {
                        for (Map.Entry<String, Object> entry : row.entrySet()) {
                            String columnName = entry.getKey();
                            Object columnValue = entry.getValue();

                            if (columnName != null && columnValue != null) {
                                if (columnName.equals("FID")) {
                                    foundFids.add(Integer.parseInt(columnValue.toString()));
                                }
                            }
                        }
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

                tableLoaders.parallelStream().forEach(tl -> tl.searchById(
                    taskId,
                    dataType,
                    searchParameter,
                    foundFids,
                    memberCode,
                    tableFileMap
                ));
            }
        }
    }
}
