package com.eactive.eai.rms.onl.apim.approval.credential;

import com.eactive.apim.portal.app.entity.Credential;
import com.eactive.eai.data.mapper.BaseMapperConfig;
import com.eactive.eai.data.mapper.GenericMapper;
import com.eactive.eai.rms.onl.manage.authserver.client.ClientUI;
import com.eactive.eai.rms.onl.transaction.apim.ApiInterfaceService;
import com.eactive.eai.rms.onl.transaction.apim.mapping.ApiSpecUIMapper;
import com.eactive.eai.rms.onl.transaction.apim.ui.ApiInterfaceUI;
import com.eactive.eai.rms.onl.transaction.apim.ui.ApiSpecInfoUI;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.mapstruct.BeanMapping;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.ReportingPolicy;
import org.springframework.beans.factory.annotation.Autowired;

@Mapper(config = BaseMapperConfig.class, componentModel = "spring", uses = {ApiSpecUIMapper.class}, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public abstract class CredentialUIMapper implements GenericMapper<CredentialUI, Credential> {

    @Autowired
    private ApiInterfaceService apiInterfaceService;

    @InheritInverseConfiguration
    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    @Mapping(target = "apiList", source = "apiList")
    public abstract void updateToEntity(CredentialUI credentialUI, @MappingTarget Credential credential);

    @Mapping(source = "clientid", target = "clientId")
    @Mapping(source = "clientname", target = "clientName")
    @Mapping(source = "clientsecret", target = "clientSecret")
    @Mapping(source = "accesstokenvalidityseconds", target = "accessTokenValiditySeconds")
    @Mapping(source = "allowedips", target = "allowedIps")
    @Mapping(source = "autoapprove", target = "autoApprove")
    @Mapping(source = "granttypes", target = "grantTypes")
    @Mapping(source = "modifiedby", target = "modifiedBy")
    @Mapping(source = "modifiedon", target = "modifiedOn", dateFormat = "yyyy-MM-dd HH:mm:ss")
    @Mapping(source = "redirecturi", target = "redirectUri")
    @Mapping(source = "refreshtokenvalidityseconds", target = "refreshTokenValiditySeconds")
    @Mapping(source = "resourceids", target = "resourceIds")
    @Mapping(source = "securitykey", target = "securityKey")
    @Mapping(source = "orgid", target = "orgId")
    @Mapping(source = "orgname", target = "orgName")
    @Mapping(source = "appstatus", target = "appStatus")
    @Mapping(source = "dailytokenlimit", target = "dailyTokenLimit")
    @Mapping(target = "apiList", expression = "java(mapApiList(credential.getApiList()))")
    @Mapping(source = "authorities", target = "authorities")
    @Mapping(source = "scope", target = "scope")
    public abstract ClientUI mapClient(CredentialUI credential);

    protected List<ApiInterfaceUI> mapApiList(List<ApiSpecInfoUI> apiSpecInfoList) {
        if (apiSpecInfoList == null) {
            return new ArrayList<>();
        }

        return apiSpecInfoList.stream()
            .map(apiSpecInfo -> {
                ApiInterfaceUI apiInterface = null;
                try {
                    apiInterface = apiInterfaceService.selectDetail(apiSpecInfo.getApiId());
                    return apiInterface;
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            })
            .collect(Collectors.toList());
    }
}
