package net.siegeln.cameleer.saas.tenant;

import net.siegeln.cameleer.saas.audit.AuditAction;
import net.siegeln.cameleer.saas.audit.AuditService;
import net.siegeln.cameleer.saas.identity.LogtoManagementClient;
import net.siegeln.cameleer.saas.tenant.dto.CreateTenantRequest;
import org.springframework.stereotype.Service;

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

@Service
public class TenantService {

    private final TenantRepository tenantRepository;
    private final AuditService auditService;
    private final LogtoManagementClient logtoClient;

    public TenantService(TenantRepository tenantRepository, AuditService auditService, LogtoManagementClient logtoClient) {
        this.tenantRepository = tenantRepository;
        this.auditService = auditService;
        this.logtoClient = logtoClient;
    }

    public TenantEntity create(CreateTenantRequest request, UUID actorId) {
        if (tenantRepository.existsBySlugAndStatusNot(request.slug(), TenantStatus.DELETED)) {
            throw new IllegalArgumentException("Slug already taken");
        }

        var entity = new TenantEntity();
        entity.setName(request.name());
        entity.setSlug(request.slug());
        entity.setTier(request.tier() != null ? Tier.valueOf(request.tier()) : Tier.LOW);
        entity.setStatus(TenantStatus.PROVISIONING);

        var saved = tenantRepository.save(entity);

        if (logtoClient.isAvailable()) {
            String logtoOrgId = logtoClient.createOrganization(saved.getName(), "Tenant: " + saved.getSlug());
            if (logtoOrgId != null) {
                saved.setLogtoOrgId(logtoOrgId);
                saved = tenantRepository.save(saved);
            }
        }

        auditService.log(actorId, null, saved.getId(),
                AuditAction.TENANT_CREATE, saved.getSlug(),
                null, null, "SUCCESS", null);

        return saved;
    }

    public Optional<TenantEntity> getById(UUID id) {
        return tenantRepository.findById(id);
    }

    public Optional<TenantEntity> getBySlug(String slug) {
        return tenantRepository.findBySlug(slug);
    }

    public Optional<TenantEntity> getByLogtoOrgId(String logtoOrgId) {
        return tenantRepository.findByLogtoOrgId(logtoOrgId);
    }

    public List<TenantEntity> findAll() {
        return tenantRepository.findAll();
    }

    public List<TenantEntity> listActive() {
        return tenantRepository.findByStatus(TenantStatus.ACTIVE);
    }

    public TenantEntity activate(UUID tenantId, UUID actorId) {
        var entity = tenantRepository.findById(tenantId)
                .orElseThrow(() -> new IllegalArgumentException("Tenant not found"));
        entity.setStatus(TenantStatus.ACTIVE);
        var saved = tenantRepository.save(entity);

        auditService.log(actorId, null, tenantId,
                AuditAction.TENANT_UPDATE, entity.getSlug(),
                null, null, "SUCCESS", null);

        return saved;
    }

    public TenantEntity suspend(UUID tenantId, UUID actorId) {
        var entity = tenantRepository.findById(tenantId)
                .orElseThrow(() -> new IllegalArgumentException("Tenant not found"));
        entity.setStatus(TenantStatus.SUSPENDED);
        var saved = tenantRepository.save(entity);

        auditService.log(actorId, null, tenantId,
                AuditAction.TENANT_SUSPEND, entity.getSlug(),
                null, null, "SUCCESS", null);

        return saved;
    }
}
