package com.bcxin.tenant.domain.conditions.impls;

import com.bcxin.tenant.domain.conditions.TenantUserSameValidator;
import com.bcxin.tenant.domain.conditions.requests.TenantUserSameCheckRequest;
import com.bcxin.tenant.domain.configs.EnvConfig;
import com.bcxin.tenant.domain.dto.TenantUserTelephoneCredentialDto;
import com.bcxin.tenant.domain.exceptions.EntryEmployeeValidationException;
import com.bcxin.tenant.domain.readers.TenantDbReader;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
public class TenantUserSameValidatorImpl implements TenantUserSameValidator {
    private final EnvConfig envConfig;
    private final TenantDbReader dbReader;

    public TenantUserSameValidatorImpl(EnvConfig envConfig, TenantDbReader dbReader) {
        this.envConfig = envConfig;
        this.dbReader = dbReader;
    }

    @Override
    public void validate(Collection<TenantUserSameCheckRequest> requests) {
        Collection<EntryEmployeeValidationException.EntryNotAllowedInfo> notAllowedCompanyInfos =
                new ArrayList<>();

        /**
         * todo: 针对envConfig.isRequiredPhoneAsLoginName()的情况
         * 我们在TenantUser的create的事件里面进行验证
         * public void create(CreateTenantUserByEmployeeCommand command) {
         *
         * 这边主要是判断手机号码是否被他人占用
         */
        /**
         * 只针对新入职|邀请入职操作（非复职）的人员才需要进行手机号(账号)和身份证匹配的验证
         */
        if(envConfig.isRequiredPhoneAsLoginName()) {
            Collection<String> numbers =
                    requests.stream().map(ii -> ii.getCredentialNumber())
                            .filter(ii -> StringUtils.hasLength(ii))
                            .distinct().collect(Collectors.toList());
            Collection<String> telephones =
                    requests.stream().map(ii -> ii.getTelephone())
                            .filter(ii -> StringUtils.hasLength(ii))
                            .distinct().collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(numbers)) {
                Collection<TenantUserTelephoneCredentialDto> userTelephoneIdCards =
                        this.dbReader.getTenantUserTelephoneCredentialsByNumberOrTel(numbers,telephones);

                for (TenantUserSameCheckRequest dataItem : requests) {
                    Optional<TenantUserTelephoneCredentialDto> selectedCredentialTelephoneOptional
                            = userTelephoneIdCards.stream().filter(ii ->
                                    ii.getCredentialNumber().equalsIgnoreCase(dataItem.getCredentialNumber()) &&
                                            ii.getCredentialType() == dataItem.getCredentialType())
                            .findFirst();
                    if (selectedCredentialTelephoneOptional.isPresent() &&

                            !selectedCredentialTelephoneOptional.get().getTelephone().equalsIgnoreCase(dataItem.getTelephone())
                    ) {
                        notAllowedCompanyInfos.add(
                                EntryEmployeeValidationException.EntryNotAllowedInfo.create(
                                        dataItem.getTelephone(),
                                        String.format(" %s 对应的证件(%s)信息已经他人(%s)占用",
                                                dataItem.getTelephone(),
                                                selectedCredentialTelephoneOptional.get().getCredentialNumber(),
                                                selectedCredentialTelephoneOptional.get().getTelephone()
                                        ),
                                        dataItem.getTelephone(),
                                        dataItem.getCredentialType(),
                                        dataItem.getCredentialNumber()
                                ));
                    }

                    Optional<TenantUserTelephoneCredentialDto> selectedCredentialTelephoneByTelOptional
                            = userTelephoneIdCards.stream().filter(ii ->
                                    ii.getTelephone().equalsIgnoreCase(dataItem.getTelephone()))
                            .findFirst();
                    if(selectedCredentialTelephoneByTelOptional.isPresent()) {
                        if (selectedCredentialTelephoneByTelOptional.get().getCredentialType() == dataItem.getCredentialType() &&
                                !selectedCredentialTelephoneByTelOptional.get().getCredentialNumber().equalsIgnoreCase(dataItem.getCredentialNumber())
                        ) {
                            notAllowedCompanyInfos.add(
                                    EntryEmployeeValidationException.EntryNotAllowedInfo.create(
                                            dataItem.getTelephone(),
                                            String.format(" %s 已经持有证件(%s)信息; 无法通过其他证件进行入/复职",
                                                    dataItem.getTelephone(),
                                                    selectedCredentialTelephoneByTelOptional.get().getCredentialNumber()
                                            ),
                                            dataItem.getTelephone(),
                                            dataItem.getCredentialType(),
                                            dataItem.getCredentialNumber()
                                    ));
                        }
                    }
                }
            }


        }


        if (!CollectionUtils.isEmpty(notAllowedCompanyInfos)) {
            throw new EntryEmployeeValidationException("", notAllowedCompanyInfos);
        }
    }
}
