package ru.nbch.indicsearchservice.filter.thirdlevel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.stereotype.Component;
import ru.nbch.indicsearchservice.model.TableData;

@Component
public class BlocksThirdLevelTableFilter implements ThirdLevelTableFilter {
    private static final Set<String> SUPPORTED_TABLE_NAMES = Set.of(
        "RU_COLLATERAL_BLOCKS",
        "RU_BANKRUPTCY_BLOCKS"
    );

    @Override
    public void applyFilter(List<TableData> firstLevelTableDataList, Map<String, List<TableData>> tableDataMapByFid) {
        if (firstLevelTableDataList == null || firstLevelTableDataList.isEmpty() || tableDataMapByFid == null) {
            return;
        }

        Map<String, Map<Object, List<TableData>>> childTablesByParentAndSerial = new HashMap<>();

        for (String tableName : SUPPORTED_TABLE_NAMES) {
            String parentTableName = tableName.replace("_BLOCKS", "");
            String childTableName = tableName;

            List<TableData> childTables = tableDataMapByFid.get(childTableName);

            if (childTables != null) {
                Map<Object, List<TableData>> groupedChildTables = new HashMap<>();
                for (TableData childTable : childTables) {
                    Object parentSerialNum = getFieldValue(childTable, "PARENT_SERIAL_NUM");
                    if (parentSerialNum != null) {
                        groupedChildTables
                            .computeIfAbsent(parentSerialNum, k -> new ArrayList<>())
                            .add(childTable);
                    }
                }
                childTablesByParentAndSerial.put(parentTableName, groupedChildTables);
            }
        }

        for (TableData firstLevelTable : firstLevelTableDataList) {
            if (firstLevelTable.getRelatedTableData() == null) {
                continue;
            }

            for (TableData secondLevelTable : firstLevelTable.getRelatedTableData()) {
                String tableName = secondLevelTable.getTableName();

                String parentTableName = tableName;
                String childTableName = tableName + "_BLOCKS";

                if (SUPPORTED_TABLE_NAMES.contains(childTableName)) {
                    Map<Object, List<TableData>> availableChildTables = childTablesByParentAndSerial.get(parentTableName);

                    if (availableChildTables != null) {
                        Object serialNum = getFieldValue(secondLevelTable, "SERIAL_NUM");

                        if (serialNum != null) {
                            List<TableData> matchingChildTables = availableChildTables.get(serialNum);
                            if (matchingChildTables != null) {
                                secondLevelTable.getRelatedTableData().addAll(matchingChildTables);
                            }
                        }
                    }
                }
            }
        }
    }

    private Object getFieldValue(TableData tableData, String targetColumnName) {
        if (tableData.getFieldData() == null) {
            return null;
        }

        for (TableData.FieldData field : tableData.getFieldData()) {
            if (targetColumnName.equals(field.columnName())) {
                return field.columnValue();
            }
        }

        return null;
    }
}
