package com.gic.haoban.manage.service.service.out.impl;

import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.BasePageInfo;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.commons.util.EntityUtil;
import com.gic.haoban.manage.api.dto.OpenStaffDTO;
import com.gic.haoban.manage.api.dto.OpenStaffLicenseDTO;
import com.gic.haoban.manage.api.dto.OpenStaffListDTO;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.enums.QwOpenStepEnum;
import com.gic.haoban.manage.api.qdto.OpenStaffInitQDTO;
import com.gic.haoban.manage.api.qdto.OpenStaffPageQDTO;
import com.gic.haoban.manage.api.service.OpenStaffApiService;
import com.gic.haoban.manage.service.dao.mapper.OpenStaffMapper;
import com.gic.haoban.manage.service.entity.TabOpenStaff;
import com.gic.haoban.manage.service.pojo.QwOpenResultInitBO;
import com.gic.haoban.manage.service.service.OpenStaffService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.util.OpenUtils;
import com.gic.redis.data.util.RedisUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.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 java.util.Date;
import java.util.List;

/**
 * 企微托管账号
 */
@Service("openStaffApiService")
public class OpenStaffApiServiceImpl implements OpenStaffApiService {

    private static final Logger log = LogManager.getLogger(OpenStaffApiService.class);

    @Autowired
    private OpenStaffMapper openStaffMapper ;
    @Autowired
    private OpenStaffService openStaffService ;
    @Autowired
    private WxEnterpriseService wxEnterpriseService ;

    @Override
    public ServiceResponse<Void> delete(Long id) {
        TabOpenStaff staff = this.openStaffMapper.getById(id) ;
        if(null != staff){
            this.openStaffService.logout(staff.getUuid(),"删除",0,null) ;
        }
        this.openStaffMapper.deleteByPrimaryKey(id) ;
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> updateValiFlag(String uuid) {
        this.openStaffMapper.updateValidFlag(uuid) ;
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> update2QrcodeFlag(String uuid) {
        TabOpenStaff openStaff = this.openStaffService.getByUUID(uuid) ;
        if(null == openStaff) {
            return ServiceResponse.failure("9999","登录错误") ;
        }
        this.openStaffMapper.update2QrcodeFlag(openStaff.getOpenStaffId());
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<OpenStaffDTO> get2Qrcode(long id) {
        TabOpenStaff openStaff = this.openStaffMapper.getById(id) ;
        if(null == openStaff) {
            return ServiceResponse.failure("9999","登录错误") ;
        }
        ServiceResponse<QwOpenResultInitBO> resp = OpenUtils.getQrcode(openStaff.getUuid(),null,2) ;
        String qrcodeData = null ;
        if(resp.isSuccess()) {
            String qrcode= resp.getResult().getQrcode() ;
            String key = resp.getResult().getKey() ;
            this.openStaffMapper.update2Qrcode(openStaff.getOpenStaffId(),qrcode,key);
            openStaff.setQrCode2(qrcode);
            qrcodeData = resp.getResult().getQrcode_data() ;
        }else {
            return ServiceResponse.failure("9999",resp.getMessage()) ;
        }
        OpenStaffDTO dto = EntityUtil.changeEntityByJSON(OpenStaffDTO.class,openStaff) ;
        dto.setQrcodeData(qrcodeData);
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<Void> updateLoginStep(String uuid, int step) {
        TabOpenStaff openStaff = this.openStaffService.getByUUID(uuid) ;
        if(null == openStaff) {
            return ServiceResponse.failure("9999","登录错误") ;
        }
        this.openStaffMapper.updateLoginStep(openStaff.getOpenStaffId(),step) ;
        if(QwOpenStepEnum.isFail(step)) {
            this.openStaffService.logout(uuid,"企微返回退出/登录超时",0, null);
        }
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> login(String uuid, Long qwCorpId, String corpName, Long qwUserId) {
        TabOpenStaff openStaff = this.openStaffService.getByUUID(uuid) ;
        if(null == openStaff) {
            return ServiceResponse.failure("9999","登录错误") ;
        }
        String wxEnterpriseId = openStaff.getWxEnterpriseId() ;
        List<String> backWxEnterpriseIdList = this.wxEnterpriseService.getWxEnterpriseIdByName(corpName) ;
        if(CollectionUtils.isEmpty(backWxEnterpriseIdList) || backWxEnterpriseIdList.size()>1 || !backWxEnterpriseIdList.get(0).equals(wxEnterpriseId)) {
            this.openStaffService.logout(uuid,"授权登录账号与当前账号不一致",10, null);
            log.info("登录的企业不对={},{}",uuid,corpName);
            return ServiceResponse.failure("9999","登录错误") ;
        }
        TabOpenStaff staff = this.openStaffMapper.getByQwUserId(qwUserId) ;
        if(null != staff && staff.getWxEnterpriseId().equals(wxEnterpriseId)) {
            this.openStaffService.logout(uuid,"只能托管一个企微企业",0 , null);
            log.info("只能托管一个企业={},{}",uuid,corpName);
            return ServiceResponse.failure("9999","只能托管一个企业") ;
        }
        openStaff.setWxCorpId(qwCorpId);
        openStaff.setQwUserId(qwUserId);
        if(null == openStaff.getFirstAuthTime()) {
            openStaff.setFirstAuthTime(new Date());
        }
        openStaff.setAuthTime(new Date());
        openStaff.setStatusFlag(1);
        this.openStaffMapper.update(openStaff);
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> logout(String uuid) {
        this.openStaffService.logout(uuid,"手机端结束登录",0 , "手机端结束登录");
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> logout(Long openStaffId) {
        TabOpenStaff staff = this.openStaffMapper.getById(openStaffId) ;
        this.openStaffService.logout(staff.getUuid(),"取消授权",0 , null);
        return ServiceResponse.success();
    }

    @Override
    public ServiceResponse<Void> checkCode(Long openStaffId, String validCode) {
        TabOpenStaff tab = this.openStaffMapper.getById(openStaffId) ;
        if(null == tab) {
            return ServiceResponse.failure("9999","记录不存在") ;
        }
        return OpenUtils.checkCode(tab.getUuid(),tab.getKey1(),validCode) ;
    }

    @Override
    public ServiceResponse<OpenStaffDTO> getById(Long openStaffId) {
        TabOpenStaff openStaff = this.openStaffMapper.getById(openStaffId) ;
        if(null == openStaff) {
            return ServiceResponse.failure("9999","已删除")  ;
        }
        OpenStaffDTO dto = EntityUtil.changeEntityByJSON(OpenStaffDTO.class,openStaff) ;
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<OpenStaffDTO> getByQwUserId(Long qwUserId) {
        TabOpenStaff openStaff = this.openStaffMapper.getByQwUserId(qwUserId) ;
        if(null == openStaff) {
            return ServiceResponse.failure("9999","已删除")  ;
        }
        OpenStaffDTO dto = EntityUtil.changeEntityByJSON(OpenStaffDTO.class,openStaff) ;
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<OpenStaffDTO> init(OpenStaffInitQDTO qdto) {
        String staffId = qdto.getStaffId();
        if(StringUtils.isBlank(staffId)) {
            log.info("staffId is null");
            return ServiceResponse.failure("9999","staffId为空") ;
        }
        String lockKey = "lock:qywx:open:"+staffId ;
        try {
            RedisUtil.lock(lockKey , 3L);
            TabOpenStaff openStaff = this.openStaffMapper.getByStaffId(staffId) ;
            Long qwUserId = null ;
            if(null != openStaff) {
                if(openStaff.getStatusFlag()==1 && qdto.getLoginAgainFlag()==0) {
                    return ServiceResponse.failure("9999","成员已托管中") ;
                }
                qwUserId = openStaff.getQwUserId() ;
                log.info("重新初始化");
                this.openStaffService.logout(openStaff.getUuid(),"重新初始化",0, null);
            }
            if(null == openStaff) {
                openStaff = new TabOpenStaff() ;
                openStaff.setStaffId(staffId);
                openStaff.setWxEnterpriseId(qdto.getWxEnterpriseId());
                openStaff.setEnterpriseId(qdto.getEnterpriseId());
            }
            ServiceResponse<QwOpenResultInitBO> resp = OpenUtils.init(qwUserId) ;
            log.info("resp={}", JSONObject.toJSONString(resp));
            QwOpenResultInitBO init = resp.getResult() ;
            openStaff.setUuid(init.getUuid());
            openStaff.setQrCode1(init.getQrcode());
            openStaff.setKey1(init.getKey());
            openStaff.setStatusFlag(2);
            openStaff.setStep(0);
            openStaff.setValidFlag(0);
            openStaff.setValidQrcodeFlag(0);
            openStaff.setQrCode2(null);
            openStaff.setKey2(null);
            openStaff = this.openStaffService.save(openStaff);
            OpenStaffDTO dto = EntityUtil.changeEntityByJSON(OpenStaffDTO.class,openStaff) ;
            dto.setQrcodeData(init.getQrcode_data()) ;
            return ServiceResponse.success(dto) ;
        }catch (Exception e) {
            log.info("异常",e);
        }
        return ServiceResponse.failure("9999","登录失败") ;
    }

    @Override
    public ServiceResponse<OpenStaffLicenseDTO> getLicenseInfo(String wxEnterpriseId, String enterpriseId) {
        OpenStaffLicenseDTO dto = new OpenStaffLicenseDTO();
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<Page<OpenStaffListDTO>> page(OpenStaffPageQDTO qdto, BasePageInfo basePageInfo) {
        return this.openStaffService.page(qdto,basePageInfo);
    }

    @Override
    public ServiceResponse<OpenStaffDTO> getByStaffId(String staffId) {
        TabOpenStaff tab = this.openStaffMapper.getByStaffId(staffId) ;
        if(null == tab) {
            return ServiceResponse.failure("9999","已删除")  ;
        }
        OpenStaffDTO dto = EntityUtil.changeEntityByJSON(OpenStaffDTO.class,tab) ;
        return ServiceResponse.success(dto);
    }

    @Override
    public ServiceResponse<OpenStaffDTO> getByUUID(String uuid) {
        TabOpenStaff tab = this.openStaffMapper.getByUUID(uuid) ;
        if(null == tab) {
            return ServiceResponse.failure("9999","不存在")  ;
        }
        OpenStaffDTO dto = EntityUtil.changeEntityByJSON(OpenStaffDTO.class,tab) ;
        return ServiceResponse.success(dto);
    }

    @Override
    public List<StaffClerkRelationDTO> listOpenStaffByClerk(String wxEnterpriseId, String enterpriseId, List<String> clerkIdList) {
        return this.openStaffMapper.listOpenStaffByClerk(wxEnterpriseId,enterpriseId,clerkIdList);
    }

    @Override
    public List<StaffClerkRelationDTO> listOpenStaffByStore(String wxEnterpriseId, String enterpriseId, List<String> storeIdList) {
        return this.openStaffMapper.listOpenStaffByStore(wxEnterpriseId,enterpriseId,storeIdList);
    }

    @Override
    public List<String> listAllOnlineStaff() {
        return this.openStaffMapper.listAll();
    }

    @Override
    public List<String> listOpenStoreId(String wxEnterpriseId, String enterpriseId) {
        return this.openStaffMapper.listOpenStoreId(wxEnterpriseId,enterpriseId);
    }

    @Override
    public void updateStopTime(Long openStaffId, int type, int time) {
        this.openStaffMapper.updateStopTime(openStaffId,type,time) ;
    }
}
