package de.cannamanage.api.controller;

import de.cannamanage.api.dto.notification.RegisterDeviceRequest;
import de.cannamanage.domain.entity.DeviceToken;
import de.cannamanage.service.DeviceRegistrationService;
import de.cannamanage.service.push.WebPushSender;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.UUID;

/**
 * Device token registration endpoints for push notifications.
 * Any authenticated user can register/unregister their devices.
 */
@RestController
@RequestMapping("/api/v1/notifications/devices")
@RequiredArgsConstructor
public class DeviceRegistrationController {

    private final DeviceRegistrationService deviceRegistrationService;
    private final WebPushSender webPushSender;

    /**
     * Register a device token for push notifications.
     */
    @PostMapping
    public ResponseEntity<Map<String, Object>> registerDevice(
            @Valid @RequestBody RegisterDeviceRequest request,
            @AuthenticationPrincipal UserDetails user) {

        UUID userId = UUID.fromString(user.getUsername());

        try {
            DeviceToken device = deviceRegistrationService.registerDevice(
                    userId, request.platform(), request.token(), request.deviceName());

            return ResponseEntity.ok(Map.of(
                    "id", device.getId(),
                    "platform", device.getPlatform().name(),
                    "deviceName", device.getDeviceName() != null ? device.getDeviceName() : "",
                    "createdAt", device.getCreatedAt().toString()
            ));
        } catch (IllegalStateException e) {
            return ResponseEntity.badRequest().body(Map.of("error", e.getMessage()));
        }
    }

    /**
     * List user's registered devices.
     */
    @GetMapping
    public ResponseEntity<?> listDevices(@AuthenticationPrincipal UserDetails user) {
        UUID userId = UUID.fromString(user.getUsername());
        var devices = deviceRegistrationService.getDevices(userId);

        var items = devices.stream().map(d -> Map.of(
                "id", (Object) d.getId(),
                "platform", d.getPlatform().name(),
                "deviceName", d.getDeviceName() != null ? d.getDeviceName() : "",
                "lastUsedAt", d.getLastUsedAt() != null ? d.getLastUsedAt().toString() : "",
                "createdAt", d.getCreatedAt().toString()
        )).toList();

        return ResponseEntity.ok(Map.of("devices", items));
    }

    /**
     * Unregister a device.
     */
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> unregisterDevice(
            @PathVariable UUID id,
            @AuthenticationPrincipal UserDetails user) {
        UUID userId = UUID.fromString(user.getUsername());
        deviceRegistrationService.unregisterDevice(id, userId);
        return ResponseEntity.noContent().build();
    }

    /**
     * Get the VAPID public key for Web Push subscription on the frontend.
     */
    @GetMapping("/vapid-key")
    public ResponseEntity<Map<String, String>> getVapidKey() {
        return ResponseEntity.ok(Map.of(
                "publicKey", webPushSender.getPublicKey(),
                "configured", String.valueOf(webPushSender.isConfigured())
        ));
    }
}
