package cn.quantgroup.xyqb.service.user.impl;

import cn.quantgroup.xyqb.entity.*;
import cn.quantgroup.xyqb.model.UserBrief;
import cn.quantgroup.xyqb.service.user.ICustomerInfoService;
import cn.quantgroup.xyqb.service.user.IOauthClientDetailsService;
import cn.quantgroup.xyqb.service.user.IProductLoginService;
import cn.quantgroup.xyqb.service.user.ITenantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * Created by 11 on 2016/12/29.
 */
@Slf4j
@Service
public class TenantServiceImpl implements ITenantService {

    @Autowired
    private IProductLoginService productLoginService;

    @Autowired
    private ICustomerInfoService customerInfoService;

    @Autowired
    private IOauthClientDetailsService oauthClientDetailsService;

    @Override
    public User getTenantUser(User user, Integer tenantId) {
        OauthClientDetailsEntity oauthClientDetails = oauthClientDetailsService.findFirstByClientId(tenantId);
        if (oauthClientDetails != null) {
            ProductLoginEntity productLogin = productLoginService.findSlaveByPloginInfo(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), user.getId());
            if (productLogin != null) {
                if (!user.getEncryptedPhoneNo().equals(productLogin.getEncryptedPhoneNo())) {
                    return null;
                }
                user.setPassword(productLogin.getPassword());
                return user;
            }
        }
        return null;
    }

    @Override
    public UserDetail getTenantUserDetail(UserDetail userDetail, Integer tenantId) {
        OauthClientDetailsEntity oauthClientDetails = oauthClientDetailsService.findFirstByClientId(tenantId);
        if (oauthClientDetails != null) {
            ProductLoginEntity productLogin = productLoginService.findSlaveByPloginInfo(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), userDetail.getUserId());
            if (productLogin != null) {
                if (!userDetail.getPhoneNo().equals(productLogin.getPhoneNo())) {
                    return null;
                }

                CustomerInfoEntity customerInfo = customerInfoService.findSlaveByCustomerId(productLogin.getCustomerId());
                if (customerInfo == null) {
                    return null;
                }

                UserDetail tenantUserDetail = new UserDetail();
                tenantUserDetail.setUserId(userDetail.getUserId());
                tenantUserDetail.setPhoneNo(userDetail.getPhoneNo());
                tenantUserDetail.setIdNo(customerInfo.getIdCardNo());
                tenantUserDetail.setName(customerInfo.getName());
                tenantUserDetail.setCreatedAt(userDetail.getCreatedAt());
                tenantUserDetail.setUpdatedAt(userDetail.getUpdatedAt());
                return tenantUserDetail;
            }
        }
        return null;
    }

    @Override
    public UserBrief getTenantCustomerInfo(UserDetail userDetail, Integer tenantId) {
        OauthClientDetailsEntity oauthClientDetails = oauthClientDetailsService.findFirstByClientId(tenantId);
        if (oauthClientDetails != null) {
            ProductLoginEntity productLogin = productLoginService.findSlaveByPloginInfo(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), userDetail.getUserId());
            if (productLogin != null) {
                if (!userDetail.getPhoneNo().equals(productLogin.getEncryptedPhoneNo())) {
                    return null;
                }

                CustomerInfoEntity customerInfo = customerInfoService.findSlaveByCustomerId(productLogin.getCustomerId());
                if (customerInfo == null) {
                    return null;
                }

                UserBrief tenantUserBrief = new UserBrief();
                tenantUserBrief.setAvatar(customerInfo.getAvatarUrl());
                tenantUserBrief.setNick(customerInfo.getNickName());
                tenantUserBrief.setName(customerInfo.getName());
                tenantUserBrief.setSex(Optional.ofNullable(customerInfo.getSex()).orElse(cn.quantgroup.xyqb.model.Gender.UNKNOWN).ordinal() + "");
                tenantUserBrief.setPhoneNo(productLogin.getPhoneNo().substring(0, 3) + "****" + productLogin.getPhoneNo().substring(7, 11));
                return tenantUserBrief;
            }
        }
        return null;
    }

    @Override
    public CustomerInfoEntity getTenantCustomerInfo(User user, Integer tenantId) {
        OauthClientDetailsEntity oauthClientDetails = oauthClientDetailsService.findFirstByClientId(tenantId);
        if (oauthClientDetails != null) {
            ProductLoginEntity productLogin = productLoginService.findSlaveByPloginInfo(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), user.getId());
            if (productLogin != null) {
                if (!user.getPhoneNo().equals(productLogin.getPhoneNo())) {
                    return null;
                }

                CustomerInfoEntity customerInfo = customerInfoService.findSlaveByCustomerId(productLogin.getCustomerId());
                if (customerInfo == null) {
                    return null;
                }
                return customerInfo;
            }
        }
        return null;
    }

    @Override
    public List<User> selectUsersByTenantId(List<User> users, Integer tenantId) {
        List<User> result = new ArrayList<>();
        if (users != null) {
            OauthClientDetailsEntity oauthClientDetails = oauthClientDetailsService.findFirstByClientId(tenantId);
            if (oauthClientDetails != null) {
                List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
                List<ProductLoginEntity> productLoginEntities = productLoginService.findSlaveByPloginInfos(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), userIds);
                if (productLoginEntities != null && productLoginEntities.size()>0) {
                    List<String> phoneNos = productLoginEntities.stream().map(ProductLoginEntity::getPhoneNo).collect(Collectors.toList());
                    users.forEach(a->{
                        if (phoneNos.contains(a.getPhoneNo())) {
                            result.add(a);
                        }
                    });
                }
            }
        }
        return result;
    }

    @Override
    public Long getTenantCustomerInfoByOpenId(String openId, Integer tenantId) {
        // 通过租户Id确认产品和机构Id
        OauthClientDetailsEntity oauthClientDetails = oauthClientDetailsService.findFirstByClientId(tenantId);
        if (oauthClientDetails != null) {
            CustomerInfoEntity customerInfo = customerInfoService.findSlaveByOpenId(openId, oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId());
            if (customerInfo != null ) {
               ProductLoginEntity productLogin = productLoginService.findSlaveByCustomerInfo(customerInfo.getCustomerId(), oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId());
               if (productLogin != null) {
                   return productLogin.getExtensionAccountId();
               }
            }
        }
        return null;
    }

    @Override
    public List<User> validationTentIdByTentId(List<User> users, Integer tenantId) {
        List<User> result = new ArrayList<>();
        if (users != null) {
            List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
            OauthClientDetailsEntity oauthClientDetails = oauthClientDetailsService.findFirstByClientId(tenantId);
            if (oauthClientDetails != null) {
                List<ProductLoginEntity> slaveByPloginInfos = productLoginService.findSlaveByPloginInfos(oauthClientDetails.getInstitutionId(), oauthClientDetails.getProductId(), userIds);
                users.forEach(a->{
                    if (slaveByPloginInfos != null && slaveByPloginInfos.size()>0) {
                        List<String> phoneNos = slaveByPloginInfos.stream().map(ProductLoginEntity::getPhoneNo).collect(Collectors.toList());
                        if (phoneNos.contains(a.getPhoneNo())) {
                            result.add(a);
                        }
                    }
                });
            }

            List<ProductLoginEntity> slaveByUserIds = productLoginService.findSlaveByUserIds(userIds);
            if (slaveByUserIds != null) {
                List<Long> collect = slaveByUserIds.stream().map(ProductLoginEntity::getExtensionAccountId).collect(Collectors.toList());
                users.forEach(a->{
                    if (collect != null) {
                        if (!collect.contains(a.getId())) {
                            result.add(a);
                        }
                    }
                });
            }
        }
        return result;
    }
}
