package at.procon.dip.domain.document.service;

import at.procon.dip.domain.document.CanonicalDocumentMetadata;
import at.procon.dip.domain.document.DocumentStatus;
import at.procon.dip.domain.document.entity.Document;
import at.procon.dip.domain.document.repository.DocumentRepository;
import at.procon.dip.domain.document.service.command.CreateDocumentCommand;
import at.procon.dip.domain.tenant.entity.DocumentTenant;
import at.procon.dip.domain.tenant.repository.DocumentTenantRepository;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class DocumentService {

    private final DocumentRepository documentRepository;
    private final DocumentTenantRepository tenantRepository;

    public Document create(CreateDocumentCommand command) {
        DocumentTenant ownerTenant = resolveOwnerTenant(command.ownerTenantKey());
        Document document = Document.builder()
                .ownerTenant(ownerTenant)
                .visibility(command.visibility())
                .documentType(command.documentType())
                .documentFamily(command.documentFamily())
                .status(command.status() == null ? DocumentStatus.RECEIVED : command.status())
                .title(command.title())
                .summary(command.summary())
                .languageCode(command.languageCode())
                .mimeType(command.mimeType())
                .businessKey(command.businessKey())
                .dedupHash(command.dedupHash())
                .build();
        return documentRepository.save(document);
    }

    public Document save(Document document) {
        return documentRepository.save(document);
    }

    public Document updateStatus(UUID documentId, DocumentStatus status) {
        Document document = getRequired(documentId);
        document.setStatus(status);
        return documentRepository.save(document);
    }

    @Transactional(readOnly = true)
    public Document getRequired(UUID documentId) {
        return documentRepository.findById(documentId)
                .orElseThrow(() -> new IllegalArgumentException("Unknown document id: " + documentId));
    }

    @Transactional(readOnly = true)
    public List<Document> findAll() {
        return documentRepository.findAll();
    }

    @Transactional(readOnly = true)
    public CanonicalDocumentMetadata getMetadata(UUID documentId) {
        return getRequired(documentId).toCanonicalMetadata();
    }

    private DocumentTenant resolveOwnerTenant(String ownerTenantKey) {
        if (ownerTenantKey == null || ownerTenantKey.isBlank()) {
            return null;
        }
        return tenantRepository.findByTenantKey(ownerTenantKey)
                .orElseThrow(() -> new IllegalArgumentException("Unknown tenant key: " + ownerTenantKey));
    }
}
