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 jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

import com.vaessl.app.shared.ServiceType;
import com.vaessl.app.shared.SessionKeys;

@RestController
@RequiredArgsConstructor
public class ConnectionController {

    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(SessionKeys.connectionId(request.serviceType()), 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(SessionKeys.CONNECTION_ID_SUFFIX))
                .forEach(k -> {
                    String name = k.replace(SessionKeys.CONNECTION_ID_SUFFIX, "");
                    try {
                        ServiceType serviceType = ServiceType.valueOf(name);
                        Long id = (Long) session.getAttribute(k);
                        ConnectionStatusResponse status =
                                connectionService.getConnectionStatus(serviceType, id);
                        if (status != null)
                            statuses.add(status);
                    } catch (IllegalArgumentException _) {
                        // stale session key from an old or removed service type — skip it
                    }
                });

        return ResponseEntity.ok(statuses);
    }

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

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

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