package com.gic.haoban.manage.service.service.impl;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.util.EntityUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.StaffDTO;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.dao.mapper.StaffMapper;
import com.gic.haoban.manage.service.dao.mapper.WxEnterpriseMapper;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.TabHaobanWxEnterprise;
import com.gic.haoban.manage.service.entity.fee.TabHaobanQywxFeeAccountStaff;
import com.gic.haoban.manage.service.service.StaffService;
import com.gic.haoban.manage.service.service.fee.HaobanQywxFeeAccountStaffService;
import com.gic.wechat.api.dto.qywx.fee.AccountListDTO;
import com.gic.wechat.api.dto.qywx.fee.AccountListResponseDTO;
import com.gic.wechat.api.dto.qywx.fee.ActiveInfoUserResponseDTO;
import com.gic.wechat.api.service.qywx.QywxOrderApiService;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.hutool.core.date.DateUtil;

@Service
public class StaffServiceImpl implements StaffService {
    private static final Logger log = LogManager.getLogger(StaffServiceImpl.class);

    @Autowired
    private StaffMapper mapper;
    @Autowired
    private QywxOrderApiService qywxOrderApiService ;
    @Autowired
    private WxEnterpriseMapper wxEnterpriseMapper ;
    @Autowired
    private Config config ;
    @Autowired
    private HaobanQywxFeeAccountStaffService haobanQywxFeeAccountStaffService;
    @Autowired
    private QywxUserApiService qywxUserApiService ;
    
    @Override
    public TabHaobanStaff selectById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public TabHaobanStaff selectByNationcodeAndPhoneNumber(String wxEnterpriseId, String nationcode, String phoneNumber) {
        if (StringUtils.isBlank(phoneNumber)) {
            return null;
        }
        return mapper.selectByNationcodeAndPhoneNumber(wxEnterpriseId, nationcode, phoneNumber);
    }

    @Override
    public String add(TabHaobanStaff tab) {
        Date now = new Date();
        tab.setCreateTime(now);
        tab.setUpdateTime(now);
        if (StringUtils.isBlank(tab.getStaffId())) {
            tab.setStaffId(StringUtil.randomUUID());
        }
        tab.setStatusFlag(1);
        tab.setAddNum(0);
        mapper.insertSelective(tab);
        return tab.getStaffId();
    }

    @Override
    public Page<TabHaobanStaff> pageStaff(List<String> staffIds, Integer activeFlag, String keyword,List<String> departmentIds,String wxEnterpriseId,Integer relationFlag,String permitState,
            Integer occupy) {
        return mapper.pageStaff(staffIds, activeFlag, keyword,departmentIds,wxEnterpriseId,relationFlag,permitState,occupy);
    }

    @Override
    public TabHaobanStaff selectByUserIdAndEnterpriseId(String userId, String wxEnterpriseId) {
        return mapper.selectByUserIdAndEnterpriseId(userId, wxEnterpriseId);
    }

    @Override
    public TabHaobanStaff selectByUserIdAndEnterpriseId(String wxUserId, String wxOpenUserId , String wxEnterpriseId) {
        if (StringUtils.isBlank(wxUserId)) {
            log.info("wxUserId is null");
            return null;
        }
        TabHaobanStaff staff = this.mapper.selectByUserIdAndEnterpriseId(wxUserId, wxEnterpriseId) ;
        if (null == staff && null != wxOpenUserId && !wxUserId.equals(wxOpenUserId)) {
            return  this.mapper.selectByUserIdAndEnterpriseId(wxOpenUserId, wxEnterpriseId) ;
        }
        return staff;
    }

    @Override
    public void updateByPrimaryKey(TabHaobanStaff tab) {
        tab.setUpdateTime(new Date());
        mapper.updateByPrimaryKeySelective(tab);
    }

    @Override
    public int delByStaffId(String staffId) {
        return this.mapper.delStaff(staffId);
    }

    @Override
    public List<StaffDTO> listByUserIdsAndWxEnterpriseId(List<String> userIds, String wxEnterpriseId) {
        return EntityUtil.changeEntityListByJSON(StaffDTO.class, this.mapper.listByUserIdsAndWxEnterpriseId(userIds, wxEnterpriseId));
    }

    @Override
    public int cleanStaff(String wxEnterpriseId, List<String> staffIds) {
        return mapper.cleanStaff(wxEnterpriseId, staffIds);
    }

    @Override
    public List<String> listDelUserStaffId(String wxEnterpriseId, List<String> staffIds) {
        return mapper.listUserStaffId(wxEnterpriseId, staffIds);
    }

    @Override
    public List<TabHaobanStaff> listNoStatusByStaffIds(String wxEnterpriseId, List<String> staffIds) {
        return mapper.listNoStatusStaffIds(wxEnterpriseId, staffIds);
    }

    @Override
    public int updateOpenUserIdsByUserId(String wxEnterpriseId, String wxUserId, String wxOpenUseId) {
        return mapper.updateOpenUserIdsByUserId(wxEnterpriseId, wxUserId, wxOpenUseId);
    }

    @Override
    public void delOtherStaffByWxUserId(String wxUserId, String staffId, String wxEnterpriseId) {
        mapper.delOtherStaffByWxUserId(wxUserId, staffId, wxEnterpriseId);
    }

    @Override
    public int updateAddNumById(String staffId) {
        return mapper.updateAddNumById(staffId);
    }

    @Override
    public int resetAddNum() {
        return mapper.resetAddNum();
    }
    
    @Override
    public int updateActiveStatusById(String staffId,  Date activeTime, Date expireTime,
            String activeCode) {
        return mapper.updateActiveStatusById(staffId, activeTime, expireTime, activeCode) ;
    }
    
    @Override
    public void updateOpenConcatFlag(List<String> wxUserIdList,int mixFlag) {
        if(CollectionUtils.isEmpty(wxUserIdList)) {
            return ;
        }
        this.mapper.updateOpenConcatFlag(wxUserIdList,mixFlag);
    }
    
    @Override
    public void activedAccountTimer(String wxEid) {
        log.info("开始查询激活账号,wxEid={}", wxEid);
        TabHaobanWxEnterprise wxEnterprise = this.wxEnterpriseMapper.selectByPrimaryKey(wxEid) ;
        if(wxEnterprise.getWxSecurityType()>0 && StringUtils.isNotEmpty(wxEnterprise.getOpenCorpid()) && wxEnterprise.getStatusFlag()==1) {
            this.haobanQywxFeeAccountStaffService.deleteAll(wxEid) ;
            this.mapper.deleteActivieInfo(wxEid); 
            this.listAccount(wxEnterprise, 500, null);
        }
    }

    @Override
    public Integer getOccupyNum(String wxEnterpriseId) {
        return mapper.getOccupyNum(wxEnterpriseId);
    }

    private void listAccount(TabHaobanWxEnterprise wxEnterprise , int limit , String cursor) {
        String wxEnterpriseId = wxEnterprise.getWxEnterpriseId() ;
        String openCorpid = wxEnterprise.getOpenCorpid() ;
        ServiceResponse<AccountListResponseDTO>  resp = this.qywxOrderApiService.listActivedAccount(config.getCorpid(), openCorpid, limit, cursor) ;
        log.info("查询激活账号,wxEid={},返回={}",wxEnterpriseId,JSON.toJSONString(resp));
        if(resp.isSuccess()) {
            AccountListResponseDTO dto = resp.getResult() ;
            List<AccountListDTO> list = dto.getAccountList() ;
            log.info("查询激活账号,size={},wxeid={}",list.size(),wxEnterpriseId);
            this.updateAccount(wxEnterpriseId,openCorpid, list);
            cursor = dto.getNextCursor() ;
            Integer hasMore = dto.getHasMore() ;
            // 从企微拉取下一批数据
            if (StringUtils.isNotBlank(cursor) && null !=hasMore &&  hasMore==1) {
                this.listAccount(wxEnterprise, limit , cursor);
            }
        }
    }
    
    private void updateAccount(String wxEnterpriseId , String openCorpid ,List<AccountListDTO> list) {
        for(AccountListDTO item : list) {
            String userId = item.getUserid() ;
            ActiveInfoUserResponseDTO activeInfoUserResponseDTO = qywxUserApiService.getActiveInfoByUser(openCorpid, config.getCorpid(), userId);
            log.info("查询用户激活详情={},{}",JSON.toJSONString(activeInfoUserResponseDTO),userId);
            String activeCode = null ;
            if (activeInfoUserResponseDTO.getErrcode() == 0) {
                for(AccountListDTO dto : activeInfoUserResponseDTO.getActiveInfoList()) {
                    if(dto.getType()==2) {
                        activeCode = dto.getActiveCode() ;
                    }
                }
            }
            if(StringUtils.isEmpty(activeCode)){
                log.info("无互通激活码={}",userId);
                continue ;
            }
            Date start = new Date(item.getActiveTime()*1000L) ;
            Date end = new Date(item.getExpireTime()*1000L) ;
            log.info("更新staff表,userId={}",userId);
            TabHaobanStaff staff = this.mapper.selectByUserIdAndEnterpriseId(userId, wxEnterpriseId) ;
            if(null == staff && end.getTime()>System.currentTimeMillis()) {
                staff = this.mapper.getDeleteUser(userId, wxEnterpriseId) ;
            }
            if(null != staff) {
                this.updateActiveStatusById(staff.getStaffId(), start, end, activeCode) ;
            }else {
                log.info("查询激活账号,用户不存在,userid={}",userId);
            }
            TabHaobanQywxFeeAccountStaff accountStaff = new TabHaobanQywxFeeAccountStaff();
            accountStaff.setFeeAccountStaffId(UniqueIdUtils.uniqueLong());
            accountStaff.setWxEnterpriseId(wxEnterpriseId);
            accountStaff.setCorpId(openCorpid);
            accountStaff.setActiveCode(activeCode);
            accountStaff.setWxUserId(userId);
            accountStaff.setAccountType(item.getType());
            accountStaff.setExpireTime(DateUtil.date(item.getExpireTime() * 1000));
            accountStaff.setActiveTime(DateUtil.date(item.getActiveTime() * 1000));
            this.haobanQywxFeeAccountStaffService.save(accountStaff);
        }
    }
    
}
