package kr.co.accura.wbx.spring.admin;

import kr.co.accura.wbx.spring.auth.*;
import kr.co.accura.wbx.spring.common.BusinessException;
import kr.co.accura.wbx.spring.common.NotFoundException;
import kr.co.accura.wbx.spring.rbac.WbxRole;
import kr.co.accura.wbx.spring.rbac.RolePermission;
import kr.co.accura.wbx.spring.rbac.RolePermissionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("${wbx.spring.api-prefix:/api}/admin")
@PreAuthorize("hasRole('SA')")
@RequiredArgsConstructor
public class AdminController {

    private final WbxUserRepository userRepository;
    private final LoginHistoryRepository loginHistoryRepository;
    private final WbxRoleRepository roleRepository;
    private final RolePermissionRepository permissionRepository;
    private final PasswordEncoder passwordEncoder;

    // ===== 사용자 관리 =====

    @GetMapping("/users")
    public Map<String, Object> listUsers(@RequestParam(defaultValue = "0") int skip,
                                          @RequestParam(defaultValue = "20") int limit) {
        Page<WbxUser> page = userRepository.findAll(PageRequest.of(skip / Math.max(limit, 1), limit));
        return Map.of("items", page.getContent(), "total", page.getTotalElements());
    }

    @GetMapping("/users/{id}")
    public WbxUser getUser(@PathVariable Long id) {
        return userRepository.findById(id)
                .orElseThrow(() -> new NotFoundException("User not found"));
    }

    @PostMapping("/users/{id}/unlock")
    public Map<String, String> unlockUser(@PathVariable Long id) {
        WbxUser user = userRepository.findById(id)
                .orElseThrow(() -> new NotFoundException("User not found"));
        user.setFailedLoginAttempts(0);
        user.setLastFailedLogin(null);
        user.setLockedUntil(null);
        userRepository.save(user);
        return Map.of("detail", "User unlocked");
    }

    @PostMapping("/users/{id}/reset-password")
    public Map<String, String> resetPassword(@PathVariable Long id) {
        WbxUser user = userRepository.findById(id)
                .orElseThrow(() -> new NotFoundException("User not found"));
        String tempPwd = "Temp" + System.currentTimeMillis() % 10000 + "!";
        user.setHashedPassword(passwordEncoder.encode(tempPwd));
        user.setMustChangePassword(true);
        userRepository.save(user);
        return Map.of("detail", "Password reset", "temp_password", tempPwd);
    }

    @PutMapping("/users/{id}/status")
    public Map<String, String> toggleStatus(@PathVariable Long id, @RequestBody Map<String, Boolean> req) {
        WbxUser user = userRepository.findById(id)
                .orElseThrow(() -> new NotFoundException("User not found"));
        user.setActive(req.getOrDefault("is_active", true));
        userRepository.save(user);
        return Map.of("detail", "Status updated");
    }

    // ===== 역할 관리 =====

    @GetMapping("/roles")
    public Map<String, Object> listRoles() {
        List<WbxRole> roles = roleRepository.findAll();
        return Map.of("items", roles, "total", roles.size());
    }

    @PostMapping("/roles")
    public WbxRole createRole(@RequestBody WbxRole role) {
        return roleRepository.save(role);
    }

    @GetMapping("/roles/{id}/permissions")
    public Map<String, Object> getRolePermissions(@PathVariable Long id) {
        List<RolePermission> perms = permissionRepository.findAll()
                .stream().filter(p -> p.getRoleId().equals(id)).toList();
        return Map.of("items", perms, "total", perms.size());
    }

    // ===== 로그인 이력 =====

    @GetMapping("/login-history")
    public Map<String, Object> loginHistory(@RequestParam(defaultValue = "0") int skip,
                                             @RequestParam(defaultValue = "50") int limit) {
        Page<WbxLoginHistory> page = loginHistoryRepository.findAllByOrderByCreatedAtDesc(
                PageRequest.of(skip / Math.max(limit, 1), limit));
        return Map.of("items", page.getContent(), "total", page.getTotalElements());
    }

    // ===== 시스템 상태 =====

    @GetMapping("/system-health")
    public Map<String, Object> systemHealth() {
        return Map.of(
                "users", userRepository.countByIsActiveTrue(),
                "status", "ok"
        );
    }
}
