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

import com.github.wxiaoqi.security.admin.biz.*;
import com.github.wxiaoqi.security.admin.bo.UserBo;
import com.github.wxiaoqi.security.admin.bo.UserStaffBo;
import com.github.wxiaoqi.security.admin.dto.AccountBindDTO;
import com.github.wxiaoqi.security.admin.entity.*;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.admin.vo.AppUserGroups;
import com.github.wxiaoqi.security.admin.vo.AppUserInfoVo;
import com.github.wxiaoqi.security.admin.vo.AppUserVo;
import com.github.wxiaoqi.security.admin.vo.UserMemberVo;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreClientToken;
import com.github.wxiaoqi.security.auth.client.annotation.IgnoreUserToken;
import com.github.wxiaoqi.security.auth.client.config.UserAuthConfig;
import com.github.wxiaoqi.security.auth.client.jwt.UserAuthUtil;
import com.github.wxiaoqi.security.auth.common.util.jwt.IJWTInfo;
import com.github.wxiaoqi.security.common.constant.UserConstant;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.msg.TableResultResponse;
import com.github.wxiaoqi.security.common.rest.CommonBaseController;
import com.github.wxiaoqi.security.common.util.Query;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

import static com.github.wxiaoqi.security.common.constant.CommonConstants.SYS_TRUE;

/**
 * @author keliii
 */
@RestController
@RequestMapping("app/user")
@Slf4j
public class AppUserController extends CommonBaseController{

    @Autowired
    AppUserBiz appUserBiz;

    @Autowired
    private UserAuthUtil userAuthUtil;

    @Autowired
    private UserAuthConfig userAuthConfig;

    @Autowired
    AppUserDetailBiz userDetailBiz;

    @Autowired
    AppUserLoginBiz appUserLoginBiz;

    @Autowired
    private BaseUserMemberBiz userMemberBiz;

    @Autowired
    AppUserPositionBiz positionBiz;

    @Autowired
    private UserMemberLevelBiz userMemberLevelBiz;

    @Autowired
    private MyWaterBiz myWaterBiz;

    @Autowired
    private AppUserAlipayBiz appUserAlipayBiz;



    @GetMapping("page")
    public TableResultResponse list(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        try {
            return appUserBiz.selectPage(query,
                    appUserBiz.getUserByUsername(userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request)).getUniqueName()));
        }catch (Exception e) {
            log.error(e.getMessage());
            return new TableResultResponse<User>();
        }
    }

    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    @ResponseBody
    public ObjectRestResponse<AppUser> get(@PathVariable int id){
        ObjectRestResponse<AppUser> entityObjectRestResponse = new ObjectRestResponse<>();
        AppUser o = appUserBiz.selectById(id);
        entityObjectRestResponse.data(o);
        return entityObjectRestResponse;
    }

    @RequestMapping(value = "/{id}",method = RequestMethod.PUT)
    @ResponseBody
    public ObjectRestResponse<AppUser> update(@RequestBody AppUser entity){
        appUserBiz.updateSelectiveById(entity);
        return new ObjectRestResponse<AppUser>();
    }
    @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public ObjectRestResponse<AppUser> remove(@PathVariable int id){
        appUserBiz.deleteById(id);
        return new ObjectRestResponse<AppUser>();
    }

    @RequestMapping(value = "/all",method = RequestMethod.GET)
    @ResponseBody
    public List<AppUser> all(){
        return appUserBiz.selectListAll();
    }

    @GetMapping("groups/{id}")
    public List<Group> groups(@PathVariable Integer id) {
        return appUserBiz.selectGroupsByAppUserId(id);
    }

    @PostMapping("groups")
    public ObjectRestResponse insertAppUserGroups(@RequestBody AppUserGroups appUserGroups) {
        appUserBiz.insertAppUserGroup(appUserGroups.getAppUserId(), appUserGroups.getGroups());
        return new ObjectRestResponse();
    }

    /**
     * 获取用户信息
     * @return
     * @throws Exception
     */
    @GetMapping("/info")
    public ObjectRestResponse<AppUserDTO> getUserInfo()throws Exception {
        String username = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request)).getId();
        if (username == null) {
            throw new Exception();
        }
        AppUserDTO userDTO=new AppUserDTO();
        Integer userid=Integer.parseInt(username);
        AppUserVo userVo = userDetailBiz.getUserInfoById(userid);
        if (userVo == null) {
            throw new Exception();
        }
        Integer id= userVo.getId();
        Integer positionId=userVo.getPositionId();
        BeanUtils.copyProperties(userDTO,userVo);
        AppUserPosition userPosition=positionBiz.selectById(positionId);
        if (userPosition!=null&&userPosition.getLevel()>0){
            userDTO.setPositionName(userPosition.getName());
        }
        List<AppUserAlipay> appUserAlipays = appUserAlipayBiz.getByUserId(request);
        long count = appUserAlipays.stream().filter(appUserAlipay -> appUserAlipay.getType() == 1).count();
        userDTO.setIsBindAliPay(count>0);
        userDTO.setId(id);
        userDTO.setAliPayNickName(userDTO.getIsBindAliPay()?appUserAlipays.get(0).getNickname():"");
        AppUserLogin appUserLogin = appUserLoginBiz.selectById(userid);
        userDTO.setIsBindWx(StringUtils.isNotEmpty(appUserLogin.getWxOpenid()));
        userDTO.setIsBindQQ(StringUtils.isNotEmpty(appUserLogin.getOpenid()));
        return ObjectRestResponse.succ(userDTO);
    }

    @ApiOperation("获取用IM密码")
    @GetMapping("/im/getPwd")
    public ObjectRestResponse getPwd() throws Exception{
        String username = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request)).getId();
        if (username == null) {
            throw new Exception();
        }
        Integer userid=Integer.parseInt(username);
        AppUserLogin appUserLogin=appUserLoginBiz.getUserById(userid);
        String imPassword="";
        if (appUserLogin!=null){
            imPassword=appUserLogin.getImPassword();
        }
        return ObjectRestResponse.succ(imPassword);
    }
    /**
     * 更新用户信息
     * @param userVo
     * @return
     * @throws Exception
     */
    @PostMapping("/edit")
    public ObjectRestResponse edit(@RequestBody AppUserVo userVo,HttpServletRequest request)throws Exception {
        String id = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request)).getId();
        userVo.setUserid(Integer.valueOf(id));
        userDetailBiz.updUuserInfoById(userVo);
        if (StringUtils.isNotBlank(userVo.getPassword())) {
            log.info("修改用户密码: userVo = {}", userVo);
            AppUserLogin appUserLogin = appUserLoginBiz.selectById(Integer.parseInt(id));
            if (appUserLogin != null) {
                appUserLogin.setPassword(new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(userVo.getPassword()));
                appUserLoginBiz.updateSelectiveByIdRe(appUserLogin);
            }
        }
        return ObjectRestResponse.succ();
    }

    @PostMapping(value = "changePwd")
    public ObjectRestResponse changePwd(@RequestBody AppUserLogin userVo,HttpServletRequest request) throws Exception {
        String id = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request)).getId();
        userVo.setId(Integer.valueOf(id));
        appUserLoginBiz.updatePasswordById(userVo);
        return ObjectRestResponse.succ();
    }

    /**
     * 第三方登录绑定
     * @param wxOpenId
     * @param wxUnionId
     * @param openId
     * @param request
     * @return
     */
    @PutMapping("/third_party_binding")
    public ObjectRestResponse bindingThirdParty(@RequestParam(value = "wxOpenId",required = false) String wxOpenId,
                                                @RequestParam(value="wxUnionId",required = false) String wxUnionId,
                                                @RequestParam(value = "openId",required = false) String openId,
                                                HttpServletRequest request){
        try {
            IJWTInfo infoFromToken = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request));
            String userId = infoFromToken.getId();
            boolean isBinding = appUserLoginBiz.checkThirdPartyBindingState(wxOpenId,wxUnionId,openId);
            if (isBinding){
                return  ObjectRestResponse.createFailedResult(400,"该微信已经绑定过");
            }else {
                AppUserLogin appUserLogin = new AppUserLogin();
                appUserLogin.setId(Integer.valueOf(userId));
                appUserLogin.setWxOpenid(wxOpenId);
                appUserLogin.setUnionid(wxUnionId);
                appUserLogin.setOpenid(openId);
                appUserLoginBiz.bindOpenid(appUserLogin);
            }
        } catch (Exception e) {
            throw  new BaseException(e);
        }

        return ObjectRestResponse.succ();
    }

    /**
     * 第三方登录解绑
     * @param request
     * @return
     */
    @PutMapping("third_party_unbind")
    public ObjectRestResponse unBindingThirdParty(@RequestParam("type") String type , HttpServletRequest request){
        try {
            IJWTInfo infoFromToken = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request));
            appUserLoginBiz.unBindThirdPartyByType(type,infoFromToken.getUniqueName(),Integer.valueOf(infoFromToken.getId()));
        } catch (Exception e) {
            throw  new BaseException(e);
        }
        return ObjectRestResponse.succ();
    }



    /**
     * 更新用户信息
     * @param username
     * @return
     */
    @GetMapping("/one")
    public AppUserLogin one(@RequestParam(value = "username")String username){
        return appUserLoginBiz.getUserByUsername(username);
    }

    /**
     * 根据用户真实姓名和手机号模糊查询寻用户
     * @param username
     * @return
     */
    @GetMapping("/getOne")
    public List<AppUserLogin> getOne(@RequestParam(value = "username",required = false)String username, @RequestParam(value = "realName",required = false)String realName){
        return appUserLoginBiz.getUserByUsernameAndRealName(username,realName);
    }
    @GetMapping("/findusersByIds")
    public Map<Integer,AppUserLogin> findAppUsersByUserIds(@RequestParam(value = "userIds") List<Integer> userIds){
     return appUserLoginBiz.findUserIdAndUserLoginMapByMemberIds(userIds);
    }

    @GetMapping("/finduserIdsByphones")
    Map<String, Integer> findAppusersByUserNames(@RequestParam(value = "phones") List<String> phones){
        return appUserLoginBiz.findPhoneAndUserIdMapByPhones(phones);
    }

    @GetMapping("/app/unauth/user_info/{code}")
    @IgnoreUserToken
    @IgnoreClientToken
    public ObjectRestResponse<AppUserInfoVo> findUserInfoByCode(@PathVariable("code") String code){
         AppUserInfoVo appUserInfoVo = userDetailBiz.findUserInfoByCode(code);
         return ObjectRestResponse.succ(appUserInfoVo);
    }

    @GetMapping("/app/unauth/getUserIdByUsername")
    @IgnoreUserToken
    @IgnoreClientToken
    public List<Integer> getUserIdByUsername(@RequestParam("keywords") String keywords){
        List<Integer> userIds = userDetailBiz.getUserIdByUsername(keywords);
        return userIds;
    }

    @GetMapping("/app/unauth/getUserByUsername")
    @IgnoreUserToken
    @IgnoreClientToken
    public ObjectRestResponse<AppUser> getUserByUsername(@RequestParam("username") String username){
        AppUser appUser = appUserBiz.getUserByUsername(username);
        return ObjectRestResponse.succ(appUser);
    }

    @GetMapping("/app/unauth/test")
    @IgnoreUserToken
    @IgnoreClientToken
    public Object test() {
        return appUserLoginBiz.test();
    }

    @PostMapping("/bind")
    public ObjectRestResponse accountBinding(@RequestBody AccountBindDTO accountBindDTO, HttpServletRequest request){
         try {
             IJWTInfo infoFromToken = userAuthUtil.getInfoFromToken(userAuthConfig.getToken(request));
            return appUserLoginBiz.bindAccount(accountBindDTO, Integer.valueOf(infoFromToken.getId()), request);
         }catch (Exception ex){
             throw new BaseException(ex);
         }
    }

    @GetMapping("/users")
    List<Integer> findAppUserIds(@RequestParam(value = "phone", required = false) String phone,
                                 @RequestParam(value = "leaderPhone", required = false) String leaderPhone,
                                 @RequestParam(value = "name", required = false) String name) {

        return appUserLoginBiz.findAppuser(phone, leaderPhone, name);

    }

    @PostMapping("/users/info")
    List<UserBo> findUserDetailByUserBo(@RequestBody(required = false) List<UserBo> userBos) {

        return appUserLoginBiz.findUserDetailInfo(userBos);
    }

    @ApiOperation("查询全部员工")
    @GetMapping("/list_staff")
    public List<UserStaffBo> findAllStaffs(){
       return userDetailBiz.findAllStaffs();
    }

    @GetMapping("/app/unauth/code/{code}")
    public ObjectRestResponse<AppUserVo> findAppuserInfoByCode(@PathVariable("code") String code){
       AppUserVo appUserVo =  userDetailBiz.findByCode(code);
       return ObjectRestResponse.succ(appUserVo);
    }
}
