package net.siegeln.cameleer.saas.license;

import net.siegeln.cameleer.saas.license.dto.LicenseResponse;
import net.siegeln.cameleer.saas.tenant.TenantService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.Duration;
import java.util.UUID;

@RestController
@RequestMapping("/api/tenants/{tenantId}/license")
public class LicenseController {

    private final LicenseService licenseService;
    private final TenantService tenantService;

    public LicenseController(LicenseService licenseService, TenantService tenantService) {
        this.licenseService = licenseService;
        this.tenantService = tenantService;
    }

    @PostMapping
    @PreAuthorize("hasAuthority('SCOPE_billing:manage')")
    public ResponseEntity<LicenseResponse> generate(@PathVariable UUID tenantId,
                                                     Authentication authentication) {
        var tenant = tenantService.getById(tenantId).orElse(null);
        if (tenant == null) return ResponseEntity.notFound().build();

        // Extract actor ID from JWT subject (Logto OIDC: sub may be a non-UUID string)
        String sub = authentication.getName();
        UUID actorId;
        try {
            actorId = UUID.fromString(sub);
        } catch (IllegalArgumentException e) {
            actorId = UUID.nameUUIDFromBytes(sub.getBytes());
        }

        var license = licenseService.generateLicense(tenant, Duration.ofDays(365), actorId);
        return ResponseEntity.status(HttpStatus.CREATED).body(toResponse(license));
    }

    @GetMapping
    public ResponseEntity<LicenseResponse> getActive(@PathVariable UUID tenantId) {
        return licenseService.getActiveLicense(tenantId)
                .map(entity -> ResponseEntity.ok(toResponse(entity)))
                .orElse(ResponseEntity.notFound().build());
    }

    private LicenseResponse toResponse(LicenseEntity entity) {
        return new LicenseResponse(
                entity.getId(),
                entity.getTenantId(),
                entity.getTier(),
                entity.getFeatures(),
                entity.getLimits(),
                entity.getIssuedAt(),
                entity.getExpiresAt(),
                entity.getToken()
        );
    }
}
