package com.izouma.dingdong.web;

import cn.hutool.core.util.ObjectUtil;
import com.izouma.dingdong.domain.User;
import com.izouma.dingdong.dto.MerchantDTO;
import com.izouma.dingdong.enums.Identity;
import com.izouma.dingdong.exception.AuthenticationException;
import com.izouma.dingdong.security.Authority;
import com.izouma.dingdong.security.JwtTokenUtil;
import com.izouma.dingdong.security.JwtUserDetailsService;
import com.izouma.dingdong.security.JwtUserFactory;
import com.izouma.dingdong.service.UserService;
import com.izouma.dingdong.service.merchant.MerchantService;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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 java.math.BigDecimal;
import java.util.Collections;
import java.util.Objects;

@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/auth")
public class AuthenticationController {
    private AuthenticationManager authenticationManager;
    private JwtTokenUtil          jwtTokenUtil;
    private JwtUserDetailsService userDetailsService;
    private UserService           userService;

    private MerchantService merchantService;

    @PostMapping("/login")
    public String loginByUserPwd(String username, String password, Integer expiration) {
        try {
            authenticate(username, password);
            final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            return jwtTokenUtil.generateToken(userDetails);
        } catch (Exception e) {
            log.error("loginByUserPwd", e);
            throw new AuthenticationException("用户名或密码错误", e);
        }
    }

    @PostMapping("/phoneLogin")
    @ApiOperation(value = "手机号登录")
    public String phoneLogin(String phone) {
        try {
            User user = userService.loginByPhone(phone);
            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
        } catch (Exception e) {
            log.error("loginByPhone", e);
            throw new AuthenticationException("登陆错误", e);
        }
    }

    @PostMapping("/mpLogin")
    @ApiOperation(value = "公众号登录")
    public String mpLogin(String code) {
        try {
            User user = userService.loginMp(code);
            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
        } catch (Exception e) {
            log.error("loginByCode", e);
            throw new AuthenticationException("登陆错误", e);
        }
    }

    @PostMapping("/maLogin")
    @ApiOperation(value = "小程序登录")
    public String maLogin(String code) {
        try {
            User user = userService.loginMa(code);
            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
        } catch (Exception e) {
            log.error("loginByCode", e);
            throw new AuthenticationException("登陆错误", e);
        }
    }

    /**
     * Authenticates the user. If something is wrong, an {@link AuthenticationException} will be thrown
     */
    private void authenticate(String username, String password) {
        Objects.requireNonNull(username);
        Objects.requireNonNull(password);
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException e) {
            throw new AuthenticationException("User is disabled!", e);
        } catch (BadCredentialsException e) {
            throw new AuthenticationException("Bad credentials!", e);
        }
    }

    @PostMapping("/loginByRegister")
    @ApiOperation("注册登录")
    public String loginByRegister(String phone, String password,Identity identity) {
        try {
            User user = userService.register(phone, password, identity);
            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
        } catch (Exception e) {
            log.error("loginByRegister", e);
            throw new AuthenticationException("登录错误", e);
        }
    }

    @PostMapping("/merchantRegister")
    @ApiOperation("注册登录")
    public String registerMerchant(MerchantDTO merchantDTO) {
        try {
            User user = userService.merUser(merchantDTO);
            //User user = userService.register(merchantDTO.getPhone(), merchantDTO.getPassword(), Identity.MERCHANT);
            //商家信息
            merchantService.registerApply(merchantDTO);
            return jwtTokenUtil.generateToken(JwtUserFactory.create(user));
        } catch (Exception e) {
            log.error("merchantRegister", e);
            throw new AuthenticationException("登录错误", e);
        }
    }


}
