package com.vaessl.app.connection;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.vaessl.app.dto.AuthResponse;
import com.vaessl.app.dto.ConnectionRequest;
import com.vaessl.app.dto.ConnectionStatusResponse;
import com.vaessl.app.dto.LoginResult;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
public class ConnectionController {

    private static final String SUFFIX = "_CONNECTION_ID";

    private final ConnectionService connectionService;

    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(
            @Valid @RequestBody ConnectionRequest request,
            HttpServletRequest httpReq) {

        LoginResult result = connectionService.login(request);

        HttpSession session = httpReq.getSession(true);
        session.setAttribute(request.serviceType() + SUFFIX, result.connectionId());

        if (result.expiresAt() != null) {
            long secs = Instant.now().until(result.expiresAt(), ChronoUnit.SECONDS);
            session.setMaxInactiveInterval((int) Math.max(secs, 300));
        }

        return ResponseEntity.ok(new AuthResponse(request.serviceType(), result.expiresAt()));
    }

    @GetMapping("/connections/status")
    public ResponseEntity<List<ConnectionStatusResponse>> getStatus(HttpServletRequest httpReq) {
        HttpSession session = httpReq.getSession(false);
        if (session == null) {
            return ResponseEntity.ok(List.of());
        }

        List<ConnectionStatusResponse> statuses = new ArrayList<>();
        Collections.list(session.getAttributeNames()).stream()
                .filter(k -> k.endsWith(SUFFIX))
                .forEach(k -> {
                    String serviceType = k.replace(SUFFIX, "");
                    Long id = (Long) session.getAttribute(k);
                    ConnectionStatusResponse status = connectionService.getConnectionStatus(serviceType, id);
                    if (status != null) statuses.add(status);
                });

        return ResponseEntity.ok(statuses);
    }

    @DeleteMapping("/connections/{serviceType}")
    public ResponseEntity<Void> logout(
            @PathVariable("serviceType") String serviceType,
            HttpServletRequest httpReq) {

        HttpSession session = httpReq.getSession(false);
        if (session != null) {
            session.removeAttribute(serviceType + SUFFIX);
            boolean hasMore = Collections.list(session.getAttributeNames()).stream()
                    .anyMatch(k -> k.endsWith(SUFFIX));
            if (!hasMore) {
                session.invalidate();
            }
        }

        return ResponseEntity.noContent().build();
    }
}
