package com.github.wxiaoqi.security.admin.rest.chw;

import cn.hutool.core.collection.CollUtil;
import com.github.wxiaoqi.security.admin.biz.GroupBiz;
import com.github.wxiaoqi.security.admin.biz.MenuBiz;
import com.github.wxiaoqi.security.admin.biz.UserBiz;
import com.github.wxiaoqi.security.admin.dto.BaseUserDTO;
import com.github.wxiaoqi.security.admin.entity.Menu;
import com.github.wxiaoqi.security.admin.entity.User;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.rest.UserRestInterface;
import com.github.wxiaoqi.security.admin.rest.UserController;
import com.github.wxiaoqi.security.admin.rpc.service.PermissionService;
import com.github.wxiaoqi.security.admin.vo.FrontUser;
import com.github.wxiaoqi.security.admin.vo.GroupUsers;
import com.github.wxiaoqi.security.admin.vo.MenuTree;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken;
import com.github.wxiaoqi.security.auth.client.config.UserAuthConfig;
import com.github.wxiaoqi.security.auth.client.jwt.UserAuthUtil;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.rest.CommonBaseController;
import com.github.wxiaoqi.security.common.util.ReflectionUtils;
import com.github.wxiaoqi.security.common.vo.DataInterBean;
import com.xxfc.platform.vehicle.constant.ResCode.ResCode;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Field;
import java.util.List;

import static com.github.wxiaoqi.security.admin.entity.User.BIZ_TYPE_BUSINESS;
import static com.github.wxiaoqi.security.admin.entity.User.BIZ_TYPE_OPERATE;
import static com.github.wxiaoqi.security.auth.common.constatns.CommonConstants.DATA_ALL_FALSE;
import static com.github.wxiaoqi.security.auth.common.constatns.CommonConstants.DATA_ALL_TRUE;
import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_TRUE;
import static com.github.wxiaoqi.security.common.util.process.ResultCode.PARAM_ILLEGAL_CODE;

/**
 * ${DESCRIPTION}
 *
 * @author wanghaobin
 * @create 2017-06-08 11:51
 */
@Slf4j
@RestController
@RequestMapping("/chw/user")
public class ChwUserController extends CommonBaseController implements UserRestInterface {

    public final static Integer CURRENT_COMPANY = 1;
    public final static Integer CURRENT_ZONE = 2;
    public final static Integer DATA_ALL = 3;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private MenuBiz menuBiz;

    @Autowired
    private GroupBiz groupBiz;

    @Autowired
    private UserBiz userBiz;

    @Autowired
    private UserAuthUtil userAuthUtil;

    @Autowired
    private UserAuthConfig userAuthConfig;

    @Autowired
    UserFeign userFeign;

    @Override
    public UserFeign getUserFeign() {
        return userFeign;
    }

    //内部类

    @Data
    public static class UserVO extends User {
        //        List<Integer> dataLimit;
        Integer dataLimit;
        List<Integer> members;
    }

    @RequestMapping(value = "/operate/page",method = RequestMethod.GET)
    public ObjectRestResponse operatePage(BaseUserDTO baseUserDTO){
        baseUserDTO.setBizType(BIZ_TYPE_OPERATE);
        return userBiz.selectList(baseUserDTO);
    }

    @RequestMapping(value = "/business/page",method = RequestMethod.GET)
    public ObjectRestResponse businessPage(BaseUserDTO baseUserDTO){
        setPowerData(baseUserDTO,true);
        return userBiz.selectList(baseUserDTO);
    }

    @RequestMapping(value = "/operate/addUser", method = RequestMethod.POST)
    @IgnoreClientToken
    public ObjectRestResponse<User> add(@RequestBody UserController.UserVO vo) {
        String username = vo.getUsername();
        vo.setBizType(BIZ_TYPE_OPERATE);
        vo.setStatus(SYS_TRUE);
        if (StringUtils.isNotBlank(username)) {
            List<User> list = userBiz.getCountByUsernameBiz(username, BIZ_TYPE_OPERATE, null);
            if (list.size() > 0) {
                return ObjectRestResponse.createFailedResult(ResCode.USER_IS_EXIST.getCode(), ResCode.USER_IS_EXIST.getDesc());
            }
        }
        userBiz.insertSelective(vo);
        //添加权限关系
        groupBiz.modifyUserGroups(vo.getId(), vo.getMembers());
        return ObjectRestResponse.succ();
    }

    @RequestMapping(value = "/business/addUser", method = RequestMethod.POST)
    @IgnoreClientToken
    public ObjectRestResponse<User> businessAdd(@RequestBody UserController.UserVO vo) {
        DataInterBean dataInterBean = getDataInter();
        String username = vo.getUsername();
        vo.setBizType(BIZ_TYPE_BUSINESS);
        vo.setStatus(SYS_TRUE);
        vo.setCorporationId(getAdminUserInfoV2().getCorporationId());
        if(CollUtil.isNotEmpty(dataInterBean.getDataCompanyIds())) {
            vo.setCompanyId(dataInterBean.getDataCompanyIds().get(0));
        }

        if (StringUtils.isNotBlank(username)) {
            List<User> list = userBiz.getCountByUsernameBiz(username, BIZ_TYPE_BUSINESS, vo.getMobilePhone());
            if (list.size() > 0) {
                return ObjectRestResponse.createFailedResult(ResCode.USER_IS_EXIST.getCode(), ResCode.USER_IS_EXIST.getDesc());
            }
        }else {
            throw new BaseException("手机号已被使用", PARAM_ILLEGAL_CODE);
        }
        userBiz.insertSelective(vo);
        //添加权限关系
        groupBiz.modifyUserGroups(vo.getId(), vo.getMembers());
        return ObjectRestResponse.succ();
    }

    @RequestMapping(value = "/operate/{id}", method = RequestMethod.PUT)
    @ResponseBody
    public ObjectRestResponse<User> update(@RequestBody UserController.UserVO vo) {
        if (!edit(vo, BIZ_TYPE_OPERATE)){
            return ObjectRestResponse.createFailedResult(ResCode.USER_IS_EXIST.getCode(), ResCode.USER_IS_EXIST.getDesc());
        }
        return new ObjectRestResponse<User>();
    }

    @RequestMapping(value = "/business/{id}", method = RequestMethod.PUT)
    @ResponseBody
    public ObjectRestResponse<User> businessUpdate(@RequestBody UserController.UserVO vo) {
        if (!edit(vo, BIZ_TYPE_BUSINESS)){
            return ObjectRestResponse.createFailedResult(ResCode.USER_IS_EXIST.getCode(), ResCode.USER_IS_EXIST.getDesc());
        }
        return new ObjectRestResponse<User>();
    }

    private boolean edit(UserController.UserVO vo, Integer bizType) {
        handleDataLimit(vo);
        String username = vo.getUsername();
        if (StringUtils.isNotBlank(username)) {
            List<User> list = userBiz.getCountByUsername(username);
            if (list.size() > 1) {
                return false;
            }
            if (list.size() == 1) {
                User user = list.get(0);
                if (!user.getId().equals(vo.getId()) && bizType != user.getBizType()) {
                    return false;
                }
            }
        }
        userBiz.updateSelectiveById(vo);
        //添加权限关系
        groupBiz.modifyUserGroups(vo.getId(), vo.getMembers());
        return true;
    }

    @RequestMapping(value = "/operate/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    public ObjectRestResponse<User> remove(@PathVariable int id) {
        del(id, BIZ_TYPE_OPERATE);
        return new ObjectRestResponse();
    }

    @RequestMapping(value = "/business/{id}", method = RequestMethod.DELETE)
    @ResponseBody
    public ObjectRestResponse businessRemove(@PathVariable int id) {
        del(id, BIZ_TYPE_BUSINESS);
        return new ObjectRestResponse();
    }

    private void del (int id, Integer bizType) {
        User user = userBiz.selectById(id);
        if(null != user && user.getBizType() == bizType) {
            del(new User(){{
                setId(id);
            }});
        }
    }

    private void handleDataLimit(@RequestBody UserController.UserVO dto) {
        if (null != dto.getDataLimit()) {
            dto.setDataCompany("");
            dto.setDataAll(DATA_ALL_FALSE);
            dto.setDataZone("");
            if (dto.getDataLimit()>=CURRENT_COMPANY && dto.getCompanyId() != null) {
                dto.setDataCompany(dto.getCompanyId().toString());

            }
            if (dto.getDataLimit()>=CURRENT_ZONE && dto.getZoneId() != null) {
                dto.setDataZone(dto.getZoneId().toString());
            }
            if (dto.getDataLimit()>=DATA_ALL) {
                dto.setDataAll(DATA_ALL_TRUE);
            }
        }
    }

   private void del(User entity) {
       Field field = ReflectionUtils.getAccessibleField(entity, "isDel");
       Field field2 = ReflectionUtils.getAccessibleField(entity, "delete");

       if(null != field) {
           ReflectionUtils.setFieldValue(entity,"isDel",1);
       }
       if(null != field2) {
           ReflectionUtils.setFieldValue(entity,"delete",1);
       }

       userBiz.updateSelectiveById(entity);
   }
}
