package com.hfkj.controller;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.exception.BaseException;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.security.UserCenter;
import com.hfkj.common.utils.*;
import com.hfkj.config.CommonSysConst;
import com.hfkj.config.SysConfig;
import com.hfkj.entity.BsUser;
import com.hfkj.entity.BsUserPlatformAuthorize;
import com.hfkj.model.ResponseData;
import com.hfkj.model.SecUserSessionObject;
import com.hfkj.model.UserSessionObject;
import com.hfkj.service.pdd.PddService;
import com.hfkj.service.user.BsUserPlatformAuthorizeService;
import com.hfkj.service.user.BsUserService;
import com.hfkj.sysenum.user.UserAuthorizePlatformEnum;
import com.hfkj.sysenum.user.UserLoginType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.util.*;

/**
 * @className: ClientController
 * @author: HuRui
 * @date: 2024/9/6
 **/
@Controller
@RequestMapping(value="/user")
@Api(value="客户端业务")
public class UserController {
    private static Logger log = LoggerFactory.getLogger(UserController.class);
    @Resource
    private BsUserService userService;
    @Resource
    private BsUserPlatformAuthorizeService userPlatformAuthorizeService;
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private UserCenter userCenter;
    @Autowired
    private SysConfig sysConfig;

    @RequestMapping(value = "/getUser", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询用户信息")
    public ResponseData getUser() {
        try {
            Map<String,Object> param = new HashMap<>();
            // 用户信息
            param.put("user", userCenter.getSessionModel(UserSessionObject.class));

            return ResponseMsgUtil.success(param);

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/getInviteUser", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "查询邀请人信息")
    public ResponseData getInviteUser() {
        try {
            UserSessionObject userSessionObject = userCenter.getSessionModel(UserSessionObject.class);
            if (userSessionObject.getUser().getInviteUserId() != null) {
                return ResponseMsgUtil.success(userService.getUser(userSessionObject.getUser().getInviteUserId()));
            }
            return ResponseMsgUtil.success(null);
        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value="uploadHead",method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "头像上传")
    public ResponseData uploadHead(@RequestParam(value = "files" , required = false) MultipartFile files,HttpServletRequest request,HttpServletResponse response) {
        try {
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            // 查询用户
            BsUser user = userService.getUser(userSession.getUser().getId());
            if (user == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的用户");
            }

            response.setHeader("Access-Control-Allow-Origin", "*");
            CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
                    request.getSession().getServletContext());
            // 判断 request 是否有文件上传,即多部分请求
            List<String> fileNames = new ArrayList<String>();
            if (multipartResolver.isMultipart(request)) {
                // 转换成多部分request
                MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
                Iterator<String> iterator = multiRequest.getFileNames();

                while (iterator.hasNext()) {
                    MultipartFile file = multiRequest.getFile(iterator.next());
                    if (file != null) {
                        FileOutputStream out = null;
                        try {
                            String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
                            if (!fileType.endsWith("jpg") && !fileType.endsWith("png")) {
                                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "只能上传jpg或png格式文件");
                            }
                            String fileName = System.currentTimeMillis() + "." + fileType;
                            String childPath = "user-head";
                            String destDirName = sysConfig.getFileUrl() + File.separator + childPath;
                            File dir = new File(destDirName);
                            if (!dir.exists()) {
                                dir.mkdirs();
                            }
                            out = new FileOutputStream(destDirName + File.separator + fileName);
                            out.write(file.getBytes());
                            out.flush();
                            fileNames.add(childPath + "/" + fileName);

                            // 修改用户头像
                            user.setHeadImg(CommonSysConst.getSysConfig().getDomain()+"/filesystem/"+fileNames.get(0));
                            userService.updateInfo(user);
                            return ResponseMsgUtil.success(user.getHeadImg());

                        } catch (BaseException e) {
                            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, e.getErrorMsg());
                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "上传失败");
                        } finally {
                            if (out != null) {
                                out.close();
                            }
                        }
                    }
                }
            }
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "上传失败");

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponseMsgUtil.exception(e);
        }

    }

    @RequestMapping(value = "/updateName", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "修改用户名称")
    public ResponseData updateName(@RequestBody JSONObject body) {
        try {
            if (body == null || StringUtils.isBlank(body.getString("name"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            // 查询用户
            BsUser user = userService.getUser(userSession.getUser().getId());
            if (user == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的用户");
            }
            user.setName(body.getString("name"));
            userService.updateInfo(user);

            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/updateWechat", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "修改用户微信号")
    public ResponseData updateWechat(@RequestBody JSONObject body) {
        try {
            if (body == null || StringUtils.isBlank(body.getString("wechatNum"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            userService.updateWechatNum(userSession.getUser().getId(), body.getString("wechatNum"));
            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/userAccreditList", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "用户授权列表")
    public ResponseData userAccreditList() {
        try {
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);

            JSONObject object = new JSONObject();
            object.put("taobao", userSession.getUser().getRelationId() != null);

            Map<String , Object> mapUser = new JSONObject();
            mapUser.put("uid", userSession.getUser().getId());

            // 判断是否需要授权
            JSONObject jsonObject = PddService.authority(mapUser.toString());
            boolean generateAuthorityUrl = jsonObject.getJSONObject("authorityQueryResponse").getInteger("bind") == 1;
            object.put("pdd", generateAuthorityUrl);

            return ResponseMsgUtil.success(object);

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/taoBaoAccreditDelete", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "淘宝授权取消")
    public ResponseData taoBaoAccreditDelete() {
        try {
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);

            BsUser user = userService.getUser(userSession.getUser().getId());

            user.setRelationId(null);
            userService.editData(user);


            return ResponseMsgUtil.success("取消成功");

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/bindPhone", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "绑定手机号")
    public ResponseData bindPhone(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("phone"))
                    || StringUtils.isBlank(body.getString("smsCode"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            if (StringUtils.isNotBlank(userSession.getUser().getPhone())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "手机号已绑定");
            }
            String phone = body.getString("phone");
            // 校验手机号格式
            if (!MemberValidateUtil.validatePhone(phone)) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请输入正确的手机号");
            }
            if (StringUtils.isBlank(body.getString("smsCode"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请输入短信验证码");
            }
            // 手机号用户
            BsUser user = userService.getUser(phone);
            if (user != null) {
                if (StringUtils.isNotBlank(user.getWechatOpenId())) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "手机号已被绑定");
                }
            }
            // 手机号的验证码
            Object phoneCodeObject = redisUtil.get("SMS_BIND_PHONE_CODE:" + phone);
            if (phoneCodeObject == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误");
            }
            if (!body.getString("smsCode").equals(phoneCodeObject.toString())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误");
            }
            redisUtil.del("SMS_BIND_PHONE_CODE:" + phone);

            // 更新手机号
            userService.updatePhone(userSession.getUser().getId(), body.getString("phone"));

            return ResponseMsgUtil.success(userCenter.getSessionModel(UserSessionObject.class));

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/bindInviteUser", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "绑定邀请人Id")
    public ResponseData bindInviteUser(@RequestBody JSONObject body) {
        try {
            if (body == null || body.getLong("inviteUseId") == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);

            // 绑定邀请人
            userService.bindInviteUser(userSession.getUser().getId(), body.getLong("inviteUseId"));

            return ResponseMsgUtil.success(userCenter.getSessionModel(UserSessionObject.class));

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/verifyUpdPhoneSmsCode", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "验证修改手机号验证码")
    public ResponseData verifyUpdPhoneSmsCode(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("phone"))
                    || StringUtils.isBlank(body.getString("smsCode"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            String phone = body.getString("phone");
            // 手机号的验证码
            Object phoneCodeObject = redisUtil.get("SMS_UPDATE_PHONE_CODE:" + phone);
            if (phoneCodeObject == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误或已失效");
            }
            if (!body.getString("smsCode").equals(phoneCodeObject.toString())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误或已失效");
            }
            redisUtil.del("SMS_UPDATE_PHONE_CODE:" + phone);

            return ResponseMsgUtil.success(true);

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/updatePhone", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "修改手机号")
    public ResponseData updatePhone(@RequestBody JSONObject body) {
        try {
            if (body == null
                    || StringUtils.isBlank(body.getString("newPhone"))
                    || StringUtils.isBlank(body.getString("smsCode"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            if (StringUtils.isBlank(userSession.getUser().getPhone())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "用户未绑定手机号");
            }
            String phone = body.getString("newPhone");
            if (userSession.getUser().getPhone().equals(phone)) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "新手机号与现绑定手机号相同");
            }
            // 手机号用户
            BsUser user = userService.getUser(phone);
            if (user != null) {
                if (StringUtils.isNotBlank(user.getWechatOpenId())) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "手机号已被绑定");
                }
            }
            // 校验手机号格式
            if (!MemberValidateUtil.validatePhone(phone)) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请输入正确的手机号");
            }
            if (StringUtils.isBlank(body.getString("smsCode"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "请输入短信验证码");
            }
            // 手机号的验证码
            Object phoneCodeObject = redisUtil.get("SMS_UPDATE_PHONE_CODE:" + phone);
            if (phoneCodeObject == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误或已失效");
            }
            if (!body.getString("smsCode").equals(phoneCodeObject.toString())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "短信验证码错误或已失效");
            }
            redisUtil.del("SMS_UPDATE_PHONE_CODE:" + phone);

            // 更新手机号
            userService.updatePhone(userSession.getUser().getId(), body.getString("newPhone"));

            return ResponseMsgUtil.success(userCenter.getSessionModel(UserSessionObject.class));

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/bindWeChat", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "绑定微信")
    public ResponseData bindWeChat(@RequestBody JSONObject body) {
        try {
            if (body == null || StringUtils.isBlank(body.getString("code"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.REQ_PARAMS_ERROR, "");
            }
            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            if (StringUtils.isNotBlank(userSession.getUser().getWechatOpenId())) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "已绑定过微信");
            }
            Map<String, Object> params = new HashMap<>();
            params.put("appid", "wxadc7c8cd025639c6");
            params.put("secret", "3b11012a83de870c2a81fb52d6427fce");
            params.put("code", body.getString("code"));
            params.put("grant_type", "authorization_code");
            JSONObject accessToken = HttpsUtils.doGet("https://api.weixin.qq.com/sns/oauth2/access_token", params);
            if (accessToken == null || StringUtils.isBlank(accessToken.getString("openid"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "授权失败");
            }
            params.clear();
            params.put("access_token", accessToken.getString("access_token"));
            params.put("openid", accessToken.getString("openid"));
            params.put("lang", "zh_CN");
            JSONObject userinfo = HttpsUtils.doGet("https://api.weixin.qq.com/sns/userinfo", params);
            if (userinfo == null || StringUtils.isBlank(userinfo.getString("openid"))) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "获取用户信息失败");
            }
            if (userService.getUserByWechatOpenId(userinfo.getString("openid")) != null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "微信已被绑定,无法重复绑定");
            }
            BsUser user = userSession.getUser();
            user.setWechatOpenId(userinfo.getString("openid"));
            user.setWechatUnionid(userinfo.getString("unionid"));
            userService.updateInfo(user);

            // 授权信息
            BsUserPlatformAuthorize authorize = new BsUserPlatformAuthorize();
            authorize.setUserId(user.getId());
            authorize.setPlatformCode(UserAuthorizePlatformEnum.type2.getType());
            authorize.setPlatformName(UserAuthorizePlatformEnum.type2.getName());
            authorize.setAvatar(userinfo.getString("headimgurl"));
            authorize.setNickName(userinfo.getString("nickname"));
            authorize.setOpenId(user.getWechatOpenId());
            userPlatformAuthorizeService.edit(authorize);

            return ResponseMsgUtil.success(userCenter.getSessionModel(UserSessionObject.class));
        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    @ApiOperation(value = "注销账户")
    public ResponseData delete() {
        try {

            UserSessionObject userSession = userCenter.getSessionModel(UserSessionObject.class);
            userService.delete(userSession.getUser().getId());

            return ResponseMsgUtil.success("操作成功");

        } catch (Exception e) {
            return ResponseMsgUtil.exception(e);
        }
    }

}