package com.dtok.api.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.secure.SaSecureUtil;
import cn.hutool.crypto.SecureUtil;

import cn.hutool.db.nosql.redis.RedisDS;
import com.dtok.entity.Account;
import com.dtok.framework.exception.BizExceptionEnum;
import com.dtok.framework.exception.ServiceException;
import com.dtok.framework.response.ResponseData;
import com.dtok.framework.util.PasswordUtil;
import com.dtok.framework.util.ToolUtil;
import com.dtok.repository.AccountRepository;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import redis.clients.jedis.Jedis;

import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.util.*;

@RequestMapping("/user")
@RestController
@ApiOperation(value = "用户")
public class UserController {

    @Autowired
    AccountRepository userRepository;


    @GetMapping("/search")
    public ResponseData search(@RequestParam(value = "username", required = false) String username,
                               @RequestParam(value = "name", required = false) String name) {

        Specification<Account> query = (root, query1, criteriaBuilder) -> {
            Predicate predicate = criteriaBuilder.conjunction();
            root.join("role", JoinType.LEFT);
            if (ToolUtil.isNotEmpty(username)) {
                predicate.getExpressions().add(criteriaBuilder.or(criteriaBuilder.equal(root.get("username"), username)));
            }
            if (ToolUtil.isNotEmpty(name)) {
                predicate.getExpressions().add(criteriaBuilder.or(criteriaBuilder.like(root.get("name"), "%" + name + "%")));
            }
            return predicate;
        };

        List<Account> users = userRepository.findAll(query);
        return ResponseData.success(users);
    }


    @GetMapping("/delete/{username}")
    @Transactional(rollbackFor = Exception.class)
    public ResponseData delete(@PathVariable("username") String username) {
        Account user = userRepository.getFirstByUsername(username);
        if (Objects.isNull(user)) {
            throw new ServiceException(BizExceptionEnum.NO_THIS_USER);
        }

        if (user.getRoleCode().equals(Account.FINAL_ROLE)) {
            throw new ServiceException(BizExceptionEnum.CANT_DELETE_ADMIN);
        }
        userRepository.delete(user);
        return ResponseData.success("删除成功");
    }

    @PostMapping("/update")
    public ResponseData update(Account user) {
        Account account = userRepository.getFirstByUsername(user.getUsername());
        if (Objects.isNull(account)) {
            throw new ServiceException(BizExceptionEnum.NO_THIS_USER);
        }

        if (account.getIsSuper() && !user.getStatus()) {
            throw new ServiceException(BizExceptionEnum.CANT_FREEZE_ADMIN);
        }

        if (account.getIsSuper() && !user.getIsSuper()) {
            throw new ServiceException(BizExceptionEnum.CANT_CHANGE_ADMIN);
        }

        if (account.getIsSuper() && !user.getRoleCode().equals(Account.FINAL_ROLE)) {
            throw new ServiceException(BizExceptionEnum.CANT_CHANGE_ADMIN);
        }

        account.setName(user.getName());
        account.setRoleCode(user.getRoleCode());
        account.setExpireAt(user.getExpireAt());
        account.setMaxDevices(user.getMaxDevices());
        account.setPhoneNumber(user.getPhoneNumber());
        userRepository.save(account);
        return ResponseData.success("修改成功");
    }

    @PostMapping("/add")
    public ResponseData add(Account user) {
        if (!ToolUtil.isNotEmpty(user.getUsername())) {
            throw new NullPointerException("用户名不能为空");
        }
        if (!ToolUtil.isNotEmpty(user.getPassword())) {
            throw new NullPointerException("密码不能为空");
        }
        if (!ToolUtil.isNotEmpty(user.getRoleCode())) {
            throw new NullPointerException("角色不能为空");
        }
        if (!ToolUtil.isNotEmpty(user.getName())) {
            throw new NullPointerException("姓名不能为空");
        }
        Account account = userRepository.getUserLoginEntity(user.getUsername());
        if (!Objects.isNull(account)) {
            throw new ServiceException(BizExceptionEnum.USER_ALREADY);
        }
        if (user.getIsSuper()) {
            user.setRoleCode(Account.FINAL_ROLE);
        }

        String salt = PasswordUtil.getSalt();
        user.setPassword(SaSecureUtil.aesEncrypt(salt, user.getPassword()));
        user.setSalt(salt);
        user.setCreatedAt(new Date());
        user.setStatus(true);
        userRepository.save(user);
        return ResponseData.success(user);
    }

    @PostMapping("/disable/{code}")
    public ResponseData disable(@PathVariable("code") String code) {
        Account account = userRepository.getFirstByUsername(code);
        if (Objects.isNull(account)) {
            throw new NullPointerException(BizExceptionEnum.NO_THIS_USER.getMessage());
        }
        if (Account.FINAL_ROLE.equals(account.getRoleCode())) {
            throw new ServiceException(BizExceptionEnum.CANT_FREEZE_ADMIN);
        }
        account.setStatus(!account.getStatus());
        userRepository.save(account);
        if (account.getStatus()) {
            return ResponseData.success("启用成功");
        } else {
            return ResponseData.success("禁用成功");
        }
    }


}
