package com.eactive.testmaster.client.mapper;

import com.eactive.testmaster.client.dto.ApiCollectionDTO;
import com.eactive.testmaster.client.dto.ApiLayoutDTO;
import com.eactive.testmaster.client.dto.ApiRequestDTO;
import com.eactive.testmaster.client.entity.ApiCollection;
import com.eactive.testmaster.client.entity.ApiLayout;
import com.eactive.testmaster.client.entity.ApiLayoutItem;
import com.eactive.testmaster.client.entity.ApiRequestInfo;
import com.eactive.testmaster.client.repository.ApiLayoutRepository;
import com.eactive.testmaster.client.repository.ApiRequestRepository;
import com.eactive.testmaster.common.mapper.CommonMapper;
import com.eactive.testmaster.server.mapper.ServerMapper;
import java.util.Comparator;
import java.util.List;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.ReportingPolicy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


@Mapper(componentModel = "spring",
    uses = {CommonMapper.class, ServerMapper.class},
    unmappedTargetPolicy = ReportingPolicy.IGNORE)
@Component
public abstract class ApiRequestMapper {

    @Autowired
    private ApiRequestRepository apiRequestRepository;

    @Autowired
    private ApiLayoutRepository apiLayoutRepository;

    @Autowired
    private ApiLayoutMapper apiLayoutMapper;

    public abstract ApiCollection map(ApiCollectionDTO dto);

    public abstract ApiRequestInfo map(ApiRequestDTO dto);

    @Mapping(target = "layout", ignore = true)
    public abstract ApiRequestDTO map(ApiRequestInfo entity);

    public String mapId(ApiRequestInfo entity) {
        if (entity == null) {
            return null;
        }
        return entity.getId();
    }

    public ApiRequestInfo map(String id) {
        if (id == null) {
            return null;
        }
        return apiRequestRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("No ApiRequest found for ID: " + id));
    }

    @AfterMapping
    public void handleTypeSpecificMapping(ApiRequestInfo entity, @MappingTarget ApiRequestDTO dto) {
        if ("TCP".equals(entity.getType()) || "HTTPFlat".equals(entity.getType())) {
            ApiLayout layout = apiLayoutRepository.findFirstByApiRequestInfo(entity);
            if (layout != null) {
                layout.getLayoutItems().sort(Comparator.comparingInt(ApiLayoutItem::getLoutItemSerno));
                dto.setLayout(apiLayoutMapper.map(layout));
            } else {
                dto.setLayout(new ApiLayoutDTO());
            }

        }
    }


    public abstract List<ApiRequestInfo> mapApis(List<ApiRequestDTO> apis);

    public abstract List<ApiCollectionDTO> mapCollections(List<ApiCollection> apis);
}
