// src/utils/unitConverter.ts
import type { UnitPrice } from '../types';

const METRIC_UNITS = ['g', 'kg', 'ml', 'l'];
const IMPERIAL_UNITS = ['oz', 'lb', 'fl oz'];

const CONVERSIONS: Record<string, { to: string; factor: number }> = {
    // metric to imperial
    g: { to: 'oz', factor: 0.035274 },
    kg: { to: 'lb', factor: 2.20462 },
    ml: { to: 'fl oz', factor: 0.033814 },
    l: { to: 'fl oz', factor: 33.814 },
    
    // imperial to metric
    oz: { to: 'g', factor: 28.3495 },
    lb: { to: 'kg', factor: 0.453592 },
    'fl oz': { to: 'ml', factor: 29.5735 },
};

interface FormattedPrice {
    price: string;
    unit: string | null;
}

/**
 * Converts a unit price to the target system and formats it for display.
 * @param unitPrice The structured unit price object from the database.
 * @param system The target system ('metric' or 'imperial').
 * @returns An object with formatted price and unit strings.
 */
export const formatUnitPrice = (unitPrice: UnitPrice | null | undefined, system: 'metric' | 'imperial'): FormattedPrice => {
    if (!unitPrice || typeof unitPrice.value !== 'number' || !unitPrice.unit) {
        return { price: '—', unit: null };
    }

    const { value, unit } = unitPrice;
    const isMetric = METRIC_UNITS.includes(unit);
    const isImperial = IMPERIAL_UNITS.includes(unit);

    let displayValue = value;
    let displayUnit = unit;

    if (system === 'imperial' && isMetric) {
        const conversion = CONVERSIONS[unit];
        if (conversion) {
            displayValue = value / conversion.factor; // Corrected: Divide price by factor
            displayUnit = conversion.to;
        }
    } else if (system === 'metric' && isImperial) {
        const conversion = CONVERSIONS[unit];
        if (conversion) {
            displayValue = value / conversion.factor; // Corrected: Divide price by factor
            displayUnit = conversion.to;
        }
    }

    // Convert the final calculated value (which is in cents) to dollars for formatting.
    const valueInDollars = displayValue / 100;

    // Smart formatting for price
    const formattedPrice = valueInDollars < 0.10
      ? valueInDollars.toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 3, maximumFractionDigits: 3 })
      : valueInDollars.toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2, maximumFractionDigits: 2 });
      
    // Always show a unit if one exists for clarity
    if (displayUnit === 'each') {
        return { price: formattedPrice, unit: '/each' };
    }
    
    return { price: formattedPrice, unit: `/${displayUnit}` };
};


/**
 * Converts an imperial unit price to its metric equivalent for database storage.
 * @param unitPrice The structured unit price object, potentially in imperial units.
 * @returns A unit price object with metric units, or the original if already metric or not applicable.
 */
export const convertToMetric = (unitPrice: UnitPrice | null | undefined): UnitPrice | null | undefined => {
    if (!unitPrice || typeof unitPrice.value !== 'number' || !unitPrice.unit) {
        return unitPrice;
    }

    const { value, unit } = unitPrice;
    const isImperial = IMPERIAL_UNITS.includes(unit);

    if (isImperial) {
        const conversion = CONVERSIONS[unit];
        if (conversion) {
            return {
                value: value * conversion.factor,
                unit: conversion.to,
            };
        }
    }
    
    // Return original if it's already metric or not a weight/volume unit (like 'each')
    return unitPrice;
};