package com.salpa.subject.mapper;

import com.salpa.subject.domain.MonitorDatabaseDocument;
import com.salpa.subject.domain.MonitorTableDocument;
import com.salpa.subject.domain.converter.JsonConverter;
import com.salpa.subject.domain.data.DatabaseDocumentSimpleResponse;
import com.salpa.subject.domain.diff.TableDocDiff;
import com.salpa.subject.domain.diff.data.DiffType;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Mapper(componentModel = "spring", uses = JsonConverter.class, unmappedTargetPolicy = ReportingPolicy.WARN)
public interface DocumentSimpleResponseConverter {

    @Mapping(target = "id", source = "database.id")
    @Mapping(target = "createAt", source = "database.createAt")
    @Mapping(target = "documentVersion", source = "database.version")
    DatabaseDocumentSimpleResponse of(MonitorDatabaseDocument database, List<TableDocDiff> tables, String projectName);

    default DatabaseDocumentSimpleResponse of(MonitorDatabaseDocument databaseDocument,
                                      List<DatabaseDocumentSimpleResponse.TableData> tables,
                                      DiffType diffType,
                                      String projectName) {
        DatabaseDocumentSimpleResponse databaseDocumentSimpleResponse = new DatabaseDocumentSimpleResponse();
        databaseDocumentSimpleResponse.setTables(tables);
        databaseDocumentSimpleResponse.setDiffType(diffType);
        databaseDocumentSimpleResponse.setProductName(databaseDocument.getProductName());
        databaseDocumentSimpleResponse.setId(databaseDocument.getId());
        databaseDocumentSimpleResponse.setSchemaName(databaseDocument.getSchemaName());
        databaseDocumentSimpleResponse.setDatabaseName(databaseDocument.getDatabaseName());
        databaseDocumentSimpleResponse.setProjectName(projectName);
        databaseDocumentSimpleResponse.setProductVersion(databaseDocument.getProductVersion());
        databaseDocumentSimpleResponse.setDocumentVersion(databaseDocument.getDocumentVersion());
        databaseDocumentSimpleResponse.setCreateAt(databaseDocument.getCreateAt());
        return databaseDocumentSimpleResponse;
    }

    default DatabaseDocumentSimpleResponse.TableData of(MonitorTableDocument tables,
                                                Integer discussionCount,
                                                String description) {
        DatabaseDocumentSimpleResponse.TableData tableData = new DatabaseDocumentSimpleResponse.TableData();
        tableData.setId(tables.getId());
        tableData.setName(tables.getName());
        tableData.setComment(tables.getComment());
        tableData.setType(tables.getType());
        tableData.setDescription(description);
        tableData.setDiscussionCount(discussionCount);
        return tableData;
    }

    default List<DatabaseDocumentSimpleResponse.TableData> of(List<MonitorTableDocument> tables,
                                                              Map<String, Integer> discussionCountMapByTableName,
                                                              Map<String, String> descriptionMapByTableName) {
        return tables.stream()
                .map(table -> {
                    Integer count = discussionCountMapByTableName.get(table.getName());
                    String description = descriptionMapByTableName.get(table.getName());
                    return of(table, count, description);
                })
                .collect(Collectors.toList());
    }

    default List<DatabaseDocumentSimpleResponse.TableData> ofDiff(List<TableDocDiff> tables,
                                                                  Map<String, Integer> discussionCountMapByTableName,
                                                                  Map<String, String> descriptionMapByTableName) {
        return tables.stream()
                .map(tableDocDiff -> {
                    String tableName = tableDocDiff.getName();
                    Integer count = discussionCountMapByTableName.get(tableName);
                    String description = descriptionMapByTableName.get(tableName);
                    return ofDiff(tableDocDiff, count, description);
                })
                .collect(Collectors.toList());
    }

    default DatabaseDocumentSimpleResponse.TableData ofDiff(TableDocDiff table,
                                                    Integer discussionCount,
                                                    String description) {
        DatabaseDocumentSimpleResponse.TableData tableData = new DatabaseDocumentSimpleResponse.TableData();
        tableData.setDiscussionCount(discussionCount);
        tableData.setDescription(description);
        tableData.setId(table.getId());
        tableData.setName(table.getName());
        tableData.setType(table.getType());
        tableData.setComment(table.getComment());
        tableData.setDiffType(table.getDiffType());
        return tableData;
    }
}
