import { RecipeIngredientDto } from "../api/dtos/RecipeIngredientDto.js";
import { RecipeIngredientGroupDto } from "../api/dtos/RecipeIngredientGroupDto.js";
import { RecipeIngredientGroupEntity } from "../entities/RecipeIngredientGroupEntity.js";
import { AbstractDtoEntityMapper } from "./AbstractDtoEntityMapper.js";
import { RecipeIngredientDtoEntityMapper } from "./RecipeIngredientDtoEntityMapper.js";

export class RecipeIngredientGroupDtoEntityMapper extends AbstractDtoEntityMapper<RecipeIngredientGroupEntity, RecipeIngredientGroupDto> {
  constructor(
    private ingredientMapper: RecipeIngredientDtoEntityMapper
  ) {
    super();
  }

  toDto(entity: RecipeIngredientGroupEntity): RecipeIngredientGroupDto {
    const dto = new RecipeIngredientGroupDto();
    this.mapBaseEntityToDto(entity, dto);

    dto.title = entity.title;
    dto.sortOrder = entity.sortOrder

    // map ingredients
    dto.ingredients = entity.ingredients?.map((ingredientEntity) => {
      const ingredientDto : RecipeIngredientDto = this.ingredientMapper.toDto(ingredientEntity);
      ingredientDto.ingredientGroupId = entity.id;
      return ingredientDto;
    });

    return dto;
  }

  toEntity(dto: RecipeIngredientGroupDto): RecipeIngredientGroupEntity {
    const entity = new RecipeIngredientGroupEntity();
    this.mapBaseDtoToEntity(dto, entity);

    entity.title = dto.title;
    entity.sortOrder = dto.sortOrder

    // map ingredients
    entity.ingredients = dto.ingredients.map((ingredientDto) => {
      const ingredientEntity = this.ingredientMapper.toEntity(ingredientDto);
      // set relation if entity already exists in DB
      if(entity.hasValidId()){
        ingredientEntity.ingredientGroup = entity;
      }
      // remove id from new entity completely and allow ORM to generate a new one
      if (!ingredientDto.id) {
        delete (ingredientEntity as any).id;
      }
      return ingredientEntity;
    });

    return entity;
  }

  createNewEntity(): RecipeIngredientGroupEntity {
    return new RecipeIngredientGroupEntity();
  }

  mergeDtoIntoEntity(dto: RecipeIngredientGroupDto, entity: RecipeIngredientGroupEntity): RecipeIngredientGroupEntity {
        entity.title = dto.title;
        entity.sortOrder = dto.sortOrder;

        // sync ingredients inside each group
        entity.ingredients = this.ingredientMapper.mergeDtoListIntoEntityList(
          dto.ingredients,
          entity.ingredients,
        );

        return entity;
  }

}