package org.jeecg.modules.system.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeecg.dingtalk.api.core.response.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.constant.enums.MessageTypeEnum;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.system.entity.SysThirdAccount;
import org.jeecg.modules.system.entity.SysThirdAppConfig;
import org.jeecg.modules.system.service.ISysThirdAccountService;
import org.jeecg.modules.system.service.ISysThirdAppConfigService;
import org.jeecg.modules.system.service.impl.DingtalkServiceImpl;
import org.jeecg.modules.system.vo.thirdapp.SyncInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 第三方App对接
 *
 * @author: jeecg-boot
 */
@Slf4j
@RestController("thirdAppController")
@RequestMapping("/sys/thirdApp")
public class ThirdAppController {

    @Autowired
    private DingtalkServiceImpl dingtalkService;

    @Autowired
    private ISysThirdAppConfigService appConfigService;

    @Autowired
    private ISysThirdAccountService sysThirdAccountService;

    /**
     * 获取启用的系统
     */
    @GetMapping("/getEnabledType")
    public Result getEnabledType() {
        Map<String, Boolean> enabledMap = new HashMap(1);
        enabledMap.put(MessageTypeEnum.DD.getType(), true);
        return Result.OK(enabledMap);
    }

    /**
     * 撤回消息测试
     *
     * @return
     */
    @PostMapping("/recallMessageTest")
    public Result recallMessageTest(@RequestBody JSONObject params) {
        /* 获取前台传递的参数 */
        // 第三方app的类型
        String app = params.getString("app");
        // 消息id
        String msgTaskId = params.getString("msg_task_id");
        if (CommonConstant.DINGTALK.equals(app)) {
            SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(MessageTypeEnum.DD.getType());
            if (null != config) {
                Response<JSONObject> response = dingtalkService.recallMessageResponse(msgTaskId);
                if (response.isSuccess()) {
                    return Result.OK("撤回成功", response);
                } else {
                    return Result.error("撤回失败：" + response.getErrcode() + "——" + response.getErrmsg(), response);
                }
            }
            return Result.error("钉钉尚未配置,请配置钉钉");
        }
        return Result.error("不识别的第三方APP");
    }

    //========================begin 应用低代码钉钉/企业微信同步用户部门专用 =============================

    /**
     * 添加第三方app配置
     *
     * @param appConfig
     * @return
     */
    @RequestMapping(value = "/addThirdAppConfig", method = RequestMethod.POST)
    public Result<String> addThirdAppConfig(@RequestBody SysThirdAppConfig appConfig) {
        Result<String> result = new Result<>();
        // 根据当前登录租户id和第三方类别判断是否已经创建
        SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(appConfig.getThirdType());
        if (null != config) {
            result.error500("操作失败,同一个租户下只允许绑定一个钉钉或者企业微信");
            return result;
        }
        String clientId = appConfig.getClientId();
        // 通过应用key获取第三方配置
        List<SysThirdAppConfig> thirdAppConfigByClientId = appConfigService.getThirdAppConfigByClientId(clientId);
        if (CollectionUtil.isNotEmpty(thirdAppConfigByClientId)) {
            result.error500("AppKey已存在，请勿重复添加");
            return result;
        }
        try {
            appConfigService.save(appConfig);
            result.success("添加成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }
        return result;
    }

    /**
     * 编辑第三方app配置
     *
     * @param appConfig
     * @return
     */
    @RequestMapping(value = "/editThirdAppConfig", method = {RequestMethod.PUT, RequestMethod.POST})
    public Result<String> editThirdAppConfig(@RequestBody SysThirdAppConfig appConfig) {
        Result<String> result = new Result<>();
        SysThirdAppConfig config = appConfigService.getById(appConfig.getId());
        if (null == config) {
            result.error500("数据不存在");
            return result;
        }
        String clientId = appConfig.getClientId();
        // 如果编辑的应用key,和数据库中的不一致，需要判断应用key是否已存在
        if (!clientId.equals(config.getClientId())) {
            // 通过应用key获取第三方配置
            List<SysThirdAppConfig> thirdAppConfigByClientId = appConfigService.getThirdAppConfigByClientId(clientId);
            if (CollectionUtil.isNotEmpty(thirdAppConfigByClientId)) {
                result.error500("AppKey已存在，请勿重复添加");
                return result;
            }
        }
        try {
            appConfigService.updateById(appConfig);
            result.success("修改成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }
        return result;
    }

    /**
     * 根据租户id和第三方类型获取第三方app配置信息
     *
     * @param thirdType
     * @return
     */
    @GetMapping("/getThirdConfigByTenantId")
    public Result<SysThirdAppConfig> getThirdApp(@RequestParam(name = "thirdType") String thirdType) {
        Result<SysThirdAppConfig> result = new Result<>();
        SysThirdAppConfig sysThirdAppConfig = appConfigService.getThirdConfigByThirdType(thirdType);
        result.setSuccess(true);
        result.setResult(sysThirdAppConfig);
        return result;
    }

    /**
     * 同步【钉钉】[部门和用户]到本地
     *
     * @param ids
     * @return
     */
    @GetMapping("/sync/dingtalk/departAndUser/toLocal")
    public Result syncDingTalkDepartAndUserToLocal(@RequestParam(value = "ids", required = false) String ids) {
        log.info(" ---- dingtalk sync run ...");
        SysThirdAppConfig config = appConfigService.getThirdConfigByThirdType(MessageTypeEnum.DD.getType());
        if (null != config) {
            SyncInfoVo syncInfo = dingtalkService.syncThirdAppDepartmentUserToLocal();
            if (syncInfo.getFailInfo().size() == 0) {
                return Result.OK("同步成功", syncInfo);
            } else {
                return Result.error("同步失败", syncInfo);
            }
        }
        return Result.error("钉钉尚未配置,请配置钉钉");
    }
    //========================end 应用低代码钉钉/企业微信同步用户部门专用 ========================


    //========================begin 应用低代码账号设置第三方账号绑定 ================================

    /**
     * 获取第三方账号
     *
     * @param thirdType
     * @return
     */
    @GetMapping("/getThirdAccountByUserId")
    public Result<List<SysThirdAccount>> getThirdAccountByUserId(@RequestParam(name = "thirdType") String thirdType) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        LambdaQueryWrapper<SysThirdAccount> query = new LambdaQueryWrapper<>();
        // 根据id查询
        query.eq(SysThirdAccount::getSysUserId, sysUser.getId());
        // 根据第三方类别查询
        if (oConvertUtils.isNotEmpty(thirdType)) {
            query.in(SysThirdAccount::getThirdType, Arrays.asList(thirdType.split(SymbolConstant.COMMA)));
        }
        List<SysThirdAccount> list = sysThirdAccountService.list(query);
        return Result.ok(list);
    }

    /**
     * 绑定第三方账号
     *
     * @return
     */
    @PostMapping("/bindThirdAppAccount")
    public Result<SysThirdAccount> bindThirdAppAccount(@RequestBody SysThirdAccount sysThirdAccount) {
        SysThirdAccount thirdAccount = sysThirdAccountService.bindThirdAppAccountByUserId(sysThirdAccount);
        return Result.ok(thirdAccount);
    }

    /**
     * 删除第三方用户信息
     *
     * @param sysThirdAccount
     * @return
     */
    @DeleteMapping("/deleteThirdAccount")
    public Result<String> deleteThirdAccountById(@RequestBody SysThirdAccount sysThirdAccount) {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (!sysUser.getId().equals(sysThirdAccount.getSysUserId())) {
            return Result.error("无权修改他人信息");
        }
        SysThirdAccount thirdAccount = sysThirdAccountService.getById(sysThirdAccount.getId());
        if (null == thirdAccount) {
            return Result.error("未找到改第三方账户信息");
        }
        sysThirdAccountService.removeById(thirdAccount.getId());
        return Result.ok("解绑成功");
    }
    //========================end 应用低代码账号设置第三方账号绑定 ================================
}
