package com.salpa.subject.mapper;

import com.alibaba.fastjson2.JSON;
import com.salpa.subject.domain.*;
import com.salpa.subject.domain.converter.JsonConverter;
import com.salpa.subject.domain.data.*;
import net.sourceforge.plantuml.json.JsonObject;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;

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

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

    @Mapping(target = "databaseName", source = "meta.databaseName")
    @Mapping(target = "schemaName", source = "meta.schemaName")
    @Mapping(target = "isArchive", constant = "false")
    MonitorDatabaseDocument toDatabasePojo(Integer projectId,
                                           DatabaseMeta meta,
                                           Long version);

    MonitorTableDocument toTablePojo(Integer databaseDocumentId,
                                     TableMeta meta);

    default List<MonitorTableColumnDocument> toColumnPojo(Integer databaseDocumentId,
                                                   Integer tableDocumentId,
                                                   List<ColumnMeta> metaList) {
        return metaList.stream()
                .map(meta -> toColumnPojo(databaseDocumentId, tableDocumentId, meta))
                .collect(Collectors.toList());
    }

    default MonitorTableColumnDocument toColumnPojo(Integer databaseDocumentId,
                                     Integer tableDocumentId,
                                     ColumnMeta meta) {
        MonitorTableColumnDocument monitorTableColumnDocument = new MonitorTableColumnDocument();
        monitorTableColumnDocument.setName(meta.getName());
        monitorTableColumnDocument.setType(meta.getType());
        monitorTableColumnDocument.setComment(meta.getComment());
        monitorTableColumnDocument.setAutoIncrement(meta.getAutoIncrement());
        monitorTableColumnDocument.setDataType(meta.getDataType());
        monitorTableColumnDocument.setDecimalDigits(meta.getDecimalDigits());
        monitorTableColumnDocument.setDefaultValue(meta.getDefaultValue());
        monitorTableColumnDocument.setPrimaryKey(meta.getIsPrimaryKey());
        monitorTableColumnDocument.setNullable(meta.getNullable());
        monitorTableColumnDocument.setSize(meta.getSize());
        monitorTableColumnDocument.setDatabaseDocumentId(databaseDocumentId);
        monitorTableColumnDocument.setTableDocumentId(tableDocumentId);
        return monitorTableColumnDocument;
    }

    default List<MonitorTableIndexDocument> toIndexPojo(Integer databaseDocumentId,
                                                 Integer tableDocumentId,
                                                 List<IndexMeta> metaList) {
        return metaList.stream()
                .map(meta -> toIndexPojo(databaseDocumentId, tableDocumentId, meta))
                .collect(Collectors.toList());
    }

    default MonitorTableIndexDocument toIndexPojo(Integer databaseDocumentId,
                                          Integer tableDocumentId,
                                          IndexMeta meta) {
        MonitorTableIndexDocument monitorTableIndexDocument = new MonitorTableIndexDocument();
        monitorTableIndexDocument.setName(meta.getName());
        monitorTableIndexDocument.setUnique(meta.getIsUniqueKey());
        monitorTableIndexDocument.setColumnNameArray(JSON.toJSONString(meta.getColumnNames()));
        monitorTableIndexDocument.setDatabaseDocumentId(databaseDocumentId);
        monitorTableIndexDocument.setTableDocumentId(tableDocumentId);
        return monitorTableIndexDocument;
    }

    default List<MonitorTableTriggerDocument> toTriggerPojo(Integer databaseDocumentId,
                                                     Integer tableDocumentId,
                                                     List<TriggerMeta> metaList) {
        return metaList.stream()
                .map(meta -> toTriggerPojo(databaseDocumentId, tableDocumentId, meta))
                .collect(Collectors.toList());
    }

    default MonitorTableTriggerDocument toTriggerPojo(Integer databaseDocumentId,
                                              Integer tableDocumentId,
                                              TriggerMeta meta) {
        MonitorTableTriggerDocument monitorTableTriggerDocument = new MonitorTableTriggerDocument();
        monitorTableTriggerDocument.setName(meta.getName());
        monitorTableTriggerDocument.setTiming(meta.getTiming());
        monitorTableTriggerDocument.setStatement(meta.getStatement());
        monitorTableTriggerDocument.setManipulation(meta.getManipulation());
        monitorTableTriggerDocument.setTriggerCreateAt(meta.getCreateAt());
        monitorTableTriggerDocument.setDatabaseDocumentId(databaseDocumentId);
        monitorTableTriggerDocument.setTableDocumentId(tableDocumentId);
        return monitorTableTriggerDocument;
    }

    default List<MonitorTableForeignKeyDocument> toForeignKeyPojo(Integer docId,
                                                           Integer tableMetaId,
                                                           List<ForeignKeyMeta> foreignKeys) {
        return foreignKeys.stream()
                .map(key -> toForeignKeyPojo(docId, tableMetaId, key))
                .collect(Collectors.toList());
    }

    default MonitorTableForeignKeyDocument toForeignKeyPojo(Integer databaseDocumentId,
                                                    Integer tableDocumentId,
                                                    ForeignKeyMeta foreignKey) {
        MonitorTableForeignKeyDocument monitorTableForeignKeyDocument = new MonitorTableForeignKeyDocument();
        monitorTableForeignKeyDocument.setKeySeq(foreignKey.getKeySeq());
        monitorTableForeignKeyDocument.setFkName(foreignKey.getFkName());
        monitorTableForeignKeyDocument.setFkTableName(foreignKey.getFkTableName());
        monitorTableForeignKeyDocument.setFkColumnName(foreignKey.getFkColumnName());
        monitorTableForeignKeyDocument.setPkName(foreignKey.getPkName());
        monitorTableForeignKeyDocument.setPkTableName(foreignKey.getPkTableName());
        monitorTableForeignKeyDocument.setPkColumnName(foreignKey.getPkColumnName());
        monitorTableForeignKeyDocument.setDeleteRule(foreignKey.getDeleteRule());
        monitorTableForeignKeyDocument.setUpdateRule(foreignKey.getUpdateRule());
        monitorTableForeignKeyDocument.setDatabaseDocumentId(databaseDocumentId);
        monitorTableForeignKeyDocument.setTableDocumentId(tableDocumentId);
        return monitorTableForeignKeyDocument;
    }
}
