package de.avatic.lcc.model.db.utils;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Represents the supported units of weight measurement in the system.
 * This enum is utilized to specify the weight unit for various entities
 * such as packaging and related operations.
 * <p>
 * The supported weight units are:
 * - T: Tons
 * - KG: Kilograms
 * - G: Grams
 */
public enum WeightUnit {
    T("t", 1000000.0),
    KG("kg", 1000.0),
    G("g", 1.0);

    private final String displayedName;
    private final double baseFactor;

    WeightUnit(String displayedName, double baseFactor) {
        this.displayedName = displayedName;
        this.baseFactor = baseFactor;
    }

    /**
     * Custom deserializer that handles case-insensitive matching
     */
    @JsonCreator
    public static WeightUnit fromString(String value) {
        if (value == null) {
            return null;
        }

        for (WeightUnit unit : WeightUnit.values()) {
            if (unit.displayedName.equalsIgnoreCase(value)) {
                return unit;
            }
        }

        throw new IllegalArgumentException("Unknown WeightUnit: " + value +
                ". Valid values are: t, kg, g (case insensitive)");
    }

    @JsonValue
    public String getDisplayedName() {
        return displayedName;
    }

    /**
     * Converts a value from one weight unit to this unit.
     *
     * @param value    the value to convert
     * @param fromUnit the source unit
     * @return the converted value
     * @throws IllegalArgumentException if value or fromUnit is null
     */
    public BigDecimal convertFrom(Number value, WeightUnit fromUnit) {
        if (value == null || fromUnit == null) {
            throw new IllegalArgumentException("Value and fromUnit must not be null");
        }

        // Convert to base unit (grams)
        BigDecimal valueInBaseUnit = BigDecimal.valueOf(value.doubleValue()).multiply(BigDecimal.valueOf(fromUnit.baseFactor));


        // Convert from base unit to target unit
        return valueInBaseUnit.divide(BigDecimal.valueOf(this.baseFactor), 8, RoundingMode.HALF_UP);
    }

    public Double convertFromG(Number value) {
        var converted = convertFrom(value, G);
        return converted.doubleValue();
    }

    public Integer convertToG(Double weight) {
        var converted = WeightUnit.G.convertFrom(weight, this);
        return converted.intValue();


    }
}