package com.mortals.xhx.busiz.h5.web;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.annotation.UnAuth;
import com.mortals.framework.ap.CookieService;
import com.mortals.framework.ap.GlobalSysInfo;
import com.mortals.framework.ap.SysConstains;
import com.mortals.framework.common.Rest;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.IAuthTokenService;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.AESUtil;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.HttpUtil;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.login.web.LoginForm;
import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.service.MenuService;
import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.model.UserQuery;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.base.system.valid.service.ValidCodeService;
import com.mortals.xhx.busiz.h5.req.DingTalkReq;
import com.mortals.xhx.common.code.GoWorkResultEnum;
import com.mortals.xhx.common.code.OffWorkResultEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.pdu.HomeStatInfo;
import com.mortals.xhx.module.attendance.model.AttendanceRecordEntity;
import com.mortals.xhx.module.attendance.model.AttendanceRecordQuery;
import com.mortals.xhx.module.attendance.model.AttendanceVacationRecordQuery;
import com.mortals.xhx.module.dept.model.DeptQuery;
import com.mortals.xhx.module.dept.service.DeptService;
import com.mortals.xhx.module.dingding.IDingTalkService;
import com.mortals.xhx.module.dingding.personal.service.IDingPersonService;
import com.mortals.xhx.module.staff.model.StaffEntity;
import com.mortals.xhx.module.staff.model.StaffQuery;
import com.mortals.xhx.module.staff.service.StaffService;
import com.mortals.xhx.module.window.model.WindowOwnerEntity;
import com.mortals.xhx.module.window.model.WindowOwnerQuery;
import com.mortals.xhx.module.window.service.WindowOwnerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.mortals.xhx.common.key.ErrorCode.*;


/**
 * 钉钉授权登录
 *
 * @author:
 * @date: 2023/7/15 10:26
 */
@RestController
@Slf4j
@RequestMapping("dingtalk")
public class DingTalkLoginController extends BaseCRUDJsonBodyMappingController<UserService, UserEntity, Long> {

    @Autowired
    private UserService userService;
    @Autowired
    private IAuthTokenService authTokenService;

    @Autowired
    private StaffService staffService;

    @Autowired
    private IDingPersonService dingPersonService;
    @Autowired
    private WindowOwnerService windowOwnerService;


    @RequestMapping("authlogin")
    @UnAuth
    public String login(@RequestBody DingTalkReq req) throws Exception {
        JSONObject ret = new JSONObject();
        JSONObject data = new JSONObject();
        UserEntity userEntity = null;
        try {
            if (ObjectUtils.isEmpty(req.getCode())) {
                throw new AppException("钉钉code不能为空！");
            }
            //根据code 查询钉钉用户id
            Rest<String> personRest = dingPersonService.getPersonByCode(req.getCode());
            if (personRest.getCode() != YesNoEnum.YES.getValue()) {
                throw new AppException(String.format("获取钉钉用户异常,%s", personRest.getMsg()));
            }
            log.info(personRest.getData());
            if (ObjectUtils.isEmpty(personRest.getData()))
                throw new AppException(1012, "未找到响应的钉钉用户！");
            //根据钉钉的用户查询系统绑定的用户,获取
            UserQuery userQuery = new UserQuery();
            userQuery.setDingUserId(personRest.getData());
            userEntity = userService.selectOne(userQuery);
            if (ObjectUtils.isEmpty(userEntity)) {
                ret.put("openId", personRest.getData());
                throw new AppException(REGISTER_AUTH_FAIL, "不存在当前匹配的钉钉关联用户！");
            }

            data.put("id", userEntity.getId());
            if(userEntity!=null) {
                StaffEntity staffEntity = null;
                if (userEntity.getCustomerId() != null) {
                    staffEntity = staffService.getCache(userEntity.getCustomerId().toString());
                }
                if (staffEntity != null) {
                    WindowOwnerEntity windowOwnerEntity = windowOwnerService.selectOne(new WindowOwnerQuery().staffId(staffEntity.getId()));
                    if (windowOwnerEntity == null) {
                        userEntity.setUserType(1);    //工作人员
                    } else {
                        if (windowOwnerEntity.getInspect() == 1) {
                            userEntity.setUserType(3);   //具有巡检的窗口负责人
                        } else {
                            userEntity.setUserType(2);   //普通窗口负责人
                        }
                        if (StringUtils.isNotEmpty(windowOwnerEntity.getStaffIds())) {
                            List<Long> staffIdList = Arrays.asList(windowOwnerEntity.getStaffIds().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                            windowOwnerEntity.setStaffCount(staffIdList.size());
                        } else {
                            windowOwnerEntity.setStaffCount(0);
                        }
                        windowOwnerEntity.setWindowOwnerDetailList(null);
                        data.put("windowOwner", windowOwnerEntity);
                    }
                }
            }
            data.put("staffId", userEntity.getCustomerId());
            data.put("userType", userEntity.getUserType());
            userEntity.setLoginTime(System.currentTimeMillis());
            userEntity.setToken(IdUtil.fastSimpleUUID());
            userEntity.setExpireTime(DateUtils.addCurrDate(1).getTime());
            String token = authTokenService.createToken(userEntity);
            data.put("token", token);
            ret.put(KEY_RESULT_DATA, data);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "用户登录系统成功!");
            recordSysLog(request, userEntity, "钉钉用户登录系统成功!");
            return ret.toJSONString();
        } catch (AppException e) {
            log.error("dinding login error ", e);
            ret.put(KEY_RESULT_CODE, e.getCode());
            ret.put(KEY_RESULT_MSG, super.convertException(e));
            return ret.toJSONString();
        } catch (Exception e) {
            log.error("系统异常 error ", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
            return ret.toJSONString();
        }
    }


    @RequestMapping("register")
    @UnAuth
    public String resgister(@RequestBody DingTalkReq req) {
        JSONObject ret = new JSONObject();

        UserEntity userEntity = null;
        try {
            if (ObjectUtils.isEmpty(req.getUserName()))
                throw new AppException("用户姓名不能为空！");

            if (ObjectUtils.isEmpty(req.getPhone()))
                throw new AppException("手机号码不能为空！");

            if (ObjectUtils.isEmpty(req.getOpenId()))
                throw new AppException("openId不能为空！");

            StaffEntity staffEntity = staffService.selectOne(new StaffQuery().phoneNumber(req.getPhone()).name(req.getUserName()));
            if (ObjectUtils.isEmpty(staffEntity))
                throw new AppException(String.format("系统未找到当前用户，姓名:%s,手机:%s,请联系管理员！", req.getUserName(), req.getPhone()));
            UserQuery userQuery = new UserQuery();
            userQuery.setCustomerId(staffEntity.getId());
            userEntity = userService.selectOne(userQuery);
            if (ObjectUtils.isEmpty(userEntity))
                throw new AppException(String.format("员工未与系统用户绑定，staffId:%s", staffEntity.getId()));
            userEntity.setDingUserId(req.getOpenId());

            // userService.update(userEntity);
            Map<String, Object> condition = new HashMap<>(1);
            condition.put("id", userEntity.getId());

            Map<String, Object> data1 = new HashMap<>(1);
            data1.put("dingUserId", req.getOpenId());
            userService.getUserDao().update(data1, condition);


            JSONObject data = new JSONObject();
            data.put("id", userEntity.getId());
            data.put("userType", userEntity.getUserType());
            userEntity.setLoginTime(System.currentTimeMillis());
            userEntity.setToken(IdUtil.fastSimpleUUID());
            userEntity.setExpireTime(DateUtils.addCurrDate(7).getTime());
            String token = authTokenService.createToken(userEntity);
            data.put("token", token);
            ret.put(KEY_RESULT_DATA, data);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "钉钉用户登录系统成功!");
            recordSysLog(request, userEntity, "钉钉用户登录系统成功!");
            return ret.toJSONString();
        } catch (AppException e) {
            log.error("dinding register error ", e);
            ret.put(KEY_RESULT_CODE, e.getCode());
            ret.put(KEY_RESULT_MSG, super.convertException(e));
            return ret.toJSONString();
        } catch (Exception e) {
            log.error("系统异常 error ", e);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
            return ret.toJSONString();
        }
    }


    @RequestMapping("index")
    public String index() throws Exception {
        JSONObject ret = new JSONObject();
        IUser user = this.getCurUser();
        if (user == null) {
            return JSONObject.toJSONString(Rest.fail(ERROR_TOKEN_EXPIRED, ERROR_TOKEN_EXPIRED_CONTENT));
        }
        JSONObject data = new JSONObject();
        UserEntity userEntity = userService.get(user.getId());
        String token = authTokenService.getToken(request);
        data.put("id", user.getId());
        data.put("token", token);
        if(userEntity!=null) {
            StaffEntity staffEntity = null;
            if (userEntity.getCustomerId() != null) {
                staffEntity = staffService.getCache(userEntity.getCustomerId().toString());
            }
            if (staffEntity != null) {
                WindowOwnerEntity windowOwnerEntity = windowOwnerService.selectOne(new WindowOwnerQuery().staffId(staffEntity.getId()));
                if (windowOwnerEntity == null) {
                    userEntity.setUserType(1);    //工作人员
                } else {
                    if (windowOwnerEntity.getInspect() == 1) {
                        userEntity.setUserType(3);   //具有巡检的窗口负责人
                    } else {
                        userEntity.setUserType(2);   //普通窗口负责人
                    }
                    if (StringUtils.isNotEmpty(windowOwnerEntity.getStaffIds())) {
                        List<Long> staffIdList = Arrays.asList(windowOwnerEntity.getStaffIds().split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                        windowOwnerEntity.setStaffCount(staffIdList.size());
                    } else {
                        windowOwnerEntity.setStaffCount(0);
                    }
                    windowOwnerEntity.setWindowOwnerDetailList(null);
                    data.put("windowOwner", windowOwnerEntity);
                }
            }
        }
        data.put("staffId", userEntity.getCustomerId());
        data.put("userType", userEntity.getUserType());
        ret.put(KEY_RESULT_DATA, data);
        ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
        ret.put(KEY_RESULT_MSG, "用户登录系统成功!");
        return ret.toJSONString();
    }

    @RequestMapping("logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        recordSysLog(request, "退出登录");
        super.removeCurrUser(request);
        this.deleteBlackCookie(request, response);
    }

    protected void deleteBlackCookie(HttpServletRequest request, HttpServletResponse response) {
        try {
            CookieService.deleteCookieForAuth(request, response);
        } catch (Throwable e) {
        }
    }


}
