package de.effigenix.domain.inventory;

public sealed interface StockError {

    String code();
    String message();

    record DuplicateStock(String articleId, String storageLocationId) implements StockError {
        @Override public String code() { return "DUPLICATE_STOCK"; }
        @Override public String message() { return "Stock already exists for article " + articleId + " at location " + storageLocationId; }
    }

    record InvalidMinimumLevel(String reason) implements StockError {
        @Override public String code() { return "INVALID_MINIMUM_LEVEL"; }
        @Override public String message() { return "Invalid minimum level: " + reason; }
    }

    record InvalidMinimumShelfLife(int days) implements StockError {
        @Override public String code() { return "INVALID_MINIMUM_SHELF_LIFE"; }
        @Override public String message() { return "Minimum shelf life must be > 0, was: " + days; }
    }

    record StockNotFound(String id) implements StockError {
        @Override public String code() { return "STOCK_NOT_FOUND"; }
        @Override public String message() { return "Stock not found: " + id; }
    }

    record InvalidArticleId(String reason) implements StockError {
        @Override public String code() { return "INVALID_ARTICLE_ID"; }
        @Override public String message() { return "Invalid article ID: " + reason; }
    }

    record InvalidStorageLocationId(String reason) implements StockError {
        @Override public String code() { return "INVALID_STORAGE_LOCATION_ID"; }
        @Override public String message() { return "Invalid storage location ID: " + reason; }
    }

    record InvalidBatchReference(String reason) implements StockError {
        @Override public String code() { return "INVALID_BATCH_REFERENCE"; }
        @Override public String message() { return "Invalid batch reference: " + reason; }
    }

    record DuplicateBatchReference(String batchId, String batchType) implements StockError {
        @Override public String code() { return "DUPLICATE_BATCH_REFERENCE"; }
        @Override public String message() { return "Batch reference already exists: " + batchId + "/" + batchType; }
    }

    record InvalidQuantity(String reason) implements StockError {
        @Override public String code() { return "INVALID_QUANTITY"; }
        @Override public String message() { return "Invalid quantity: " + reason; }
    }

    record InvalidExpiryDate(String reason) implements StockError {
        @Override public String code() { return "INVALID_EXPIRY_DATE"; }
        @Override public String message() { return "Invalid expiry date: " + reason; }
    }

    record BatchNotFound(String id) implements StockError {
        @Override public String code() { return "BATCH_NOT_FOUND"; }
        @Override public String message() { return "Batch not found: " + id; }
    }

    record NegativeStockNotAllowed() implements StockError {
        @Override public String code() { return "NEGATIVE_STOCK_NOT_ALLOWED"; }
        @Override public String message() { return "Removal would result in negative stock"; }
    }

    record BatchNotAvailable(String id, String status) implements StockError {
        @Override public String code() { return "BATCH_NOT_AVAILABLE"; }
        @Override public String message() { return "Batch " + id + " is not available for removal (status: " + status + ")"; }
    }

    record BatchAlreadyBlocked(String id) implements StockError {
        @Override public String code() { return "BATCH_ALREADY_BLOCKED"; }
        @Override public String message() { return "Batch " + id + " is already blocked"; }
    }

    record BatchNotBlocked(String id) implements StockError {
        @Override public String code() { return "BATCH_NOT_BLOCKED"; }
        @Override public String message() { return "Batch " + id + " is not blocked"; }
    }

    record InsufficientStock(String available, String requested) implements StockError {
        @Override public String code() { return "INSUFFICIENT_STOCK"; }
        @Override public String message() { return "Insufficient stock: available " + available + ", requested " + requested; }
    }

    record InvalidReferenceType(String value) implements StockError {
        @Override public String code() { return "INVALID_REFERENCE_TYPE"; }
        @Override public String message() { return "Invalid reference type: " + value; }
    }

    record InvalidReferenceId(String reason) implements StockError {
        @Override public String code() { return "INVALID_REFERENCE_ID"; }
        @Override public String message() { return "Invalid reference ID: " + reason; }
    }

    record InvalidReservationPriority(String value) implements StockError {
        @Override public String code() { return "INVALID_RESERVATION_PRIORITY"; }
        @Override public String message() { return "Invalid reservation priority: " + value; }
    }

    record ReservationNotFound(String id) implements StockError {
        @Override public String code() { return "RESERVATION_NOT_FOUND"; }
        @Override public String message() { return "Reservation not found: " + id; }
    }

    record InvalidFilterCombination(String message) implements StockError {
        @Override public String code() { return "INVALID_FILTER_COMBINATION"; }
    }

    record Unauthorized(String message) implements StockError {
        @Override public String code() { return "UNAUTHORIZED"; }
    }

    record MovementCreationFailed(String message) implements StockError {
        @Override public String code() { return "MOVEMENT_CREATION_FAILED"; }
    }

    record RepositoryFailure(String message) implements StockError {
        @Override public String code() { return "REPOSITORY_ERROR"; }
    }
}
