package de.effigenix.infrastructure.production.persistence.entity;

import jakarta.persistence.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "batches")
public class BatchEntity {

    @Id
    @Column(name = "id", nullable = false, length = 36)
    private String id;

    @Version
    @Column(name = "version", nullable = false)
    private Long version;

    @Column(name = "batch_number", nullable = false, unique = true, length = 20)
    private String batchNumber;

    @Column(name = "recipe_id", nullable = false, length = 36)
    private String recipeId;

    @Column(name = "status", nullable = false, length = 20)
    private String status;

    @Column(name = "planned_quantity_amount", nullable = false, precision = 19, scale = 6)
    private BigDecimal plannedQuantityAmount;

    @Column(name = "planned_quantity_unit", nullable = false, length = 10)
    private String plannedQuantityUnit;

    @Column(name = "production_date", nullable = false)
    private LocalDate productionDate;

    @Column(name = "best_before_date", nullable = false)
    private LocalDate bestBeforeDate;

    @Column(name = "actual_quantity_amount", precision = 19, scale = 6)
    private BigDecimal actualQuantityAmount;

    @Column(name = "actual_quantity_unit", length = 10)
    private String actualQuantityUnit;

    @Column(name = "waste_amount", precision = 19, scale = 6)
    private BigDecimal wasteAmount;

    @Column(name = "waste_unit", length = 10)
    private String wasteUnit;

    @Column(name = "remarks", length = 500)
    private String remarks;

    @Column(name = "created_at", nullable = false, updatable = false)
    private OffsetDateTime createdAt;

    @Column(name = "updated_at", nullable = false)
    private OffsetDateTime updatedAt;

    @Column(name = "completed_at")
    private OffsetDateTime completedAt;

    @Column(name = "cancellation_reason", length = 500)
    private String cancellationReason;

    @Column(name = "cancelled_at")
    private OffsetDateTime cancelledAt;

    @OneToMany(mappedBy = "batch", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private List<ConsumptionEntity> consumptions = new ArrayList<>();

    protected BatchEntity() {}

    public BatchEntity(
            String id,
            String batchNumber,
            String recipeId,
            String status,
            BigDecimal plannedQuantityAmount,
            String plannedQuantityUnit,
            LocalDate productionDate,
            LocalDate bestBeforeDate,
            OffsetDateTime createdAt,
            OffsetDateTime updatedAt
    ) {
        this.id = id;
        this.batchNumber = batchNumber;
        this.recipeId = recipeId;
        this.status = status;
        this.plannedQuantityAmount = plannedQuantityAmount;
        this.plannedQuantityUnit = plannedQuantityUnit;
        this.productionDate = productionDate;
        this.bestBeforeDate = bestBeforeDate;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
    }

    public String getId() { return id; }
    public Long getVersion() { return version; }
    public String getBatchNumber() { return batchNumber; }
    public String getRecipeId() { return recipeId; }
    public String getStatus() { return status; }
    public BigDecimal getPlannedQuantityAmount() { return plannedQuantityAmount; }
    public String getPlannedQuantityUnit() { return plannedQuantityUnit; }
    public LocalDate getProductionDate() { return productionDate; }
    public LocalDate getBestBeforeDate() { return bestBeforeDate; }
    public OffsetDateTime getCreatedAt() { return createdAt; }
    public OffsetDateTime getUpdatedAt() { return updatedAt; }
    public List<ConsumptionEntity> getConsumptions() { return consumptions; }

    public BigDecimal getActualQuantityAmount() { return actualQuantityAmount; }
    public String getActualQuantityUnit() { return actualQuantityUnit; }
    public BigDecimal getWasteAmount() { return wasteAmount; }
    public String getWasteUnit() { return wasteUnit; }
    public String getRemarks() { return remarks; }
    public OffsetDateTime getCompletedAt() { return completedAt; }
    public String getCancellationReason() { return cancellationReason; }
    public OffsetDateTime getCancelledAt() { return cancelledAt; }

    public void setStatus(String status) { this.status = status; }
    public void setUpdatedAt(OffsetDateTime updatedAt) { this.updatedAt = updatedAt; }
    public void setActualQuantityAmount(BigDecimal actualQuantityAmount) { this.actualQuantityAmount = actualQuantityAmount; }
    public void setActualQuantityUnit(String actualQuantityUnit) { this.actualQuantityUnit = actualQuantityUnit; }
    public void setWasteAmount(BigDecimal wasteAmount) { this.wasteAmount = wasteAmount; }
    public void setWasteUnit(String wasteUnit) { this.wasteUnit = wasteUnit; }
    public void setRemarks(String remarks) { this.remarks = remarks; }
    public void setCompletedAt(OffsetDateTime completedAt) { this.completedAt = completedAt; }
    public void setCancellationReason(String cancellationReason) { this.cancellationReason = cancellationReason; }
    public void setCancelledAt(OffsetDateTime cancelledAt) { this.cancelledAt = cancelledAt; }
}
