package org.brapi.test.BrAPITestServer.system.service;

import org.brapi.test.BrAPITestServer.system.dto.LoginRequest;
import org.brapi.test.BrAPITestServer.system.dto.RegisterRequest;
import org.brapi.test.BrAPITestServer.system.dto.TokenResponse;
import org.brapi.test.BrAPITestServer.system.entity.SysUserEntity;
import org.brapi.test.BrAPITestServer.system.exception.AuthApiException;
import org.brapi.test.BrAPITestServer.system.repository.SysUserRepository;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class AuthService {

    private final SysUserRepository sysUserRepository;
    private final PasswordService passwordService;
    private final TokenService tokenService;

    public AuthService(
            SysUserRepository sysUserRepository,
            PasswordService passwordService,
            TokenService tokenService) {
        this.sysUserRepository = sysUserRepository;
        this.passwordService = passwordService;
        this.tokenService = tokenService;
    }

    @Transactional
    public TokenResponse register(RegisterRequest request) {
        String account = normalizeAccount(request.getAccount());
        String email = normalizeEmail(request.getEmail());
        String phone = normalizeOptional(request.getPhone());

        if (sysUserRepository.existsByAccount(account) || sysUserRepository.existsByEmail(email)) {
            throw new AuthApiException(HttpStatus.CONFLICT, "Account or email already exists");
        }

        SysUserEntity user = new SysUserEntity();
        user.setAccount(account);
        user.setPasswordHash(passwordService.hashPassword(request.getPassword()));
        user.setName(request.getName().trim());
        user.setEmail(email);
        user.setPhone(phone);
        sysUserRepository.save(user);

        return tokenService.issueToken(user);
    }

    @Transactional
    public TokenResponse login(LoginRequest request) {
        String account = normalizeAccount(request.getAccount());
        SysUserEntity user = sysUserRepository.findByAccount(account)
                .orElseThrow(() -> new AuthApiException(HttpStatus.UNAUTHORIZED, "Invalid account or password"));

        if (!passwordService.verifyPassword(request.getPassword(), user.getPasswordHash())) {
            throw new AuthApiException(HttpStatus.UNAUTHORIZED, "Invalid account or password");
        }

        return tokenService.issueToken(user);
    }

    private String normalizeAccount(String account) {
        return account == null ? "" : account.trim();
    }

    private String normalizeEmail(String email) {
        return email == null ? "" : email.trim().toLowerCase();
    }

    private String normalizeOptional(String value) {
        if (value == null) {
            return null;
        }
        String trimmed = value.trim();
        return trimmed.isEmpty() ? null : trimmed;
    }
}
