package com.gpf.pethospital.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gpf.pethospital.common.ApiResponse;
import com.gpf.pethospital.dto.LoginRequest;
import com.gpf.pethospital.dto.RegisterRequest;
import com.gpf.pethospital.entity.User;
import com.gpf.pethospital.service.UserService;
import com.gpf.pethospital.util.JwtUtil;
import jakarta.validation.Valid;
import org.springframework.security.crypto.password.PasswordEncoder;
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.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/auth")
public class AuthController {
    private final UserService userService;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtil jwtUtil;

    public AuthController(UserService userService, PasswordEncoder passwordEncoder, JwtUtil jwtUtil) {
        this.userService = userService;
        this.passwordEncoder = passwordEncoder;
        this.jwtUtil = jwtUtil;
    }

    @PostMapping("/register")
    public ApiResponse<?> register(@Valid @RequestBody RegisterRequest request) {
        if ((request.getPhone() == null || request.getPhone().isBlank())
                && (request.getEmail() == null || request.getEmail().isBlank())) {
            return ApiResponse.error(400, "phone or email is required");
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername())
                .or()
                .eq(request.getPhone() != null && !request.getPhone().isBlank(), User::getPhone, request.getPhone())
                .or()
                .eq(request.getEmail() != null && !request.getEmail().isBlank(), User::getEmail, request.getEmail());
        if (userService.count(wrapper) > 0) {
            return ApiResponse.error(409, "user already exists");
        }
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPhone(request.getPhone());
        user.setEmail(request.getEmail());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setRole("CUSTOMER");
        user.setStatus(1);
        userService.save(user);
        return ApiResponse.success("registered", null);
    }

    @PostMapping("/login")
    public ApiResponse<?> login(@Valid @RequestBody LoginRequest request) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getAccount())
                .or()
                .eq(User::getPhone, request.getAccount())
                .or()
                .eq(User::getEmail, request.getAccount());
        User user = userService.getOne(wrapper);
        if (user == null || user.getStatus() != null && user.getStatus() == 0) {
            return ApiResponse.error(401, "invalid account or disabled");
        }
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            return ApiResponse.error(401, "invalid account or password");
        }
        String token = jwtUtil.generateToken(user.getId(), user.getRole(), user.getUsername());
        Map<String, Object> data = new HashMap<>();
        data.put("token", token);
        data.put("role", user.getRole());
        data.put("userId", user.getId());
        data.put("username", user.getUsername());
        return ApiResponse.success(data);
    }
}
