package de.effigenix.domain.inventory;

public sealed interface InventoryCountError {

    String code();
    String message();

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

    record InvalidCountDate(String reason) implements InventoryCountError {
        @Override public String code() { return "INVALID_COUNT_DATE"; }
        @Override public String message() { return "Invalid count date: " + reason; }
    }

    record CountDateInFuture(String date) implements InventoryCountError {
        @Override public String code() { return "COUNT_DATE_IN_FUTURE"; }
        @Override public String message() { return "Count date must not be in the future: " + date; }
    }

    record InvalidInitiatedBy(String reason) implements InventoryCountError {
        @Override public String code() { return "INVALID_INITIATED_BY"; }
        @Override public String message() { return "Invalid initiatedBy: " + reason; }
    }

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

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

    record DuplicateArticle(String articleId) implements InventoryCountError {
        @Override public String code() { return "DUPLICATE_ARTICLE"; }
        @Override public String message() { return "Article already exists in count: " + articleId; }
    }

    record InvalidStatusTransition(String from, String to) implements InventoryCountError {
        @Override public String code() { return "INVALID_STATUS_TRANSITION"; }
        @Override public String message() { return "Cannot transition from " + from + " to " + to; }
    }

    record NoCountItems() implements InventoryCountError {
        @Override public String code() { return "NO_COUNT_ITEMS"; }
        @Override public String message() { return "Inventory count has no count items"; }
    }

    record IncompleteCountItems() implements InventoryCountError {
        @Override public String code() { return "INCOMPLETE_COUNT_ITEMS"; }
        @Override public String message() { return "Not all count items have been counted"; }
    }

    record InvalidCountItemId(String reason) implements InventoryCountError {
        @Override public String code() { return "INVALID_COUNT_ITEM_ID"; }
        @Override public String message() { return "Invalid count item ID: " + reason; }
    }

    record CountItemNotFound(String id) implements InventoryCountError {
        @Override public String code() { return "COUNT_ITEM_NOT_FOUND"; }
        @Override public String message() { return "Count item not found: " + id; }
    }

    record SamePersonViolation() implements InventoryCountError {
        @Override public String code() { return "SAME_PERSON_VIOLATION"; }
        @Override public String message() { return "Counter must not be the same person who initiated the count"; }
    }

    record InvalidInventoryCountId(String reason) implements InventoryCountError {
        @Override public String code() { return "INVALID_INVENTORY_COUNT_ID"; }
        @Override public String message() { return "Invalid inventory count ID: " + reason; }
    }

    record InventoryCountNotFound(String id) implements InventoryCountError {
        @Override public String code() { return "INVENTORY_COUNT_NOT_FOUND"; }
        @Override public String message() { return "Inventory count not found: " + id; }
    }

    record ActiveCountExists(String storageLocationId) implements InventoryCountError {
        @Override public String code() { return "ACTIVE_COUNT_EXISTS"; }
        @Override public String message() { return "An active inventory count already exists for storage location: " + storageLocationId; }
    }

    record StockNotFoundForArticle(String articleId) implements InventoryCountError {
        @Override public String code() { return "STOCK_NOT_FOUND_FOR_ARTICLE"; }
        @Override public String message() { return "No stock found for article: " + articleId; }
    }

    record CancellationReasonRequired() implements InventoryCountError {
        @Override public String code() { return "CANCELLATION_REASON_REQUIRED"; }
        @Override public String message() { return "Cancellation reason is required"; }
    }

    record InvalidStatus(String status) implements InventoryCountError {
        @Override public String code() { return "INVALID_STATUS"; }
        @Override public String message() { return "Invalid status: " + status; }
    }

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

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