package ru.kirillius.pf.sdn.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.kirillius.pf.sdn.dto.AuthResponse;
import ru.kirillius.pf.sdn.dto.ChangePasswordRequest;
import ru.kirillius.pf.sdn.dto.ErrorResponse;
import ru.kirillius.pf.sdn.dto.LoginRequest;
import ru.kirillius.pf.sdn.service.AuthService;
import ru.kirillius.pf.sdn.service.SessionService;

@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {

    private final AuthService authService;
    private final SessionService sessionService;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest request) {
        return authService.login(request.getUsername(), request.getPassword())
                .<ResponseEntity<?>>map(token -> ResponseEntity.ok(new AuthResponse(token, request.getUsername())))
                .orElse(ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                        .body(new ErrorResponse("Invalid username or password")));
    }

    @PostMapping("/logout")
    public ResponseEntity<?> logout(@RequestHeader("Authorization") String authHeader) {
        var maybeToken = sessionService.extractToken(authHeader);
        if (maybeToken.isEmpty()) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(new ErrorResponse("Missing or invalid Authorization header"));
        }
        sessionService.invalidate(maybeToken.get());
        return ResponseEntity.ok().build();
    }

    @PostMapping("/change-password")
    public ResponseEntity<?> changePassword(
            @RequestHeader("Authorization") String authHeader,
            @RequestBody ChangePasswordRequest request) {

        var maybeToken = sessionService.extractToken(authHeader);
        if (maybeToken.isEmpty()) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(new ErrorResponse("Missing or invalid Authorization header"));
        }

        String token = maybeToken.get();
        var maybeUserId = authService.validateToken(token);
        if (maybeUserId.isEmpty()) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
                    .body(new ErrorResponse("Invalid token"));
        }

        boolean changed = authService.changePassword(maybeUserId.get(), request.getOldPassword(), request.getNewPassword());
        if (changed) {
            sessionService.invalidate(token);
            return ResponseEntity.ok(new AuthResponse(null, null));
        }

        return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                .body(new ErrorResponse("Old password is incorrect"));
    }
}
