package ru.ibs.socrates.confexporter.dao.mapper;

import java.time.OffsetDateTime;
import java.util.Optional;
import java.util.UUID;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import ru.ibs.socrates.confexporter.dao.dto.ContentDaoDto;
import ru.ibs.socrates.confexporter.dao.entity.MessageEntity;
import ru.ibs.socrates.confexporter.dao.entity.ProjectEntity;
import ru.ibs.socrates.confexporter.dao.entity.TextContentEntity;
import ru.ibs.socrates.confexporter.service.content.utils.UuidMapper;

/**
 * Маппер для взаимодействия с базой данных.
 */
@Mapper(uses = {UuidMapper.class})
public interface ContentDaoMapper {
  
  /**
   * Маппинг создания экземпляра ContentDaoDto.
   * 
   * @param messageEntity
   * @return
   */
  @Mapping(target = "contentId.entityId", source = "id") // типизированный id
  @Mapping(target = "projectSourceId", source = "project.sourceId")
  @Mapping(target = "projectTitle", source = "project.title")
  @Mapping(target = "projectComment", source = "project.comment")
  ContentDaoDto toContentDto(MessageEntity messageEntity);
  
  /**
   * Маппинг создания экземпляра ContentDaoDto.
   * 
   * @param messageEntity
   * @return
   */
  @Mapping(target = "contentId.entityId", source = "messageEntity.id")
  @Mapping(target = "updated", source = "messageEntity.updated")
  @Mapping(target = "text", source = "textContentEntity.text")
  @Mapping(target = "link", source = "textContentEntity.link")
  ContentDaoDto toContentDto(MessageEntity messageEntity,
      TextContentEntity textContentEntity);
  
  /**
   * Маппинг создания экземпляра ContentEntity.
   * 
   * @param contentDaoDto
   * @return
   */
  @Mapping(target = "id", ignore = true)
  @Mapping(target = "created", ignore = true)
  @Mapping(target = "updated", ignore = true)
  @Mapping(target = "contentSize", ignore = true)
  @Mapping(target = "project.sourceId", source = "projectSourceId")
  MessageEntity toContentEntity(ContentDaoDto contentDaoDto);
  
  /**
   * Маппинг получения названия проекта. 
   * @param project
   * @return
   */
  default String toProjectSourceId(ProjectEntity project) {
    return Optional.of(project)
        .map(ProjectEntity::getSourceId)
        .map(UUID::toString)
        .get();
  }
  
  /**
   * Обогощает messageEntity по данным contentCreate.
   *  
   * @param messageEntity
   * @param contentCreate
   */
  default void updateContentEntity(
      MessageEntity messageEntity, ContentDaoDto contentCreate) {
    messageEntity.getContentEntity().setText(contentCreate.getText());
    messageEntity.getContentEntity().setLink(contentCreate.getLink());
    messageEntity.setContentType(contentCreate.getContentType());
    messageEntity.setUpdated(OffsetDateTime.now());
    messageEntity.getProject().setUpdated(OffsetDateTime.now());
  }
  
  /**
   * Маппинг создания сущности ContentEntity из ContentDaoDto.
   * 
   * @param contentCreate
   * @return
   */
  default MessageEntity createContentEntity(
      ContentDaoDto contentCreate, ProjectEntity projectEntity) {
    TextContentEntity textContentEntity = TextContentEntity.builder()
        .text(contentCreate.getText())
        .link(contentCreate.getLink())
        .build();
    MessageEntity messageEntity = MessageEntity.builder()
        .externalMessagelId(contentCreate.getExternalMessagelId())
        .contentType(contentCreate.getContentType())
        .project(projectEntity)
        .build();
    messageEntity.addContent(textContentEntity);
    return messageEntity;
  }
  
  /**
   * Создает сущность ProjectEntity по данным contentCreate.
   * 
   * @param contentCreate
   * @return
   */
  @Mapping(target = "id", ignore = true)
  @Mapping(target = "sourceId", source = "projectSourceId")
  @Mapping(target = "title", source = "projectTitle")
  @Mapping(target = "comment", source = "projectComment")
  ProjectEntity createNewProject(ContentDaoDto contentCreate);
  
}
