package com.goldenchart.service;

import com.goldenchart.auth.UserRole;
import com.goldenchart.dto.LoginResponse;
import com.goldenchart.entity.GcUser;
import com.goldenchart.repository.GcUserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class AuthService {

    private final GcUserRepository userRepo;
    private final PasswordEncoder passwordEncoder;

    @Transactional(readOnly = true)
    public LoginResponse login(String username, String password) {
        if (username == null || username.isBlank() || password == null || password.isBlank()) {
            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "아이디와 비밀번호를 입력하세요.");
        }
        GcUser user = userRepo.findByUsername(username.trim())
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.UNAUTHORIZED, "아이디 또는 비밀번호가 올바르지 않습니다."));
        if (!Boolean.TRUE.equals(user.getEnabled())) {
            throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "비활성화된 계정입니다.");
        }
        if (!passwordEncoder.matches(password, user.getPasswordHash())) {
            throw new ResponseStatusException(HttpStatus.UNAUTHORIZED, "아이디 또는 비밀번호가 올바르지 않습니다.");
        }
        return toLoginResponse(user);
    }

    @Transactional(readOnly = true)
    public Optional<LoginResponse> me(Long userId) {
        if (userId == null) return Optional.empty();
        return userRepo.findById(userId)
                .filter(u -> Boolean.TRUE.equals(u.getEnabled()))
                .map(this::toLoginResponse);
    }

    private LoginResponse toLoginResponse(GcUser user) {
        return LoginResponse.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .displayName(user.getDisplayName() != null ? user.getDisplayName() : user.getUsername())
                .role(user.getRole() != null ? user.getRole() : UserRole.USER.name())
                .build();
    }

    /** 기본 관리자 계정 (admin / admin) — 없으면 생성 */
    @Transactional
    public void ensureDefaultAdmin() {
        if (userRepo.findByUsername("admin").isPresent()) return;
        userRepo.save(GcUser.builder()
                .username("admin")
                .passwordHash(passwordEncoder.encode("admin"))
                .displayName("관리자")
                .enabled(true)
                .role(UserRole.ADMIN.name())
                .build());
    }
}
