package net.siegeln.cameleer.saas.vendor;

import jakarta.validation.Valid;
import net.siegeln.cameleer.saas.identity.ServerApiClient.ServerHealthResponse;
import net.siegeln.cameleer.saas.license.dto.LicenseResponse;
import net.siegeln.cameleer.saas.provisioning.ServerStatus;
import net.siegeln.cameleer.saas.tenant.TenantEntity;
import net.siegeln.cameleer.saas.tenant.dto.CreateTenantRequest;
import net.siegeln.cameleer.saas.tenant.dto.TenantResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.jwt.Jwt;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/vendor/tenants")
@PreAuthorize("hasAuthority('SCOPE_platform:admin')")
public class VendorTenantController {

    private final VendorTenantService vendorTenantService;

    public VendorTenantController(VendorTenantService vendorTenantService) {
        this.vendorTenantService = vendorTenantService;
    }

    // --- Response types ---

    public record VendorTenantSummary(
            UUID id,
            String name,
            String slug,
            String tier,
            String status,
            String serverState,
            String licenseExpiry,
            String provisionError
    ) {}

    public record VendorTenantDetail(
            TenantResponse tenant,
            String serverState,
            boolean serverHealthy,
            String serverStatus,
            LicenseResponse license
    ) {}

    // --- Endpoints ---

    @GetMapping
    public ResponseEntity<List<VendorTenantSummary>> listAll() {
        List<VendorTenantSummary> summaries = vendorTenantService.listAll().stream()
                .map(tenant -> {
                    ServerStatus status = vendorTenantService.getServerStatus(tenant);
                    String licenseExpiry = vendorTenantService
                            .getLicenseForTenant(tenant.getId())
                            .map(l -> l.getExpiresAt() != null ? l.getExpiresAt().toString() : null)
                            .orElse(null);
                    return new VendorTenantSummary(
                            tenant.getId(), tenant.getName(), tenant.getSlug(),
                            tenant.getTier().name(), tenant.getStatus().name(),
                            status.state().name(), licenseExpiry, tenant.getProvisionError()
                    );
                })
                .toList();
        return ResponseEntity.ok(summaries);
    }

    @PostMapping
    public ResponseEntity<TenantResponse> create(@Valid @RequestBody CreateTenantRequest request,
                                                  @AuthenticationPrincipal Jwt jwt) {
        UUID actorId = resolveActorId(jwt);
        try {
            TenantEntity tenant = vendorTenantService.createAndProvision(request, actorId);
            return ResponseEntity.status(HttpStatus.CREATED).body(TenantResponse.from(tenant));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.status(HttpStatus.CONFLICT).build();
        }
    }

    @GetMapping("/{id}")
    public ResponseEntity<VendorTenantDetail> getById(@PathVariable UUID id) {
        return vendorTenantService.getById(id)
                .map(tenant -> {
                    ServerStatus serverStatus = vendorTenantService.getServerStatus(tenant);
                    ServerHealthResponse health = vendorTenantService.getServerHealth(tenant);
                    LicenseResponse license = vendorTenantService
                            .getLicenseForTenant(id)
                            .map(LicenseResponse::from)
                            .orElse(null);
                    return ResponseEntity.ok(new VendorTenantDetail(
                            TenantResponse.from(tenant),
                            serverStatus.state().name(),
                            health.healthy(),
                            health.status(),
                            license
                    ));
                })
                .orElse(ResponseEntity.notFound().build());
    }

    @PostMapping("/{id}/suspend")
    public ResponseEntity<TenantResponse> suspend(@PathVariable UUID id,
                                                   @AuthenticationPrincipal Jwt jwt) {
        UUID actorId = resolveActorId(jwt);
        try {
            TenantEntity tenant = vendorTenantService.suspend(id, actorId);
            return ResponseEntity.ok(TenantResponse.from(tenant));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @PostMapping("/{id}/activate")
    public ResponseEntity<TenantResponse> activate(@PathVariable UUID id,
                                                    @AuthenticationPrincipal Jwt jwt) {
        UUID actorId = resolveActorId(jwt);
        try {
            TenantEntity tenant = vendorTenantService.activate(id, actorId);
            return ResponseEntity.ok(TenantResponse.from(tenant));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable UUID id,
                                        @AuthenticationPrincipal Jwt jwt) {
        UUID actorId = resolveActorId(jwt);
        try {
            vendorTenantService.delete(id, actorId);
            return ResponseEntity.noContent().build();
        } catch (IllegalArgumentException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @PostMapping("/{id}/license")
    public ResponseEntity<LicenseResponse> renewLicense(@PathVariable UUID id,
                                                         @AuthenticationPrincipal Jwt jwt) {
        UUID actorId = resolveActorId(jwt);
        try {
            var license = vendorTenantService.renewLicense(id, actorId);
            return ResponseEntity.ok(LicenseResponse.from(license));
        } catch (IllegalArgumentException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @GetMapping("/{id}/health")
    public ResponseEntity<ServerHealthResponse> health(@PathVariable UUID id) {
        return vendorTenantService.getById(id)
                .map(tenant -> ResponseEntity.ok(vendorTenantService.getServerHealth(tenant)))
                .orElse(ResponseEntity.notFound().build());
    }

    // --- Helpers ---

    private UUID resolveActorId(Jwt jwt) {
        try {
            return UUID.fromString(jwt.getSubject());
        } catch (Exception e) {
            return UUID.nameUUIDFromBytes(jwt.getSubject().getBytes());
        }
    }
}
