package com.yonge.cooleshow.tenant.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.auth.api.entity.SysUser;
import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
import com.yonge.cooleshow.biz.dal.service.EmployeeService;
import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
import com.yonge.cooleshow.biz.dal.service.SysConfigService;
import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.controller.BaseController;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.cooleshow.common.security.SecurityConstants;
import com.yonge.cooleshow.tenant.io.request.SysUserWrapper;
import com.yonge.cooleshow.tenant.io.request.TenantInfoVo;
import com.yonge.toolset.base.exception.BizException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Author：haonan
 * @Date：2023/7/24 9:57
 * @Filename：TenantInfoController
 */
@RestController
@RequestMapping("/tenantInfoUpdate")
@Api(value = "机构信息修改", tags = "机构信息修改")
public class TenantInfoController extends BaseController {

    @Autowired
    TenantInfoService tenantInfoService;

    @Autowired
    SysUserFeignService sysUserFeignService;

    @Autowired
    private SmsCodeService smsCodeService;

    @Autowired
    private TenantStaffService tenantStaffService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private EmployeeService employeeService;

    @ApiOperation(value = "发送登录短信验证码")
    @ApiImplicitParams({@ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "type", value = "类型（PASSWD:修改密码，LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号）", required =
                    true, dataType = "String")})
    @PostMapping(value = "/sendSmsCode")
    public Object sendLoginVerifyCode(String mobile, String type,String code) throws Exception {
        smsCodeService.sendValidCode(mobile, type, ClientEnum.SYSTEM, code);
        return succeed();
    }

    @ApiOperation(value = "校验短信验证码")
    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String"),
            @ApiImplicitParam(name = "type", value = "类型（PASSWD:修改密码，LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号）", required =
                    true, dataType = "String")})
    @PostMapping(value = "/verifySmsCode")
    public Object verifySmsCode(String phone, String code, String type) {
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
        }
        if (smsCodeService.verifyValidCode(phone, code, type)) {
            return succeed();
        }
        return failed("验证码校验失败");
    }


    /**
     * 机构修改数据
     */
    @PostMapping("/update")
    @ApiOperation(value = "修改机构信息", notes = "传入TenantInfo")
//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/update')")
    public HttpResponseResult<Boolean> updateTenantInfo(@Valid @RequestBody TenantInfoVo.TenantInfo info) {

        TenantInfo tenantInfo = JSON.parseObject(info.jsonString(), TenantInfo.class);
            tenantInfoService.updateById(tenantInfo);

        return  HttpResponseResult.succeed(true);

    }




    /**
     * 当前机构查询详细
     */
    @PostMapping("/detail")
    @ApiOperation(value = "查询详细", notes = "查询详细")
//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/detail')")
    public HttpResponseResult<TenantInfoWrapper.TenantInfo> detail() {
        TenantInfoWrapper.TenantInfo info = new TenantInfoWrapper.TenantInfo();
        SysUser sysUser = sysUserFeignService.queryUserInfo();
        Long id = sysUser.getId();
        List<TenantStaff> list = tenantStaffService.lambdaQuery().eq(TenantStaff::getUserId, id).list();
        if (CollectionUtils.isNotEmpty(list)){
            TenantStaff staff = list.get(0);
            Long tenantId = staff.getTenantId();
            if (!(tenantId == null)){
                info = tenantInfoService.detailTenantInfo(tenantId);
            }
        }
        return succeed(info);
    }



    /**
     * 当前用户查询详细
     */
    @PostMapping("/sysUserDetail")
    @ApiOperation(value = "查询详细", notes = "查询详细")
//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/sysUserDetail')")
    public HttpResponseResult<SysUser> sysUserDetail() {

        SysUser sysUser = sysUserFeignService.queryUserInfo();


        return HttpResponseResult.succeed(sysUser);
    }

    /**
     * 当前用户修改信息
     */
    @PostMapping("/sysUserUpdate")
    @ApiOperation(value = "用户修改", notes = "用户修改")
//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/sysUserUpdate')")
    public HttpResponseResult<Boolean> sysUserUpdate(@RequestBody SysUserWrapper.SysUser sysUser) {

        // 当前用户请登录，提示请登录
        SysUser user = sysUserFeignService.queryUserInfo();
        if (Objects.isNull(user)) {
            throw new BizException("请登录");
        }

        TenantStaff staff = tenantStaffService.getByUserId(user.getId());
        if (Objects.nonNull(staff)) {
            // 设置用户机构ID
            user.setTenantId(staff.getTenantId());
        }
        //如果传手机号
        if (StringUtils.isNotBlank(sysUser.getPhone())) {

            if (StringUtils.isBlank(sysUser.getCode())) {
                throw new BizException("验证码不能为空");
            }

            boolean exists = smsCodeService.verifyValidCode(sysUser.getPhone(), sysUser.getCode(), "PHONE");
            if (Boolean.FALSE.equals(exists)) {
                throw new BizException("验证码错误");
            }

            long userId;
            // 查询输入的手机号  是否存在于sysUser表中
            SysUser sysUserInfo = sysUserMapper.findUserByPhone(sysUser.getPhone());

            // 用户默认头象
            if (Objects.nonNull(sysUserInfo)) {

                //如果存在 判断是否为机构员工
                TenantStaff tenantStaff = tenantStaffService.getByUserId(sysUserInfo.getId());
                if (Objects.nonNull(tenantStaff)) {
                    throw new BizException("该手机号已绑定机构");
                }

                // 平台员工不允许重复
                SysUser employee = employeeService.queryUserByMobile(sysUser.getPhone());
                if (Objects.nonNull(employee) && employee.getPhone().equals(sysUser.getPhone())
                        && employee.getUserType().contains(ClientEnum.SYSTEM.getCode())) {
                    throw new BizException("当前手机号已绑定平台员工");
                }

                // 更新用户身份
                com.yonge.cooleshow.biz.dal.entity.SysUser newSysUser = new com.yonge.cooleshow.biz.dal.entity.SysUser();
                // 设置用户ID
                newSysUser.setId(sysUserInfo.getId());
                // 用户身份
                newSysUser.setUserType(sysUserInfo.getUserType() + ",ORGANIZATION");
                newSysUser.setUpdateTime(LocalDateTime.now());

                // 新用户更新
                sysUserMapper.updateById(newSysUser);

                // 新用户ID
                userId = sysUserInfo.getId();
            } else {

                // 重新生成sysUser数据
                com.yonge.cooleshow.biz.dal.entity.SysUser newSysUser = JSON.parseObject(JSON.toJSONString(user),
                        com.yonge.cooleshow.biz.dal.entity.SysUser.class);
                // 重置主键ID
                newSysUser.setId(null);
                // 设置新手机号
                newSysUser.setPhone(sysUser.getPhone());
                // 创建和修改时间
                newSysUser.setCreateTime(LocalDateTime.now());
                newSysUser.setUpdateTime(LocalDateTime.now());
                if (StringUtils.isBlank(newSysUser.getAvatar())) {
                    // 使用默认用户头像
                    newSysUser.setAvatar(sysConfigService.findConfigValue(SysConfigConstant.TEACHER_AVATAR));
                }
                // 锁定状态
                newSysUser.setLockFlag(0);
                // 用户类型
                newSysUser.setUserType("ORGANIZATION");
                // 删除状态
                newSysUser.setDelFlag(0);
                newSysUser.setImToken("");

                sysUserMapper.insert(newSysUser);
                // 新用户ID
                userId = newSysUser.getId();
            }

            // 旧用户移动机构身份
            com.yonge.cooleshow.biz.dal.entity.SysUser oldSysUser = new com.yonge.cooleshow.biz.dal.entity.SysUser();
            oldSysUser.setId(user.getId());
            // 用户身份
            String userType = Arrays.stream(user.getUserType().split(","))
                    .filter(x -> !x.equals("ORGANIZATION")).collect(Collectors.joining(","));
            oldSysUser.setUserType(userType);
            sysUserMapper.updateById(oldSysUser);

            // 更新用户ID
            tenantStaffService.lambdaUpdate()
                    .eq(TenantStaff::getUserId, user.getId())
                    .set(TenantStaff::getUserId, userId)
                    .update();

            // 更新机构信息表中的用户
            if (Optional.ofNullable(user.getTenantId()).orElse(-1L) > 0) {

                tenantInfoService.lambdaUpdate()
                        .eq(TenantInfo::getId, user.getTenantId())
                        .set(TenantInfo::getUserId, userId)
                        .set(TenantInfo::getPhone,sysUser.getPhone())
                        .update();
            }

        } else {

            // 修改用户基础信息流程
            // 更新用户头象
            com.yonge.cooleshow.biz.dal.entity.SysUser updateSysUser = new com.yonge.cooleshow.biz.dal.entity.SysUser();
            updateSysUser.setId(user.getId());
            // 用户昵称
            if (StringUtils.isNotBlank(sysUser.getUsername())) {
                updateSysUser.setUsername(sysUser.getUsername());
            }
            //设置默认头像
            if (StringUtils.isNotBlank(sysUser.getAvatar())) {
                //sysUser.setAvatar(sysConfigService.findConfigValue(SysConfigConstant.DEFAULT_HEARD));
                updateSysUser.setAvatar(sysUser.getAvatar());
            }
            updateSysUser.setUpdateTime(LocalDateTime.now());
            sysUserMapper.updateById(updateSysUser);

            // 更新机构员工头像和昵称，机构信息表中的用户昵称
            tenantStaffService.lambdaUpdate()
                    .eq(TenantStaff::getUserId, user.getId())
                    .set(StringUtils.isNotEmpty(sysUser.getUsername()), TenantStaff::getNickname, sysUser.getUsername())
                    .set(StringUtils.isNotEmpty(sysUser.getAvatar()), TenantStaff::getAvatar, sysUser.getAvatar())
                    .set(TenantStaff::getUpdateTime, LocalDateTime.now())
                    .update();


            // 更新机构信息表中的用户昵称
            if (StringUtils.isNotBlank(sysUser.getUsername()) && Optional.ofNullable(user.getTenantId()).orElse(-1L) > 0) {

                tenantInfoService.lambdaUpdate()
                        .eq(TenantInfo::getId, user.getTenantId())
                        .set(TenantInfo::getUsername, sysUser.getUsername())
                        .update();
            }

        }

        // 修改了手机号码，清理token和WXOpenId
        if (StringUtils.isNotEmpty(sysUser.getPhone()) && !user.getPhone().equals(sysUser.getPhone())) {
            // 清除登录token信息,有wxOpenId说明登陆过
            if (StringUtils.isNotEmpty(staff.getWxOpenid())) {
                TenantStaff newStaff = tenantStaffService.getByPhone(sysUser.getPhone());
                sysUserFeignService.exitByPhoneAndOpenId(ClientEnum.ORGANIZATION.getCode().toLowerCase(),
                        user.getPhone(), staff.getWxOpenid());
                // 清除WXOpenId
                tenantStaffService.update(null, Wrappers.<TenantStaff>lambdaUpdate()
                        .set(TenantStaff::getWxOpenid, null)
                        .eq(TenantStaff::getUserId, newStaff.getUserId()));
            }
        }

        return HttpResponseResult.succeed(true);
    }
}
