/**
  * 获取当前登录用户的所有百度账户信息
  *
  * @param currUserName
  * @return
  */
 @Override
 public List<BaiduAccountInfoDTO> getBaiduAccountItems(String currUserName) {
   SystemUserDTO systemUserDTO = systemUserDAO.findByUserName(currUserName);
   if (systemUserDTO != null) {
     return systemUserDTO.getBaiduAccounts();
   }
   return Collections.emptyList();
 }
  @Override
  public boolean removeAccount(Long id, String account) {

    SystemUserDTO byUserName = systemUserDAO.findByUserName(account);
    boolean Master = false;
    if (byUserName != null && byUserName.getBaiduAccounts().size() > 0) {
      for (int i = 0; i < byUserName.getBaiduAccounts().size(); i++) {
        if (byUserName.getBaiduAccounts().get(i).getId().compareTo(id) == 0) {
          if (byUserName.getBaiduAccounts().get(i).isDfault()) {}

          byUserName.getBaiduAccounts().remove(i);
          --i;
        }
      }
      List<BaiduAccountInfoDTO> baiduAccountInfoDTOs = byUserName.getBaiduAccounts();
      if (baiduAccountInfoDTOs.size() > 0 && Master) {
        baiduAccountInfoDTOs.get(0).setDfault(true);
      }
      int falg = systemUserDAO.removeAccountInfo(baiduAccountInfoDTOs, account);
      if (falg > 0) {
        return true;
      }
    }
    return false;
  }
  @Override
  public void getAdgroupReportData(
      List<AdgroupReportDTO> adgroupReportDTOs, SystemUserDTO systemUser, String dateStr, int i) {
    MongoTemplate mongoTemplate;
    mongoTemplate =
        BaseMongoTemplate.getMongoTemplate(DBNameUtils.getReportDBName(systemUser.getUserName()));

    List<AdgroupReportEntity> adgroupReportEntities =
        new ArrayList<>(ObjectUtils.convert(adgroupReportDTOs, AdgroupReportEntity.class));
    List<AdgroupReportEntity> adgroupReportEntities1;
    if (mongoTemplate.collectionExists(dateStr + "-adgroup")) {
      if (i > 1) {
        adgroupReportEntities1 =
            new ArrayList<>(
                mongoTemplate.find(new Query(), AdgroupReportEntity.class, dateStr + "-adgroup"));
        adgroupReportEntities.addAll(adgroupReportEntities1);
      }
      mongoTemplate.dropCollection(dateStr + "-adgroup");
    }

    mongoTemplate.insert(adgroupReportEntities, dateStr + "-adgroup");
  }
  @Override
  public void getAccountReportData(
      List<AccountReportDTO> accountReportDTOs,
      SystemUserDTO systemUser,
      String dateStr,
      String baiduUserName) {
    MongoTemplate mongoTemplate;
    mongoTemplate =
        BaseMongoTemplate.getMongoTemplate(DBNameUtils.getReportDBName(systemUser.getUserName()));

    List<AccountReportEntity> accountReportEntities =
        ObjectUtils.convert(accountReportDTOs, AccountReportEntity.class);
    Date date = new Date();
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    String dateString = df.format(date);

    List<AccountReportEntity> entities = null;
    if (!dateStr.equals(dateString)) {
      try {
        entities =
            mongoTemplate.find(
                Query.query(
                    Criteria.where("date")
                        .is(new SimpleDateFormat("yyyy-MM-dd").parse(dateStr))
                        .and("acna")
                        .is(baiduUserName)),
                AccountReportEntity.class);
      } catch (ParseException e) {
        e.printStackTrace();
      }

      if (entities == null || entities.size() == 0) {
        mongoTemplate.insert(accountReportEntities, TBL_ACCOUNT_REPORT);
      }
    }
  }
  @Override
  public void initAccount(String userName, Long accountId) {
    logger.info("开始导入数据: 用户名=" + userName + ", 账号= " + accountId);

    SystemUserDTO systemUserDTO = getSystemUser(userName);
    if (systemUserDTO == null) {
      logger.warn("没有此账号: " + userName);
      return;
    }

    logger.info("清理已有数据...");
    clearAccountData(accountId);
    logger.info("清理数据完成!");

    for (BaiduAccountInfoDTO baiduAccountInfoDTO : systemUserDTO.getBaiduAccounts()) {

      Long aid = baiduAccountInfoDTO.getId();
      if (!Objects.equals(aid, accountId)) continue;
      CommonService commonService =
          BaiduServiceSupport.getCommonService(
              baiduAccountInfoDTO.getBaiduUserName(),
              baiduAccountInfoDTO.getBaiduPassword(),
              baiduAccountInfoDTO.getToken());
      BaiduApiService apiService = new BaiduApiService(commonService);

      logger.info("查询账户信息...");
      // 初始化账户数据
      AccountInfoType accountInfoType = apiService.getAccountInfo();
      if (accountInfoType == null) {
        logger.error("获取账户信息错误: " + ResHeaderUtil.getJsonResHeader(false).toString());
        continue;
      }
      boolean isDefault = baiduAccountInfoDTO.isDfault();
      baiduAccountInfoDTO = ObjectUtils.convert(accountInfoType, BaiduAccountInfoDTO.class);
      baiduAccountInfoDTO.setId(accountInfoType.getUserid());
      baiduAccountInfoDTO.setBaiduUserName(baiduAccountInfoDTO.getBaiduUserName());
      baiduAccountInfoDTO.setBaiduPassword(baiduAccountInfoDTO.getBaiduPassword());
      baiduAccountInfoDTO.setToken(baiduAccountInfoDTO.getToken());
      baiduAccountInfoDTO.setDfault(isDefault);

      // 新增百度账户
      systemUserDAO.insertAccountInfo(userName, baiduAccountInfoDTO);

      logger.info("查询账户推广计划...");
      List<CampaignType> campaignTypes = apiService.getAllCampaign();
      logger.info("查询结束: 计划数=" + campaignTypes.size());

      List<CampaignDTO> campaignEntities = EntityConvertUtils.convertToCamEntity(campaignTypes);

      // 查询推广单元
      List<Long> ids = new ArrayList<>(campaignEntities.size());

      for (CampaignDTO campaignEntity : campaignEntities) {
        campaignEntity.setAccountId(aid);
        ids.add(campaignEntity.getCampaignId());
      }

      logger.info("查询账户推广单元...");
      List<AdgroupType> adgroupTypeList = apiService.getAllAdGroup(ids);

      logger.info("查询结束: 单元数=" + adgroupTypeList.size());

      List<AdgroupDTO> adgroupEntities = EntityConvertUtils.convertToAdEntity(adgroupTypeList);
      ids.clear();
      for (AdgroupDTO adgroupEntity : adgroupEntities) {
        adgroupEntity.setAccountId(aid);
        ids.add(adgroupEntity.getAdgroupId());
      }

      logger.info("查询账户推广关键词...");

      //            List<KeywordType> keywordTypes = apiService.getAllKeyword(ids);
      //            logger.info("查询结束: 关键词数=" + keywordTypes.size());
      //
      //            List<KeywordDTO> keywordEntities =
      // EntityConvertUtils.convertToKwEntity(keywordTypes);
      //
      //            for (KeywordDTO keywordEntity : keywordEntities) {
      //                keywordEntity.setAccountId(aid);
      //            }

      // 分批次请求关键词数据
      List<Long> subList = new ArrayList<>(4);
      for (int i = 1; i <= ids.size(); i++) {
        Long adgroupId = ids.get(i - 1);
        subList.add(adgroupId);

        if (i % 4 == 0) {
          List<KeywordType> keywordTypes = apiService.getAllKeyword(subList);
          List<KeywordDTO> keywordEntities = EntityConvertUtils.convertToKwEntity(keywordTypes);

          for (KeywordDTO keywordEntity : keywordEntities) {
            keywordEntity.setAccountId(aid);
          }
          keywordDAO.save(keywordEntities);
          subList.clear();
        }
      }

      if (!subList.isEmpty()) {
        List<KeywordType> keywordTypes = apiService.getAllKeyword(subList);
        List<KeywordDTO> keywordEntities = EntityConvertUtils.convertToKwEntity(keywordTypes);

        for (KeywordDTO keywordEntity : keywordEntities) {
          keywordEntity.setAccountId(aid);
        }
        keywordDAO.save(keywordEntities);
        subList.clear();
      }

      logger.info("查询账户推广创意...");
      List<CreativeType> creativeTypes = apiService.getAllCreative(ids);
      logger.info("查询结束: 普通创意数=" + creativeTypes.size());

      List<CreativeDTO> creativeEntityList = EntityConvertUtils.convertToCrEntity(creativeTypes);

      for (CreativeDTO creativeEntity : creativeEntityList) {
        creativeEntity.setAccountId(aid);
      }

      // 开始保存数据
      campaignDAO.save(campaignEntities);
      adgroupDAO.save(adgroupEntities);
      creativeDAO.save(creativeEntityList);
    }
  }
  @Override
  public List<CampaignDTO> getCampaign(String userName, long accountId) {
    SystemUserDTO systemUserDTO = getSystemUser(userName);

    if (systemUserDTO == null) {
      return Collections.emptyList();
    }

    List<BaiduAccountInfoDTO> baiduAccountInfoDTOList = systemUserDTO.getBaiduAccounts();

    if (baiduAccountInfoDTOList == null || baiduAccountInfoDTOList.isEmpty()) {
      return Collections.emptyList();
    }

    BaiduAccountInfoDTO baiduAccountInfoDTO = null;
    for (BaiduAccountInfoDTO dto : baiduAccountInfoDTOList) {
      if (Long.valueOf(accountId).compareTo(dto.getId()) == 0) {
        baiduAccountInfoDTO = dto;
        break;
      }
    }

    Objects.requireNonNull(baiduAccountInfoDTO);
    Long acid = baiduAccountInfoDTO.getId();

    CommonService commonService =
        BaiduServiceSupport.getCommonService(
            baiduAccountInfoDTO.getBaiduUserName(),
            baiduAccountInfoDTO.getBaiduPassword(),
            baiduAccountInfoDTO.getToken());
    BaiduApiService apiService = new BaiduApiService(commonService);

    // 本地的推广单元
    List<CampaignDTO> campaignEntityList = Lists.newArrayList(campaignDAO.findAll());
    List<CampaignType> campaignTypes = apiService.getAllCampaign();
    List<CampaignDTO> campaignEntities = EntityConvertUtils.convertToCamEntity(campaignTypes);
    // 凤巢中的推广单元
    Map<Long, CampaignDTO> campaignEntityMap = new LinkedHashMap<>();
    for (CampaignDTO campaignEntity : campaignEntities) {
      campaignEntity.setAccountId(acid);
      campaignEntityMap.put(campaignEntity.getCampaignId(), campaignEntity);
    }

    List<CampaignDTO> sumList = new ArrayList<>(campaignEntityList);
    sumList.addAll(campaignEntities);
    for (CampaignDTO entity : sumList) {
      Long campaignId = entity.getCampaignId();
      if (campaignId == null) {
        continue;
      }
      if (campaignEntityMap.get(campaignId) != null) {
        campaignEntityMap.remove(campaignId);
      }
    }

    if (campaignEntityMap.size() == 0) {
      return Collections.emptyList();
    } else {
      List<CampaignDTO> campaignDTOList = new ArrayList<>();
      campaignEntityMap
          .values()
          .forEach(
              e -> {
                CampaignDTO campaignDTO = new CampaignDTO();
                BeanUtils.copyProperties(e, campaignDTO);
                campaignDTOList.add(campaignDTO);
              });
      return new ArrayList<>(campaignDTOList);
    }
  }
  @Override
  public void updateAccountData(String userName, long accountId, List<Long> camIds) {
    SystemUserDTO systemUserDTO = getSystemUser(userName);

    if (systemUserDTO == null) {
      return;
    }

    List<BaiduAccountInfoDTO> baiduAccountInfoDTOList = systemUserDTO.getBaiduAccounts();
    if (baiduAccountInfoDTOList == null || baiduAccountInfoDTOList.isEmpty()) {
      return;
    }

    BaiduAccountInfoDTO baiduAccountInfoDTO = null;
    for (BaiduAccountInfoDTO dto : baiduAccountInfoDTOList) {
      if (accountId == dto.getId()) {
        baiduAccountInfoDTO = dto;
        break;
      }
    }

    Objects.requireNonNull(baiduAccountInfoDTO);
    Long acid = baiduAccountInfoDTO.getId();

    CommonService commonService =
        BaiduServiceSupport.getCommonService(
            baiduAccountInfoDTO.getBaiduUserName(),
            baiduAccountInfoDTO.getBaiduPassword(),
            baiduAccountInfoDTO.getToken());
    BaiduApiService apiService = new BaiduApiService(commonService);

    // 获取账户总数据
    AccountInfoType accountInfoType = apiService.getAccountInfo();
    BeanUtils.copyProperties(accountInfoType, baiduAccountInfoDTO);

    // update account data
    updateBaiduAccountInfo(userName, accountId, baiduAccountInfoDTO);

    // 获取指定id的推广计划
    List<CampaignType> campaignTypes = apiService.getCampaignById(camIds);

    // 转换成本地系统的实体
    List<CampaignDTO> campaignEntities = EntityConvertUtils.convertToCamEntity(campaignTypes);

    List<Long> localAdgroupIds = getLocalAdgroupIds(accountId, camIds);
    List<Long> localKeywordIds = getLocalKeywordIds(accountId, localAdgroupIds);
    List<Long> localCreativeIds = getLocalCreativeIds(accountId, localAdgroupIds);

    // clear data
    clearCampaignData(accountId, camIds);
    clearAdgroupData(accountId, localAdgroupIds);
    clearKeywordData(accountId, localKeywordIds);
    clearCreativeData(accountId, localCreativeIds);

    // 凤巢返回回来的计划实体id
    List<Long> campaignIds = new ArrayList<>(campaignEntities.size());

    for (CampaignDTO campaignEntity : campaignEntities) {
      campaignEntity.setAccountId(acid);
      campaignIds.add(campaignEntity.getCampaignId());
    }
    campaignDAO.save(campaignEntities);

    List<AdgroupType> adgroupTypeList = apiService.getAllAdGroup(campaignIds);

    List<AdgroupDTO> adgroupEntities = EntityConvertUtils.convertToAdEntity(adgroupTypeList);

    List<Long> adgroupIds = new ArrayList<>(adgroupEntities.size());
    for (AdgroupDTO adgroupEntity : adgroupEntities) {
      adgroupEntity.setAccountId(acid);
      adgroupIds.add(adgroupEntity.getAdgroupId());
    }
    adgroupDAO.save(adgroupEntities);

    // 分批次请求关键词数据
    List<Long> subList = new ArrayList<>(4);
    for (int i = 1; i <= adgroupIds.size(); i++) {
      Long adgroupId = adgroupIds.get(i - 1);
      subList.add(adgroupId);

      if (i % 4 == 0) {
        List<KeywordType> keywordTypes = apiService.getAllKeyword(subList);
        List<KeywordDTO> keywordEntities = EntityConvertUtils.convertToKwEntity(keywordTypes);

        for (KeywordDTO keywordEntity : keywordEntities) {
          keywordEntity.setAccountId(acid);
        }
        keywordDAO.save(keywordEntities);
        subList.clear();
      }
    }

    if (!subList.isEmpty()) {
      List<KeywordType> keywordTypes = apiService.getAllKeyword(subList);
      List<KeywordDTO> keywordEntities = EntityConvertUtils.convertToKwEntity(keywordTypes);

      for (KeywordDTO keywordEntity : keywordEntities) {
        keywordEntity.setAccountId(acid);
      }
      keywordDAO.save(keywordEntities);
      subList.clear();
    }

    List<CreativeType> creativeTypes = apiService.getAllCreative(adgroupIds);

    List<CreativeDTO> creativeEntityList = EntityConvertUtils.convertToCrEntity(creativeTypes);

    for (CreativeDTO creativeEntity : creativeEntityList) {
      creativeEntity.setAccountId(acid);
    }
    creativeDAO.save(creativeEntityList);
  }
  @Override
  public void updateAccountData(String userName, long accountId) {
    SystemUserDTO systemUserDTO = getSystemUser(userName);
    if (systemUserDTO == null) {
      return;
    }

    List<BaiduAccountInfoDTO> baiduAccountInfoDTOList = systemUserDTO.getBaiduAccounts();

    if (baiduAccountInfoDTOList == null || baiduAccountInfoDTOList.isEmpty()) {
      return;
    }

    // 清除当前账户所有数据
    clearAccountData(accountId);

    BaiduAccountInfoDTO _dto;
    for (BaiduAccountInfoDTO baiduAccountInfoDTO : baiduAccountInfoDTOList) {

      Long aid = baiduAccountInfoDTO.getId();
      if (aid != accountId) continue;

      CommonService commonService =
          BaiduServiceSupport.getCommonService(
              baiduAccountInfoDTO.getBaiduUserName(),
              baiduAccountInfoDTO.getBaiduPassword(),
              baiduAccountInfoDTO.getToken());
      BaiduApiService apiService = new BaiduApiService(commonService);

      // 初始化账户数据
      AccountInfoType accountInfoType = apiService.getAccountInfo();
      boolean isDefault = baiduAccountInfoDTO.isDfault();
      _dto = ObjectUtils.convert(accountInfoType, BaiduAccountInfoDTO.class);
      _dto.setId(accountInfoType.getUserid());
      _dto.setBaiduUserName(baiduAccountInfoDTO.getBaiduUserName());
      _dto.setBaiduPassword(baiduAccountInfoDTO.getBaiduPassword());
      _dto.setToken(baiduAccountInfoDTO.getToken());
      _dto.setDfault(isDefault);

      // 更新账户数据
      updateBaiduAccountInfo(userName, accountId, _dto);

      // 更新推广计划数据
      List<CampaignType> campaignTypes = apiService.getAllCampaign();
      List<CampaignDTO> campaignEntities = EntityConvertUtils.convertToCamEntity(campaignTypes);
      // 查询推广单元
      List<Long> camIds = new ArrayList<>(campaignEntities.size());
      for (CampaignDTO campaignEntity : campaignEntities) {
        campaignEntity.setAccountId(aid);
        camIds.add(campaignEntity.getCampaignId());
      }
      campaignDAO.save(campaignEntities);

      // 更新推广单元数据
      List<AdgroupType> adgroupTypeList = apiService.getAllAdGroup(camIds);
      List<AdgroupDTO> adgroupEntities = EntityConvertUtils.convertToAdEntity(adgroupTypeList);
      List<Long> adgroupIds = new ArrayList<>();
      for (AdgroupDTO adgroupEntity : adgroupEntities) {
        adgroupEntity.setAccountId(aid);
        adgroupIds.add(adgroupEntity.getAdgroupId());
      }
      adgroupDAO.save(adgroupEntities);

      // 分批次请求关键词数据
      List<Long> subList = new ArrayList<>(4);
      for (int i = 1; i <= adgroupIds.size(); i++) {
        Long adgroupId = adgroupIds.get(i - 1);
        subList.add(adgroupId);

        if (i % 4 == 0) {
          List<KeywordType> keywordTypes = apiService.getAllKeyword(subList);
          List<KeywordDTO> keywordEntities = EntityConvertUtils.convertToKwEntity(keywordTypes);

          for (KeywordDTO keywordEntity : keywordEntities) {
            keywordEntity.setAccountId(aid);
          }
          keywordDAO.save(keywordEntities);
          subList.clear();
        }
      }

      if (!subList.isEmpty()) {
        List<KeywordType> keywordTypes = apiService.getAllKeyword(subList);
        List<KeywordDTO> keywordEntities = EntityConvertUtils.convertToKwEntity(keywordTypes);

        for (KeywordDTO keywordEntity : keywordEntities) {
          keywordEntity.setAccountId(aid);
        }
        keywordDAO.save(keywordEntities);
        subList.clear();
      }

      List<CreativeType> creativeTypes = apiService.getAllCreative(adgroupIds);

      List<CreativeDTO> creativeEntityList = EntityConvertUtils.convertToCrEntity(creativeTypes);

      for (CreativeDTO creativeEntity : creativeEntityList) {
        creativeEntity.setAccountId(aid);
      }
      creativeDAO.save(creativeEntityList);
    }
  }