package com.gic.haoban.manage.web.controller.open;

import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.BasePageInfo;
import com.gic.api.base.commons.JSONResponse;
import com.gic.api.base.commons.Page;
import com.gic.api.base.commons.ServiceResponse;
import com.gic.clerk.api.dto.AuthorizedUser;
import com.gic.commons.util.DateUtil;
import com.gic.commons.util.PageHelperUtils;
import com.gic.commons.webapi.reponse.RestResponse;
import com.gic.enterprise.api.dto.EnterpriseDTO;
import com.gic.enterprise.api.dto.EnterpriseUsingPermissionDto;
import com.gic.enterprise.api.dto.WechatWorkServiceSetting;
import com.gic.enterprise.api.service.EnterpriseService;
import com.gic.enterprise.api.service.EnterpriseUseForbidService;
import com.gic.haoban.base.api.common.pojo.dto.WebLoginDTO;
import com.gic.haoban.common.utils.AuthWebRequestUtil;
import com.gic.haoban.common.utils.EntityUtil;
import com.gic.haoban.manage.api.dto.*;
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.api.service.StaffApiService;
import com.gic.haoban.manage.api.service.StaffClerkRelationApiService;
import com.gic.haoban.manage.web.qo.open.OpenStaffQO;
import com.gic.haoban.manage.web.vo.open.OpenQwAccountInfoVO;
import com.gic.haoban.manage.web.vo.open.OpenStaffVO;
import com.gic.qcloud.BucketNameEnum;
import com.gic.web.common.download.DownloadTask;
import com.gic.web.common.download.DownloadTaskUtil;
import com.gic.web.common.download.constants.TaskTypeEnum;
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.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 企微托管
 */
@RestController
@RequestMapping("/qw-open")
public class QywxOpenController {

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

    @Autowired
    private OpenStaffApiService openStaffApiService;
    @Autowired
    private StaffApiService staffApiService;
    @Autowired
    private StaffClerkRelationApiService staffClerkRelationApiService;
    @Autowired
    private EnterpriseService enterpriseService;
    @Autowired
    private OpenStaffExcelHandler openStaffExcelHandler;
    @Autowired
    private EnterpriseUseForbidService enterpriseUseForbidService;

    /**
     * 托管列表
     *
     * @param qo
     * @return
     */
    @RequestMapping("open-staff-page")
    public RestResponse<Page<OpenStaffVO>> page(@RequestBody OpenStaffQO qo) {
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        OpenStaffPageQDTO qdto = EntityUtil.changeEntityByJSON(OpenStaffPageQDTO.class, qo);
        String enterpriseId = loginUser.getEnterpriseId();
        qdto.setWxEnterpriseId(loginUser.getWxEnterpriseId());
        qdto.setEnterpriseId(enterpriseId);
        BasePageInfo basePageInfo = new BasePageInfo();
        basePageInfo.setPageNum(qo.getPageNum());
        basePageInfo.setPageSize(qo.getPageSize());
        if (null != qdto.getEndDate()) {
            qdto.setEndDate(DateUtil.getEndTimeOfDay(qdto.getEndDate()));
        }
        ServiceResponse<Page<OpenStaffListDTO>> pageResp = this.openStaffApiService.page(qdto, basePageInfo);
        Page<OpenStaffListDTO> page = pageResp.getResult();
        Page<OpenStaffVO> retPage = PageHelperUtils.changePageToCurrentPage(page, OpenStaffVO.class);
        if (CollectionUtils.isNotEmpty(retPage.getResult())) {
            EnterpriseDTO en = this.enterpriseService.getEnterpriseById(enterpriseId);
            retPage.getResult().forEach(o -> {
                o.setBrandName(en.getBrandName());
            });
        }
        return RestResponse.successResult(retPage);
    }

    /**
     * 托管列表导出
     *
     * @param qo
     * @return
     */
    @RequestMapping("open-staff-excel")
    public RestResponse<String> excel(@RequestBody OpenStaffQO qo) {
        WebLoginDTO loginUser = AuthWebRequestUtil.getLoginUser();
        OpenStaffPageQDTO qdto = EntityUtil.changeEntityByJSON(OpenStaffPageQDTO.class, qo);
        qdto.setWxEnterpriseId(loginUser.getWxEnterpriseId());
        qdto.setEnterpriseId(loginUser.getEnterpriseId());
        BasePageInfo basePageInfo = new BasePageInfo();
        basePageInfo.setPageNum(1);
        basePageInfo.setPageSize(1);
        if (null != qdto.getEndDate()) {
            qdto.setEndDate(DateUtil.getEndTimeOfDay(qdto.getEndDate()));
        }
        ServiceResponse<Page<OpenStaffListDTO>> pageResp = this.openStaffApiService.page(qdto, basePageInfo);
        final int totalCount = pageResp.getResult().getTotalCount();
        if (totalCount == 0) {
            return RestResponse.failure("9999", "导出数据条数为0");
        }
        AuthorizedUser user = new AuthorizedUser();
        user.setUserId(loginUser.getClerkId());
        user.setEnterpriseId(loginUser.getEnterpriseId());
        user.setRealName(loginUser.getClerkName());
        String fileName = "好办托管企微号";
        Date startDate = qdto.getStartDate();
        Date endDate = qdto.getEndDate();
        if (null != startDate && null != endDate) {
            fileName = "好办托管企微号" + "-" + DateUtil.formatString(startDate, "yyyy-MM-dd") + "到" + DateUtil.formatString(endDate, "yyyy-MM-dd");
        }
        // 1.组装数据查询条件
        DownloadTask task = new DownloadTask();
        task.setTaskTypeEnum(TaskTypeEnum.HAOBAN_OPEN_STAFF_LIST);
        task.setUser(user);
        task.setDataType(1);
        task.setTotalCount(totalCount);
        task.setFileName(fileName);
        task.setChannelName(TaskTypeEnum.HAOBAN_OPEN_STAFF_LIST.getName());
        task.setBucketName(BucketNameEnum.REPORT_50000.getName());
        task.setSearchDataParams(JSON.toJSONStringWithDateFormat(qdto, DatePattern.NORM_DATETIME_PATTERN));
        task.setHandler(openStaffExcelHandler);
        JSONResponse jsonResponse = DownloadTaskUtil.createDownloadTask(task);
        final String reportId;
        if (jsonResponse.isSuccess()) {
            reportId = (String) jsonResponse.getResult();
        } else {
            return RestResponse.failure("9999", jsonResponse.getErrorMessage());
        }
        return RestResponse.successResult(reportId);
    }

    /**
     * 登录初始化
     *
     * @param staffId
     * @return
     */
    @RequestMapping("login-init")
    public RestResponse<OpenStaffDTO> init(String staffId, @RequestParam(defaultValue = "0") int loginAgainFlag) {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        String enterpriseId = login.getEnterpriseId();
        String checkMsg = this.check(wxEnterpriseId, enterpriseId);
        if (null != checkMsg) {
            return RestResponse.failure("9999", checkMsg);
        }
        if (StringUtils.isBlank(staffId)) {
            return RestResponse.failure("9999", "请先选择成员");
        }
        StaffDTO staff = this.staffApiService.selectById(staffId);
        if (null == staff || !staff.getWxEnterpriseId().equals(wxEnterpriseId)) {
            return RestResponse.failure("9999", "成员不存在");
        }
        List<StaffClerkRelationDTO> relationList = this.staffClerkRelationApiService.listByStaffId(wxEnterpriseId, staffId);
        if (CollectionUtils.isEmpty(relationList)) {
            return RestResponse.failure("9999", "成员未关联导购");
        }
        relationList = relationList.stream().filter(o -> o.getClerkType() <= 1 && o.getEnterpriseId().equals(enterpriseId)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(relationList)) {
            return RestResponse.failure("9999", "成员需关联gic商户下导购");
        }
        OpenStaffInitQDTO initQDTO = new OpenStaffInitQDTO();
        initQDTO.setWxEnterpriseId(wxEnterpriseId);
        initQDTO.setEnterpriseId(enterpriseId);
        initQDTO.setStaffId(staffId);
        initQDTO.setLoginAgainFlag(loginAgainFlag);
        ServiceResponse<OpenStaffDTO> resp = this.openStaffApiService.init(initQDTO);
        if (!resp.isSuccess()) {
            return RestResponse.failure("9999", resp.getMessage());
        }
        OpenStaffDTO openStaffDTO = resp.getResult();
        openStaffDTO.setStaffHeadImg(staff.getHeadImg());
        openStaffDTO.setStaffName(staff.getStaffName());
        return RestResponse.successResult(openStaffDTO);
    }

    /**
     * 获取账号详情
     *
     * @param openStaffId
     * @return
     */
    @RequestMapping("get-open-staff")
    public RestResponse<OpenStaffDTO> getOpenStaff(Long openStaffId) {
        ServiceResponse<OpenStaffDTO> resp = this.openStaffApiService.getById(openStaffId);
        if (!resp.isSuccess()) {
            return RestResponse.failure("9999", resp.getMessage());
        }
        OpenStaffDTO openStaffDTO = resp.getResult();
        StaffDTO staff = this.staffApiService.selectById(openStaffDTO.getStaffId());
        openStaffDTO.setStaffHeadImg(staff.getHeadImg());
        openStaffDTO.setStaffName(staff.getStaffName());
        return RestResponse.successResult(openStaffDTO);
    }

    /**
     * 校验验证码
     *
     * @param openStaffId
     * @param code
     * @return
     */
    @RequestMapping("check-code")
    public RestResponse<Void> checkCode(Long openStaffId, String code) {
        ServiceResponse<Void> resp = this.openStaffApiService.checkCode(openStaffId, code);
        if (!resp.isSuccess()) {
            return RestResponse.failure("9999", resp.getMessage());
        }
        return RestResponse.successResult();
    }

    /**
     * 获取2次验证二维码
     *
     * @param openStaffId
     * @return
     */
    @RequestMapping("get-2qrcode")
    public RestResponse<OpenStaffDTO> get2Qrcode(Long openStaffId) {
        ServiceResponse<OpenStaffDTO> resp = this.openStaffApiService.get2Qrcode(openStaffId);
        if (!resp.isSuccess()) {
            return RestResponse.failure("9999", resp.getMessage());
        }
        return RestResponse.successResult(resp.getResult());
    }

    /**
     * 许可数量查询
     */
    @RequestMapping("license-info")
    public RestResponse<OpenQwAccountInfoVO> licenseInfo() {
        WebLoginDTO login = AuthWebRequestUtil.getLoginUser();
        String wxEnterpriseId = login.getWxEnterpriseId();
        String enterpriseId = login.getEnterpriseId();
        OpenQwAccountInfoVO vo = this.getCheckInfo(wxEnterpriseId, enterpriseId);
        return RestResponse.successResult(vo);
    }

    /**
     * 删除托管
     *
     * @return
     */
    @RequestMapping("del-open-staff")
    public RestResponse<Void> delOpenStaff(Long openStaffId) {
        ServiceResponse<Void> resp = this.openStaffApiService.delete(openStaffId);
        if (!resp.isSuccess()) {
            return RestResponse.failure("9999", resp.getMessage());
        }
        return RestResponse.successResult();
    }

    /**
     * 取消授权
     *
     * @return
     */
    @RequestMapping("cancel-open-staff")
    public RestResponse<Void> cancelOpenStaff(Long openStaffId) {
        ServiceResponse<Void> resp = this.openStaffApiService.logout(openStaffId);
        if (!resp.isSuccess()) {
            return RestResponse.failure("9999", resp.getMessage());
        }
        return RestResponse.successResult();
    }

    private String check(String wxEnterpriseId, String enterpriseId) {
        OpenQwAccountInfoVO vo = this.getCheckInfo(wxEnterpriseId, enterpriseId);
        if (vo.getStatus() == 0) {
            return "请联系商务经理购买服务后再进行账号托管";
        }
        if (vo.getStatus() == 2) {
            return "当前企微服务已过期";
        }
        if (vo.getGicTotal() <= vo.getUseNum()) {
            return "托管账号数量已达上线";
        }
        return null;
    }

    private OpenQwAccountInfoVO getCheckInfo(String wxEnterpriseId, String enterpriseId) {
        OpenQwAccountInfoVO vo = new OpenQwAccountInfoVO();
        ServiceResponse<EnterpriseUsingPermissionDto> resp = this.enterpriseUseForbidService.getWxEnterpriseService(enterpriseId, wxEnterpriseId);
        log.info("托管许可={}", JSONObject.toJSONString(resp));
        if (resp.isSuccess()) {
            EnterpriseUsingPermissionDto dto = resp.getResult();
            if (null == dto) {
                vo.setStatus(0);
            } else {
                vo.setExpireDate(dto.getServiceEndDate());
                vo.setStatus(1);
                if (dto.getServiceEndDate().before(new Date())) {
                    vo.setStatus(2);
                }
                String json = dto.getModuleSetting();
                WechatWorkServiceSetting bo = JSONObject.parseObject(json, WechatWorkServiceSetting.class);
                vo.setGicTotal(bo.getAccountNumber());
                vo.setVersion(dto.getModuleVersion());
            }
        }
        ServiceResponse<OpenStaffLicenseDTO> hbResp = this.openStaffApiService.getLicenseInfo(wxEnterpriseId, enterpriseId);
        vo.setUseNum(hbResp.getResult().getUseNum());
        vo.setValidNum(hbResp.getResult().getValidNum());
        log.info("OpenQwAccountInfoVO={}", JSONObject.toJSONString(vo));
        return vo;
    }

}
