package fastweb.controller.system;

import fastweb.QueryVo.IdQuery;
import fastweb.QueryVo.PasswordVo;
import fastweb.controller.BaseController;
import fastweb.domain.system.WrapperResult;
import fastweb.domain.usertype.User;
import fastweb.respository.userType.UserRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/user")
public class UserController extends BaseController {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 分别对应增删改查
     * <p>
     * list查询列表方法
     *
     * @return
     */
    @RequestMapping("/list")
    private WrapperResult list(@RequestParam(value = "page", defaultValue = "1") Integer page,
                               @RequestParam(value = "limit", defaultValue = "20") Integer limit,
                               @RequestParam(value = "name",required = false)String name) {
        try {
            Sort sort = new Sort(Sort.Direction.DESC, "id");
            Pageable pageable = new PageRequest(page - 1, limit, sort);
            Specification<User> userSpecification = (root, query, cb) -> {
                List<Predicate> preList = new ArrayList<Predicate>();
                if(!StringUtils.isEmpty(name)) {
                    Predicate predicate = cb.like(root.get("account"),"%" + name+"%");
                    preList.add(predicate);
                }
                User u  = getLoginUser();
                if (u.getType() == "2") {
                    Predicate predicate = cb.equal(root.get("id"), u.getId());
                    preList.add(predicate);
                }
                query.where(preList.toArray(new Predicate[preList.size()]));
                return null;
            };
            Page<User> contents = userRepository.findAll(userSpecification,pageable);
            return WrapperResult.successWrapedResult(contents);
        } catch (Exception e) {
            return WrapperResult.failedWrappedResult(e.getMessage());
        }
    }

    @RequestMapping("/listAll")
    private WrapperResult listAll() {
        try {
            Specification<User> specification = new Specification<User>() {
                @Override
                public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    List<Predicate> preList = new ArrayList<Predicate>();
                    Predicate predicate = cb.isNull(root.get("type"));
                    preList.add(predicate);
                    query.where(preList.toArray(new Predicate[preList.size()]));
                    return null;
                }
            };
            return WrapperResult.successWrapedResult(userRepository.findAll(specification));
        } catch (Exception e) {
            return WrapperResult.failedWrappedResult(e.getMessage());
        }
    }

    @PutMapping("/password")
    private WrapperResult password(@RequestBody PasswordVo passwordVo){
       try {
           String id = getLoginUserId();
           Optional<User> user = userRepository.findById(id);
           User user1 = user.get();
           if (!passwordEncoder.matches(passwordVo.getPassword(), user1.getPassword())) {
               String msg = "密码错误";
               throw new BadCredentialsException(msg);
           }
           String password = passwordEncoder.encode(passwordVo.getNewPassword());
           user1.setPassword(password);
           userRepository.save(user1);
           return WrapperResult.successWrapedResult(user1);
       }catch (Exception ex) {
           return WrapperResult.failedWrappedResult(ex.getMessage());
       }
    }

    /**
     * 查询单个方法
     *
     * @param id
     * @return
     */
    @RequestMapping("/getuser/{id}")
    private WrapperResult get(@PathVariable String id) {
        try {
            if (StringUtils.isEmpty(id)) {
                return WrapperResult.failedWrappedResult("id不能为空");
            }
            User content = userRepository.getOne(id);
            return WrapperResult.successWrapedResult(content);
        } catch (Exception e) {
            return WrapperResult.failedWrappedResult(e.getMessage());
        }
    }

    /**
     * 新增或修改方法
     *
     * @param content
     * @return
     */
    @PostMapping("/saveorupdate")
    private WrapperResult saveOrUpdate(@RequestBody User content) {
        try {
            if (StringUtils.isEmpty(content.getId())) {
                String password = passwordEncoder.encode(content.getPassword());
                content.setPassword(password);
                content.setCreatedDate(new Date(System.currentTimeMillis()));
                User contentNew = userRepository.save(content);
                return WrapperResult.successWrapedResult(contentNew);
            } else {
                Optional<User> contentOld = userRepository.findById(content.getId());
                if (contentOld.isPresent()) {
                    BeanUtils.copyProperties(content, contentOld.get(),"password","createdDate");
                    userRepository.save(contentOld.get());
                }
                return WrapperResult.successWrapedResult(contentOld.get());
            }
        } catch (Exception e) {
            return WrapperResult.failedWrappedResult(e.getMessage());
        }
    }

    /**
     * 删除方法
     *
     * @param
     * @return
     */
    @PostMapping("/del")
    private WrapperResult del(@RequestBody IdQuery idQuery) {
        try {
            if (StringUtils.isEmpty(idQuery.getId())) {
                return WrapperResult.failedWrappedResult("id 不能为空");
            } else {
                userRepository.deleteById(idQuery.getId());
                return WrapperResult.successWrapedResult("删除成功");
            }
        } catch (Exception e) {
            return WrapperResult.failedWrappedResult(e.getMessage());
        }
    }

    @PostMapping("/logout")
    private WrapperResult logout(HttpServletRequest httpServletRequest) {
        try {
            String token = httpServletRequest.getHeader("token");
            if (StringUtils.isEmpty(token)) {
                return WrapperResult.successWrapedResult("用户已退出");
            }
            stringRedisTemplate.delete(token);
            String id = getLoginUserId();
            if (!StringUtils.isEmpty(id)) {
                stringRedisTemplate.delete(id);
            }
            return WrapperResult.successWrapedResult("成功");
        } catch (Exception e) {
            return WrapperResult.failedWrappedResult(e.getMessage());
        }
    }
}
