package com.hys.app.controller.system;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hys.app.controller.erp.use.msg.AliSmsUtil;
import com.hys.app.controller.erp.use.msg.MsgContant;
import com.hys.app.controller.erp.use.msg.MsgUtilClient;
import com.hys.app.framework.context.user.AdminUserContext;
import com.hys.app.framework.exception.ResourceNotFoundException;
import com.hys.app.framework.exception.ServiceException;
import com.hys.app.framework.util.BeanUtil;
import com.hys.app.framework.util.StringUtil;
import com.hys.app.framework.validation.annotation.DemoSiteDisable;
import com.hys.app.model.erp.entity.CompanyErp;
import com.hys.app.model.errorcode.SystemErrorCode;
import com.hys.app.model.system.dos.AdminUser;
import com.hys.app.model.system.vo.AdminLoginVO;
import com.hys.app.model.system.vo.AdminUserVO;
import com.hys.app.service.base.service.ValidatorManager;
import com.hys.app.service.erp.CompanyErpManager;
import com.hys.app.service.system.AdminUserManager;
import io.jsonwebtoken.ExpiredJwtException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 平台管理员控制器
 *
 * @author zh
 * @version v7.0
 * @since v7.0.0
 * 2018-06-20 20:38:26
 */
@RestController
@RequestMapping("/admin/systems/admin-users")
@Api(description = "平台管理员相关API")
@Validated
public class AdminUserManagerController {

    @Autowired
    private AdminUserManager adminUserManager;
    @Autowired
    private ValidatorManager validatorManager;
    @Autowired
    private CompanyErpManager companyManager;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    MsgUtilClient msgUtilClient;


    @GetMapping("/login")
    @ApiOperation(value = "用户名（手机号）/密码登录API")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query")
    })
    public AdminLoginVO login(String username,
                              String password,
                              @NotEmpty(message = "平台登录sys，公司登录com") String type,
                              String phone,
                              String checkCodeKey,
                              String checkCode,
                              @NotEmpty(message = "账号登录 password 手机登录 phone") String loginType,
                              String companyName) {
        if ("password".equals(loginType)) {
            return adminUserManager.login(username, password, companyName, type);
        }else if ("phone".equals(loginType)){
            String code = (String) redisTemplate.opsForValue().get(checkCodeKey);
            if (!code.equals(checkCode)) {
                throw new ServiceException("验证码错误");
            }
            return adminUserManager.loginByPhone(phone, companyName, type);
        }
        throw new ServiceException("不支持的登录类型");
    }


    @ApiOperation(value = "刷新token")
    @PostMapping("/token")
    @ApiImplicitParam(name = "refresh_token", value = "刷新token", required = true, dataType = "String", paramType = "query")
    public String refreshToken(@ApiIgnore @NotEmpty(message = "刷新token不能为空") String refreshToken) {
        try {
            return adminUserManager.exchangeToken(refreshToken);
        } catch (ExpiredJwtException e) {
            throw new ServiceException("当前token已经失效");
        }
    }

    @PutMapping
    @ApiOperation(value = "修改管理员密码及头像", response = AdminUser.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "face", value = "头像", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "old_passwprd", value = "原密码", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "新密码", required = false, dataType = "String", paramType = "query")
    })
    @DemoSiteDisable
    public AdminUser edit(@NotEmpty(message = "管理员头像不能为空") String face, @ApiIgnore String oldPasswprd, String password) {
        Long uid = AdminUserContext.getAdmin().getUid();
        AdminUser adminUser = this.adminUserManager.getModel(uid);
        if (adminUser == null) {
            throw new ResourceNotFoundException("当前管理员不存在");
        }
        AdminUserVO adminUserVO = new AdminUserVO();
        BeanUtil.copyProperties(adminUser, adminUserVO);

        //校验密码
        if (!StringUtil.isEmpty(oldPasswprd) && StringUtil.isEmpty(password)) {
            throw new ServiceException(SystemErrorCode.E923.code(), "新密码不能为空");
        }
        if (StringUtil.isEmpty(oldPasswprd) && !StringUtil.isEmpty(password)) {
            throw new ServiceException(SystemErrorCode.E922.code(), "原始密码不能为空");
        }
        if (!StringUtil.isEmpty(oldPasswprd) && !StringUtil.isEmpty(password)) {
            String dbOldPassword = StringUtil.md5(oldPasswprd + adminUser.getUsername().toLowerCase());
            if (!dbOldPassword.equals(adminUser.getPassword())) {
                throw new ServiceException(SystemErrorCode.E921.code(), "原密码错误");
            }
            adminUserVO.setPassword(password);
        } else {
            adminUserVO.setPassword("");
        }
        adminUserVO.setFace(face);
        AdminUser upAdminUser = adminUserManager.edit(adminUserVO, adminUser.getId());
        this.adminUserManager.logout(uid);
        return upAdminUser;
    }

    @ApiOperation(value = "注销管理员登录")
    @PostMapping(value = "/logout")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "uid", value = "管理员id", dataType = "int", paramType = "query", required = true)
    })
    public String loginOut(@NotNull(message = "管理员id不能为空") Long uid) {
        this.adminUserManager.logout(uid);
        return null;
    }

    @ApiOperation(value = "查询当前管理员的信息")
    @GetMapping(value = "/info")
    public AdminUser info() {
        return this.adminUserManager.getModel(AdminUserContext.getAdminUserId());
    }


    @GetMapping("/login/getCompany")
    public List<CompanyErp> loginGetCompany(String key) {
        return companyManager.list(new LambdaQueryWrapper<CompanyErp>()
                .select(CompanyErp::getId, CompanyErp::getName)
                .and(StrUtil.isNotBlank(key), item -> item.like(CompanyErp::getName, key)
                        .or()
                        .like(CompanyErp::getFirstPy, key)
                        .or()
                        .like(CompanyErp::getPinying, key)));
    }

    @GetMapping("/loginGetCheckCode")
    @ApiOperation(value = "获取验证码")
    public String getCheckCode(String phone) {
        Map<String, Object> map = new HashMap<>();
        String fastUUID = IdUtil.fastUUID();
        Random random = new Random();
        int randomNumber = 100000 + random.nextInt(900000);
        map.put("code", randomNumber);
        AliSmsUtil.sendSms(phone, MsgContant.CHECK_CODE_SMS, JSON.toJSONString(map));
        redisTemplate.opsForValue().set(fastUUID, String.valueOf(randomNumber));
        redisTemplate.expire(fastUUID, 5, TimeUnit.HOURS);
        return fastUUID;
    }
}
