package com.oguerreiro.resilient.service.mapper;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;

import com.oguerreiro.resilient.domain.DashboardComponent;
import com.oguerreiro.resilient.domain.DashboardComponentDetail;
import com.oguerreiro.resilient.domain.DashboardComponentDetailValue;
import com.oguerreiro.resilient.domain.Organization;
import com.oguerreiro.resilient.domain.Variable;
import com.oguerreiro.resilient.service.dto.DashboardComponentDTO;
import com.oguerreiro.resilient.service.dto.DashboardComponentDetailDTO;
import com.oguerreiro.resilient.service.dto.DashboardComponentDetailValueDTO;
import com.oguerreiro.resilient.service.dto.OrganizationDTO;
import com.oguerreiro.resilient.service.dto.VariableDTO;

/**
 * Mapper for the entity {@link DashboardComponentDetailValue} and its DTO {@link DashboardComponentDetailValueDTO}.
 */
@Mapper(componentModel = "spring")
public interface DashboardComponentDetailValueMapper {
  // extends ResilientEntityMapper<DashboardComponentDetailValueDTO, DashboardComponentDetailValue> {
  @Mapping(target = "dashboardComponentDetail", source = "dashboardComponentDetail", qualifiedByName = "dashboardComponentDetailPropertyName")
  @Mapping(target = "targetDashboardComponent", source = "targetDashboardComponent", qualifiedByName = "targetDashboardComponentPropertyName")
  @Mapping(target = "organization", source = "owner", qualifiedByName = "organizationPropertyName")
  DashboardComponentDetailValueDTO toDto(DashboardComponentDetailValue dashboardComponentDetailValue);

  @Named("dashboardComponentDetailPropertyName")
  @BeanMapping(ignoreByDefault = true)
  @Mapping(target = "id", source = "id")
  @Mapping(target = "name", source = "name")
  @Mapping(target = "color", source = "color")
  @Mapping(target = "help", source = "help")
  @Mapping(target = "variable", source = "variable", qualifiedByName = "variablePropertyName")
  DashboardComponentDetailDTO toDtoDashboardComponentDetailPropertyName(
      DashboardComponentDetail dashboardComponentDetail);

  @Named("targetDashboardComponentPropertyName")
  @BeanMapping(ignoreByDefault = true)
  @Mapping(target = "id", source = "id")
  DashboardComponentDTO toDtoTargetDashboardComponentPropertyName(DashboardComponent targetDashboardComponent);

  @Named("variablePropertyName")
  @BeanMapping(ignoreByDefault = true)
  @Mapping(target = "id", source = "id")
  VariableDTO toDtoVariablePropertyName(Variable variable);

  @Named("organizationPropertyName")
  @BeanMapping(ignoreByDefault = true)
  @Mapping(target = "id", source = "id")
  @Mapping(target = "code", source = "code")
  OrganizationDTO toDtoOrganizationPropertyName(Organization organization);

  default Map<String, List<DashboardComponentDetailValueDTO>> mapToDto(
      Map<String, List<DashboardComponentDetailValue>> entityMap) {
    Map<String, List<DashboardComponentDetailValueDTO>> newMap = new LinkedHashMap<String, List<DashboardComponentDetailValueDTO>>();

    for (Entry<String, List<DashboardComponentDetailValue>> entry : entityMap.entrySet()) {
      List<DashboardComponentDetailValueDTO> details = new ArrayList<DashboardComponentDetailValueDTO>();

      for (DashboardComponentDetailValue dashboardComponentDetailValue : entry.getValue()) {
        details.add(toDto(dashboardComponentDetailValue));
      }

      newMap.put(entry.getKey(), details);
    }

    return newMap;
  }
}
