package de.effigenix.domain.production;

public sealed interface ProductionOrderError {

    String code();
    String message();

    record ProductionOrderNotFound(ProductionOrderId id) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_NOT_FOUND"; }
        @Override public String message() { return "Production order with ID '" + id.value() + "' not found"; }
    }

    record InvalidPlannedQuantity(String reason) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_INVALID_PLANNED_QUANTITY"; }
        @Override public String message() { return "Invalid planned quantity: " + reason; }
    }

    record PlannedDateInPast(java.time.LocalDate date) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_PLANNED_DATE_IN_PAST"; }
        @Override public String message() { return "Planned date " + date + " is in the past"; }
    }

    record InvalidPriority(String value) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_INVALID_PRIORITY"; }
        @Override public String message() { return "Invalid priority: " + value; }
    }

    record RecipeNotActive(RecipeId recipeId) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_RECIPE_NOT_ACTIVE"; }
        @Override public String message() { return "Recipe '" + recipeId.value() + "' is not in ACTIVE status"; }
    }

    record RecipeNotFound(RecipeId recipeId) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_RECIPE_NOT_FOUND"; }
        @Override public String message() { return "Recipe '" + recipeId.value() + "' not found"; }
    }

    record InvalidStatusTransition(ProductionOrderStatus current, ProductionOrderStatus target) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_INVALID_STATUS_TRANSITION"; }
        @Override public String message() { return "Cannot transition from " + current + " to " + target; }
    }

    record BatchAlreadyAssigned(BatchId batchId) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_BATCH_ALREADY_ASSIGNED"; }
        @Override public String message() { return "Production order already has batch '" + batchId.value() + "' assigned"; }
    }

    record BatchNotCompleted(BatchId batchId) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_BATCH_NOT_COMPLETED"; }
        @Override public String message() { return "Batch '" + batchId.value() + "' is not in COMPLETED status"; }
    }

    record RescheduleNotAllowed(ProductionOrderStatus current) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_RESCHEDULE_NOT_ALLOWED"; }
        @Override public String message() { return "Cannot reschedule production order in status " + current; }
    }

    record BatchCreationFailed(String batchErrorCode, String message) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_BATCH_CREATION_FAILED"; }
    }

    record ValidationFailure(String message) implements ProductionOrderError {
        @Override public String code() { return "PRODUCTION_ORDER_VALIDATION_ERROR"; }
    }

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

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