package com.yeejoin.amos.boot.module.hygf.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.hygf.api.Enum.PeasantHouseholdEnum;
import com.yeejoin.amos.boot.module.hygf.api.Enum.PhoneRegisterTypeEum;
import com.yeejoin.amos.boot.module.hygf.api.Enum.TaskTypeStationEnum;
import com.yeejoin.amos.boot.module.hygf.api.dto.*;
import com.yeejoin.amos.boot.module.hygf.api.entity.*;
import com.yeejoin.amos.boot.module.hygf.api.mapper.PeasantHouseholdMapper;
import com.yeejoin.amos.boot.module.hygf.api.mapper.PersonnelBusinessMapper;
import com.yeejoin.amos.boot.module.hygf.api.service.IPeasantHouseholdService;
import com.yeejoin.amos.boot.module.hygf.api.service.IWxService;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.robot.AmosRequestContext;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.privilege.model.IdPasswordAuthModel;
import com.yeejoin.amos.feign.privilege.model.LoginInfoModel;
import com.yeejoin.amos.feign.privilege.model.RoleModel;
import com.yeejoin.amos.feign.privilege.model.VerifyCodeAuthModel;
import com.yeejoin.amos.feign.privilege.util.DesUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.rdbms.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.spec.AlgorithmParameterSpec;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 农户信息服务实现类
 *
 * @author system_generator
 * @date 2023-07-07
 */
@Service
@Slf4j
public class PeasantHouseholdServiceImpl extends BaseService<PeasantHouseholdDto,PeasantHousehold,PeasantHouseholdMapper> implements IPeasantHouseholdService {

    private Long TOKEN_TIME = 1209600l;

    @Value("${amos.system.user.product}")
    private String product;

    @Value("${amos.system.user.app-key}")
    private String appKey;

    @Value("${login.environment}")
    private String loginEnvironment;

    @Value("${farmer.orgCode}")
    private String orgCode;

    @Value("${farmer.sequenceNbr}")
    private Long orgSequenceNbr;

    @Value("${farmer.orgNamesWithoutRole:智信能源科技有限公司}")
    private String orgNamesWithoutRole;

    @Value("${dealer.appcode}")
    private String appCodes;

    @Value("${platform.access.loginId}")
    private String platfromAccessLoginId;

    @Value("${platform.access.password}")
    private String platfromAccessPassword;

    @Value("${farmer.roleId:1678211468450885633}")
    private String farmerRoleId;

    @Value("${farmer.registerPassword}")
    private String registerPassword;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private IWxService wxService;

    @Autowired
    SurveyInformationServiceImpl surveyInformationService;

    @Autowired
    SurveyDetailsServiceImpl surveyDetailsService;

    @Autowired
    InformationServiceImpl informationService;

    @Autowired
    ExtendedInformationServiceImpl extendedInformationService;

    @Autowired
    CommercialServiceImpl commercialService;

    @Autowired
    SurveyInformationServiceImpl surveyInformationServiceImpl;

    @Autowired
    HouseholdContractServiceImpl householdContractServiceImpl;
    @Autowired
    PersonnelBusinessMapper personnelBusinessMapper;
    @Autowired
    UnitInfoServiceImpl unitInfoServiceImpl;
    @Autowired
    AmosRequestContext requestContext;
    @Autowired
    ToDoTasksServiceImpl toDoTasksServiceImpl;

    public static final String SECRETKEY = "qaz";

    @Transactional (rollbackFor = Exception.class)
    public PeasantHouseholdDto savePeasantHousehold(PeasantHouseholdDto model, AgencyUserModel userInfo) {
        SurveyInformationDto surveyInformationDto = new SurveyInformationDto();
        surveyInformationServiceImpl.createWithModel(surveyInformationDto);

        model.setSurveyInformationId(surveyInformationDto.getSequenceNbr());
        model.setSurveyOrNot(0);
        model.setReview(0);
        if (model.getCreationTime() == null) {
            model.setCreationTime(new Date());
        }
        model.setPeasantHouseholdNo(this.getPeasantHouseholdNo());
        model.setIsCertified(model.getIsCertified() == null ? 0 : model.getIsCertified());// 未认证

        if (model.getSequenceNbr() == null) {
            List<PeasantHousehold> peasantHouseholds = this.query().eq("telephone", model.getTelephone()).orderByDesc("rec_date").list();
            PeasantHousehold phd = peasantHouseholds.size() > 0 ? peasantHouseholds.get(0) : null;
            if (phd != null) {
                model.setSequenceNbr(phd.getSequenceNbr());
            }
        }

        PeasantHousehold peasantHousehold = new PeasantHousehold();
        BeanUtils.copyProperties(model, peasantHousehold);
        this.saveOrUpdate(peasantHousehold);
        //生成合同
        HouseholdContract householdContract=new HouseholdContract();
        householdContract.setPartyA(peasantHousehold.getOwnersName());
        householdContract.setPeasantHouseholdNumber(peasantHousehold.getPeasantHouseholdNo());
        householdContract.setPeasantHouseholdCard(peasantHousehold.getIdCard());
        householdContract.setDealerId(peasantHousehold.getDeveloperId());
        householdContract.setDealerCode(peasantHousehold.getDeveloperCode());
        householdContract.setDealerName(peasantHousehold.getDeveloperName());
        householdContract.setPeasantHouseholdId(peasantHousehold.getSequenceNbr());
        householdContract.setRegionalCompaniesCode(peasantHousehold.getRegionalCompaniesCode());
        householdContract.setRegionalCompaniesName(peasantHousehold.getRegionalCompaniesName());
        householdContract.setRegionalCompaniesSeq(peasantHousehold.getRegionalCompaniesSeq());
        householdContract.setPeasantHouseholdPhone(peasantHousehold.getTelephone());
        householdContract.setProjectAddressDetail(peasantHousehold.getProjectAddressDetail());
        householdContract.setProjectAddressName(peasantHousehold.getProjectAddressName());
        householdContract.setPermanentAddressDetail(peasantHousehold.getPermanentAddressDetail());
        householdContract.setPermanentAddressName(peasantHousehold.getPermanentAddressName());
        householdContract.setProjectUserId(peasantHousehold.getAmosUserId());
        householdContractServiceImpl.addHouseholdContract(householdContract);

        //生成待办任务
        ToDoTasks toDoTasks=  new ToDoTasks (  TaskTypeStationEnum.电站勘察.getCode(),  peasantHousehold.getSequenceNbr(),   "用户"+householdContract.getPartyA()+"电站信息勘察",householdContract.getDealerCode());
        toDoTasksServiceImpl.addToDoTasksByUserId(peasantHousehold.getDeveloperUserId(),toDoTasks,"");

        ToDoTasks toDoTasks1=  new ToDoTasks (  TaskTypeStationEnum.合同填报.getCode(),  householdContract.getSequenceNbr(),  "用户"+householdContract.getPartyA()+"的合同待发起",householdContract.getDealerCode());
        toDoTasksServiceImpl.addToDoTasksByUserId(peasantHousehold.getDeveloperUserId(),toDoTasks1,"");

        return model;
    }

    public boolean deletePeasantHouseholdBySequenceNbr(Long sequenceNbr){
        PeasantHouseholdDto peasantHouseholdDto = this.queryBySeq(sequenceNbr);
        Long surveyInformationId = peasantHouseholdDto.getSurveyInformationId();
        //删除勘察基本信息
        surveyInformationService.deleteBySeq(surveyInformationId);
        //删除扩展信息
        QueryWrapper<ExtendedInformation> extendedInformationDeleteWrapper = new QueryWrapper<>();
        extendedInformationDeleteWrapper.lambda().eq(ExtendedInformation::getSurveyInformationId,surveyInformationId);
        extendedInformationService.getBaseMapper().delete(extendedInformationDeleteWrapper);
        //删除勘察明细
        QueryWrapper<SurveyDetails> surveyDetailsDeleteWrapper = new QueryWrapper<>();
        surveyDetailsDeleteWrapper.lambda().eq(SurveyDetails::getSurveyInformationId,surveyInformationId);
        surveyDetailsService.getBaseMapper().delete(surveyDetailsDeleteWrapper);
        //删除商务信息
        QueryWrapper<Commercial> commercialDeleteWrapper = new QueryWrapper<>();
        commercialDeleteWrapper.lambda().eq(Commercial::getSurveyInformationId,surveyInformationId);
        commercialService.getBaseMapper().delete(commercialDeleteWrapper);
        //删除资料归档信息
        QueryWrapper<Information> informationDeleteWrapper = new QueryWrapper<>();
        informationDeleteWrapper.lambda().eq(Information::getSurveyInformationId,surveyInformationId);
        informationService.getBaseMapper().delete(informationDeleteWrapper);
        //删除农户信息
        return this.deleteBySeq(sequenceNbr);
    }

    /**
     * 分页查询
     */
    public Page<PeasantHouseholdDto> queryForPeasantHouseholdPage(Page<PeasantHouseholdDto> page,String developerCode,@Condition(Operator.like) String ownersName,Long developerId, @Condition(Operator.eq) Integer isCertified)   {
        Page<PeasantHouseholdDto> peasantHouseholdDtoPage = this.queryForPage(page, "rec_date", false,developerCode,ownersName,developerId, isCertified);
        List<PeasantHouseholdDto> records = peasantHouseholdDtoPage.getRecords();
        List<PeasantHouseholdDto> newRecords = records.stream().map(item -> {
            if(item.getSurveyOrNot() != null){
                if (item.getSurveyOrNot() == 0) {
                    item.setSurveyOrNotText("待勘察");
                } else if (item.getSurveyOrNot() == 1) {
                    item.setSurveyOrNotText("已勘察");
                } else if (item.getSurveyOrNot() == 2) {
                    item.setSurveyOrNotText("审核中");
                } else if (item.getSurveyOrNot() == 3) {
                    item.setSurveyOrNotText("审核完成");
                }
            }

            if (!StringUtils.isEmpty(item.getProjectAddressName())) {
                item.setProjectAddressText(Arrays.asList(item.getProjectAddressName().split("/")));
            }
            if(!StringUtils.isEmpty(item.getPermanentAddressName())){
                item.setPermanentAddressText(Arrays.asList(item.getPermanentAddressName().split("/")));
            }

            item.setProjectAddressName(item.getProjectAddressName()+"/"+item.getProjectAddressDetail());
            return item;
        }).collect(Collectors.toList());
        peasantHouseholdDtoPage.setRecords(newRecords);
        return peasantHouseholdDtoPage;
    }

    /**
     * 列表查询 示例
     */
    public List<PeasantHouseholdDto> queryForPeasantHouseholdList(@Condition(Operator.eq) Integer isCertified)   {
        return this.queryForList("" , false, isCertified);
    }

    public Boolean doAuthenticate(Long sequenceNbr) {
        // 判断是否注册过
        PeasantHousehold peasantHousehold = this.getById(sequenceNbr);
        if (null == peasantHousehold) {
            throw new BadRequest("认证失败, 农户信息不存在");
        }
        peasantHousehold.setIsCertified(1);// 认证
        return this.updateById(peasantHousehold);
    }

    @Transactional(rollbackFor = Exception.class)
    public PeasantHouseholdWxDto wxUserLogin(MobileLoginParamDto wxDTO) {
        // 通过手机号和验证码调用平台接口进行验证
        String phoneNo = this.parsePhoneNo(wxDTO);
        if (phoneNo == null) {
            log.error("获取手机号失败!");
            throw new BadRequest("微信授权失败, 请重新授权");
        }
        log.info("用户手机号码 => {} 开始登录", phoneNo);
        wxDTO.setPhoneNo(phoneNo);
        // 机器人token
        RequestContext.setAppKey("AMOS_STUDIO");
        RequestContext.setProduct("AMOS_STUDIO_WEB");
        RequestContext.setToken(requestContext.getToken());

        AgencyUserModel registerUserModel = null;
        // region 判断有无在平台内部注册过用户 没有注册则去平台注册
        FeignClientResult<LoginInfoModel> loginInfo = Privilege.agencyUserClient.getLoginInfo(phoneNo);

        if (loginInfo != null && 200 == loginInfo.getStatus()) {
            LoginInfoModel loginInfoModel = loginInfo.getResult();
            if (loginInfoModel == null || !StringUtils.isNotBlank(loginInfoModel.getLoginId())) {
                // 没有认证过, 去注册用户
                FeignClientResult<AgencyUserModel> registerUserModelRestult = doRegister(wxDTO);
                if (registerUserModelRestult == null || registerUserModelRestult.getStatus() != 200) {
                    log.error("用户手机号码 => " + phoneNo + " 调用平台创建用户信息失败: " + registerUserModelRestult.getDevMessage());
                    throw new RuntimeException(registerUserModelRestult.getMessage());
                }
                registerUserModel = registerUserModelRestult.getResult();
            }
        }
        // endregion
        // 登录
        PeasantHouseholdWxDto loginResult;
        try {
            loginResult = doLogin(wxDTO, registerUserModel);
            // 查询农户信息
            List<PeasantHousehold> peasantHouseholds = this.query().eq("telephone", phoneNo).orderByDesc("rec_date").list();
            PeasantHousehold peasantHousehold = peasantHouseholds.size() > 0 ? peasantHouseholds.get(0) : null;
            if (null == peasantHousehold) {
                peasantHousehold = new PeasantHousehold();
                peasantHousehold.setIsCertified(0);
                peasantHousehold.setSurveyOrNot(0);
                peasantHousehold.setReview(0);
                peasantHousehold.setTelephone(phoneNo);
                PeasantHouseholdDto peasantHouseholdDto = buildDefaultPeasantHouseholdDto(wxDTO.getAmosUserId(), wxDTO.getQrCodeType(), phoneNo);
                peasantHousehold.setDeveloperCode(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getDeveloperCode).orElse(null));// 开发方code
                peasantHousehold.setDeveloperId(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getDeveloperId).orElse(null));// 开发方id
                peasantHousehold.setDeveloperName(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getDeveloperName).orElse(null));// 开发方名称
                peasantHousehold.setDeveloper(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getDeveloper).orElse(null));// 开发人
                peasantHousehold.setDeveloperUserId(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getDeveloperUserId).orElse(null));
                peasantHousehold.setRegionalCompaniesSeq(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getRegionalCompaniesSeq).orElse(null));
                peasantHousehold.setRegionalCompaniesCode(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getRegionalCompaniesCode).orElse(null));
                peasantHousehold.setRegionalCompaniesName(Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getRegionalCompaniesName).orElse(null));
                peasantHousehold.setIsCertified(0);
                // 过滤传给前端的数据
                this.save(peasantHousehold);
            }
            /*else {
                // 场景：扫码未实名认证的情况下, 关掉小程序第二次扫另一个区域经销商的二维码
                //
                wxDTO.getAmosUserId();// 二维码携带的经销商userId
                PeasantHouseholdDto peasantHouseholdDto = buildDefaultPeasantHouseholdDto(wxDTO.getAmosUserId(), wxDTO.getQrCodeType(), phoneNo);
                Long newRegionalCompaniesSeq = Optional.ofNullable(peasantHouseholdDto).map(PeasantHouseholdDto::getRegionalCompaniesSeq).orElse(null);
                if (newRegionalCompaniesSeq.compareTo()) {
                    throw new RuntimeException("");
                }
            }*/
            log.debug("返回给前端数据, 手机号码 => {}, 农户信息 => {}", phoneNo, peasantHousehold);
            // 装载农户信息
            loginResult.setPeasantHousehold(peasantHousehold);
            return loginResult;
        } catch (Exception e) {
            log.error(e.getMessage());
            if (null != registerUserModel) {
                log.error("调用平台接口回滚注册的用户 => {}", e, registerUserModel.getUserId());
                // 调用平台接口回滚注册的用户
                RequestContext.setAppKey("AMOS_STUDIO");
                RequestContext.setProduct("AMOS_STUDIO_WEB");
                RequestContext.setToken(requestContext.getToken());
                Privilege.agencyUserClient.multDeleteUser(registerUserModel.getUserId());
            }
            if (e instanceof BadRequest || e.getCause() instanceof BadRequest) {
                throw new BadRequest(e.getMessage());
            }
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 农户微信注册
     *
     *
     * @param mobileLoginParamDto mobileLoginParamDto
     * @return {@link  AgencyUserModel}
     * @author Provence
     * @throws
     * @date 2023/8/21 18:05
     */
    public FeignClientResult<AgencyUserModel> doRegister(MobileLoginParamDto mobileLoginParamDto) {
        CompanyModel companyInfo = new CompanyModel();
        companyInfo.setSequenceNbr(orgSequenceNbr);
        companyInfo.setCompanyOrgCode(Integer.valueOf(orgCode));
        RoleModel allRoleList = null;
        FeignClientResult<RoleModel> roleListResult = Privilege.roleClient.seleteOne(Long.valueOf(farmerRoleId));
        if (roleListResult != null && roleListResult.getStatus() == 200) {
            allRoleList = roleListResult.getResult();
        }

        List<RoleModel> userRoleList = new ArrayList<>();
        List<String> split = Arrays.asList(StringUtils.split(appCodes, ','));
        Map<Long, List<Long>> roleSeqMap = new HashMap<>();
        Map<Long, List<RoleModel>> orgRoles = new HashMap<>();
        // 提前建立好一个默认角色
        List<Long> roleIds = new ArrayList<>();
        userRoleList.add(allRoleList);
        roleIds.add(Long.valueOf(farmerRoleId));
        roleSeqMap.put(companyInfo.getSequenceNbr(), roleIds);
        orgRoles.put(companyInfo.getSequenceNbr(), userRoleList);
        // 初始默认密码  a1234560
        String custPassword = DesUtil.encode(registerPassword, SECRETKEY);
        AgencyUserModel agencyUserModel = new AgencyUserModel();
        agencyUserModel.setUserName(mobileLoginParamDto.getPhoneNo());
        agencyUserModel.setRealName(mobileLoginParamDto.getPhoneNo());
        agencyUserModel.setPassword(custPassword);
        agencyUserModel.setRePassword(custPassword);
        // model中有个openId, 传手机号，verifyCode值为手机号加密
        agencyUserModel.setOpenId(mobileLoginParamDto.getPhoneNo());
        agencyUserModel.setVerifyCode(DesUtil.encode(mobileLoginParamDto.getPhoneNo(), SECRETKEY));
        agencyUserModel.setLockStatus("UNLOCK");
        agencyUserModel.setAgencyCode("JXIOP");
        agencyUserModel.setMobile(mobileLoginParamDto.getPhoneNo());
        agencyUserModel.setAppCodes(split);
        agencyUserModel.setOrgRoles(orgRoles);
        agencyUserModel.setOrgRoleSeqs(roleSeqMap);
        log.debug("注册用户入参, agencyUserModel => {}", agencyUserModel);
        FeignClientResult<AgencyUserModel> agencyUserResult = Privilege.agencyUserClient.create(agencyUserModel);
        return agencyUserResult;
    }

    /**
     * 农户微信登录
     *
     *
     * @param param param
     * @return {@link  PeasantHouseholdWxDto}
     * @author Provence
     * @throws
     * @date 2023/8/21 18:05
     */
    public PeasantHouseholdWxDto doLogin(MobileLoginParamDto param, AgencyUserModel registerUserModel) {
        RequestContext.setToken("");
        RequestContext.setProduct("STUDIO_APP_MOBILE");
        RequestContext.setAppKey("studio_normalapp_5133538");
        String phoneNo = param.getPhoneNo();
        if (phoneNo == null) {
            log.error("获取手机号失败!");
            throw new BadRequest("微信授权失败, 请重新授权");
        }
        FeignClientResult loginResult;
        if (!param.getIsNeedVerify() || ("dev".equals(loginEnvironment) && "666666".equals(param.getVerifyCode()))) {
            // 授权登录
            VerifyCodeAuthModel verifyCodeAuthModel = new VerifyCodeAuthModel();
            verifyCodeAuthModel.setLoginId(phoneNo);
            verifyCodeAuthModel.setVerifyCode(DesUtil.encode(phoneNo, SECRETKEY));// 手机号码 + 密码盐
            log.info("微信登录入参 => {}", verifyCodeAuthModel);
            loginResult = Privilege.authClient.Wechat(verifyCodeAuthModel);
        } else {
            // 验证码
            VerifyCodeAuthModel model = new VerifyCodeAuthModel();
            model.setLoginId(phoneNo);
            model.setVerifyCode(param.getVerifyCode());
            loginResult = Privilege.authClient.mobileVerifyCode(model);
        }
        if (loginResult == null || loginResult.getStatus() != 200) {
            log.error("手机号码 => " + phoneNo + " 登录失败: " + loginResult.getDevMessage());
            String message = StringUtils.isEmpty(loginResult.getMessage()) ? "账号或密码错误" : loginResult.getMessage();
            throw new RuntimeException(message);
        }
        HashMap resultMap = (HashMap) loginResult.getResult();
        String token = resultMap.get("token").toString();
        // 设置登录信息
        RequestContext.setToken(token);
        // redisUtils.set(model.getPhone() + "_token", token, TOKEN_TIME);
        String userId = (String) resultMap.get("userId");
        // 组装数据
        PeasantHouseholdWxDto peasantHouseholdWxDto = new PeasantHouseholdWxDto();
        peasantHouseholdWxDto.setExpire(Long.valueOf((String) resultMap.get("expire")));
        peasantHouseholdWxDto.setUserId(userId);
        // 组装authInfo数据
        Map<String, Object> authInfo = new HashMap<>();
        authInfo.put("token", token);
        authInfo.put("personId", userId);
        /*authInfo.put("appKey", "STUDIO_APP_MOBILE");
        authInfo.put("product", "studio_normalapp_5133538");*/
        peasantHouseholdWxDto.setAuthInfo(authInfo);

        return peasantHouseholdWxDto;
    }

    /**
     * 通过区域/个人二维码扫描组装信息
     *
     * @param qrCodeType qrCodeType
     * @param userInfo userInfo
     * @return {@link  PeasantHouseholdDto}
     * @author Provence
     * @throws
     */
    public PeasantHouseholdDto buildDefaultPeasantHouseholdDto(String qrCodeType, AgencyUserModel userInfo) {


        if (null == userInfo) {
            log.warn("userId:{} 查询不到经销商信息 或者 查询不到经销商单位信息");
            return null;
        }
        log.info("通过区域/个人二维码扫描组装信息, user => {}, user's companys => {}", userInfo.getUserId(), JSONObject.toJSONString(userInfo.getCompanys()));

        //获取用户所在经销商单位
        UserUnitInformationDto userUnitInformationDto=personnelBusinessMapper.getUserUnitInformationDto(userInfo.getUserId());

//        Long sequenceNbr = userInfo.getCompanys().get(0).getSequenceNbr();
//        String companyOrgCode = userInfo.getCompanys().get(0).getOrgCode();
//        String companyName = userInfo.getCompanys().get(0).getCompanyName();
        Long sequenceNbr = userUnitInformationDto.getAmosDealerId();
        String companyOrgCode = userUnitInformationDto.getAmosDealerOrgCode();
        String companyName = userUnitInformationDto.getAmosDealerName();

        // unitInfoServiceImpl.createCompanyAndUser 创建经销商的时候绑定的平台用户
      //  List<UnitInfo> unitInfos = unitInfoServiceImpl.list(new LambdaQueryWrapper<UnitInfo>().eq(UnitInfo::getAmosCompanySeq, sequenceNbr));
        PeasantHouseholdDto dto = new PeasantHouseholdDto();
        // 先在后台创建一个角色和公司，微信农户新建的用户使用统一的
        // 用户光伏-微信农户
        // 非扫码进入注册页面，默认
        dto.setDeveloperCode(companyOrgCode);// 开发方code
        dto.setDeveloperId(sequenceNbr);// 开发方id
        dto.setDeveloperName(companyName);// 开发方名称
        dto.setDeveloper(userInfo.getRealName());// 开发人
        dto.setDeveloperUserId(userInfo.getUserId());
//        UnitInfo unitInfo;
//        if (!CollectionUtils.isEmpty(unitInfos)) {
//            log.warn("userId:{} 查询不到经销商信息", userInfo.getUserId());
//            unitInfo = unitInfos.get(0);
//           // Long regionalCompaniesSeq = unitInfo.getRegionalCompaniesSeq();
//            String regionalCompaniesCode = unitInfo.getRegionalCompaniesCode();
//            String regionalCompaniesName = unitInfo.getRegionalCompaniesName();
//            dto.setRegionalCompaniesSeq(null);//所属区域公司id
//            dto.setRegionalCompaniesCode(regionalCompaniesCode);//所属区域公司code
//            dto.setRegionalCompaniesName(regionalCompaniesName);//所属区域公司名称
//        }

        dto.setRegionalCompaniesSeq(userUnitInformationDto.getRegionalCompaniesSeq());//所属区域公司id
        dto.setRegionalCompaniesCode(userUnitInformationDto.getRegionalCompaniesCode());//所属区域公司code
        dto.setRegionalCompaniesName(userUnitInformationDto.getRegionalCompaniesName());//所属区域公司名称

        return dto;
    }

    /**
     * 农户通过扫描区域二维码进入注册，查询区域经销商的信息并
     *
     *
     * @param userId userId
     * @param qrCodeType qrCodeType
     * @param phoneNo phoneNo
     * @return {@link  PeasantHouseholdDto}
     * @author Provence
     * @throws
     */
    private PeasantHouseholdDto buildDefaultPeasantHouseholdDto(String userId, String qrCodeType, String phoneNo) {
        // 这里的userId 是解析区域二维码得到的参数, 如果第一次扫码进来会创建一条农户数据然后关联起来
        if (StringUtils.isBlank(userId)) {
            throw new BadRequest("请通过区域二维码扫码进入");
        }
        FeignClientResult<AgencyUserModel> userInfoResult = Privilege.agencyUserClient.queryByUserId(userId);// 获取用户
        if (userInfoResult == null || userInfoResult.getStatus() != 200) {
            return null;
        }
        AgencyUserModel userInfo = userInfoResult.getResult();
        return buildDefaultPeasantHouseholdDto(qrCodeType, userInfo);
    }

    /**
     * 手机号解析
     *
     * @param param MobileLoginParam.class
     * @return String phoneNo
     */
    private String parsePhoneNo(MobileLoginParamDto param) {
        if (param.getRegisterType() == PhoneRegisterTypeEum.WX.getCode()) {
            // 进行验证码解析
            String encryptedData = param.getEncryptedData();
            String iv = param.getIv();
            String code = param.getCode();
            return getPhoneNumber(wxService.getSessionKey(code), encryptedData, iv);
        } else {
            return param.getPhoneNo();
        }
    }

    public String getPhoneNumber(String sessionkey, String encryptedData, String iv) {
        byte[] encrypData = java.util.Base64.getDecoder().decode(encryptedData);
        byte[] ivData = java.util.Base64.getDecoder().decode(iv);
        byte[] sessionKey = java.util.Base64.getDecoder().decode(sessionkey);
        String resultString = null;
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivData);
        SecretKeySpec keySpec = new SecretKeySpec(sessionKey, "AES");
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            resultString = new String(cipher.doFinal(encrypData), "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("getPhoneNumber error:", e);
            throw new BadRequest("微信授权失败, 请重新授权");
        }
        JSONObject object = JSONObject.parseObject(resultString);
        if (object != null) {
            // 拿到手机号码
            String phone = object.getString("phoneNumber");
            return phone;
        }
        return null;
    }


    /**
     * 设置平台接口调用权限
     */
    public void setPlatFormAccess() {
        RequestContext.setProduct(product);
        RequestContext.setAppKey(appKey);
        /*IdPasswordAuthModel authModel = new IdPasswordAuthModel();
        authModel.setLoginId("admin_jxiop");
        authModel.setPassword("AC286A35E74D2DD281EB979789DECF3A");*/

        IdPasswordAuthModel authModel = new IdPasswordAuthModel();
        authModel.setLoginId(platfromAccessLoginId);
        authModel.setPassword(platfromAccessPassword);

        FeignClientResult<Map<String, String>> authResult = Privilege.authClient.idpassword(authModel);
        String token = authResult.getResult().get("token");
        System.out.println("token:" + token);
        RequestContext.setToken(token);
        // 正常情况下，这里应该做缓存
    }

    /**
     * 生成一个农户信息编号
     *
     *
     * @param
     * @return {@link  String}
     * @author Provence
     * @throws
     */
    public String getPeasantHouseholdNo() {
        String redisKey = "getPeasantHouseholdNo";
        String sdf = new SimpleDateFormat("yyyyMMdd").format(new Date());
        long increment = redisUtils.incr(redisKey, 1);
        if (increment == 0) {
            redisUtils.expire(redisKey, nextDay());
        }
        return "N" + sdf + String.format("%05d", increment);
    }

    private long nextDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }

}