package de.effigenix.domain.production;

public sealed interface BatchError {

    String code();
    String message();

    record BatchNotFound(BatchId id) implements BatchError {
        @Override public String code() { return "BATCH_NOT_FOUND"; }
        @Override public String message() { return "Batch with ID '" + id.value() + "' not found"; }
    }

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

    record InvalidDates(String reason) implements BatchError {
        @Override public String code() { return "BATCH_INVALID_DATES"; }
        @Override public String message() { return "Invalid dates: " + reason; }
    }

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

    record BatchNotFoundByNumber(BatchNumber batchNumber) implements BatchError {
        @Override public String code() { return "BATCH_NOT_FOUND_BY_NUMBER"; }
        @Override public String message() { return "Batch with number '" + batchNumber.value() + "' not found"; }
    }

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

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

    record NotInProduction(BatchId id) implements BatchError {
        @Override public String code() { return "BATCH_NOT_IN_PRODUCTION"; }
        @Override public String message() { return "Batch '" + id.value() + "' is not in IN_PRODUCTION status"; }
    }

    record DuplicateInputBatch(BatchId inputBatchId) implements BatchError {
        @Override public String code() { return "BATCH_DUPLICATE_INPUT_BATCH"; }
        @Override public String message() { return "Input batch '" + inputBatchId.value() + "' already recorded"; }
    }

    record InvalidConsumptionQuantity(String reason) implements BatchError {
        @Override public String code() { return "BATCH_INVALID_CONSUMPTION_QUANTITY"; }
        @Override public String message() { return "Invalid consumption quantity: " + reason; }
    }

    record MissingConsumptions(BatchId id) implements BatchError {
        @Override public String code() { return "BATCH_MISSING_CONSUMPTIONS"; }
        @Override public String message() { return "Batch '" + id.value() + "' requires at least one consumption before completion"; }
    }

    record InvalidActualQuantity(String reason) implements BatchError {
        @Override public String code() { return "BATCH_INVALID_ACTUAL_QUANTITY"; }
        @Override public String message() { return "Invalid actual quantity: " + reason; }
    }

    record InvalidWaste(String reason) implements BatchError {
        @Override public String code() { return "BATCH_INVALID_WASTE"; }
        @Override public String message() { return "Invalid waste: " + reason; }
    }

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

    record CancellationReasonRequired() implements BatchError {
        @Override public String code() { return "BATCH_CANCELLATION_REASON_REQUIRED"; }
        @Override public String message() { return "A cancellation reason is required"; }
    }

    record CancellationReasonTooLong(int maxLength) implements BatchError {
        @Override public String code() { return "BATCH_CANCELLATION_REASON_TOO_LONG"; }
        @Override public String message() { return "Cancellation reason must not exceed " + maxLength + " characters"; }
    }

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