<?php
/**
 * Conversion calculators.
 *
 * @package Logistica
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Keeps inventory calculation formulas in one place.
 */
class Logistica_Conversions {
	/**
	 * Option name for configurable formula notes.
	 */
	const FORMULA_OPTION = 'logistica_conversion_formula_settings';

	/**
	 * Returns the default conversion formula configuration.
	 *
	 * @return array
	 */
	public static function default_formula_settings() {
		return array(
			'bobina_peso_hoja'     => array(
				'label'   => __( 'Bobina a pliego: peso hoja', 'logistica' ),
				'formula' => '(vertical_cm / 100) * (horizontal_cm / 100) * (gramaje / 1000)',
				'notes'   => __( 'Calcula el peso de una hoja en kg.', 'logistica' ),
			),
			'bobina_kg'            => array(
				'label'   => __( 'Bobina a pliego: kg usados', 'logistica' ),
				'formula' => 'cantidad_pliegos * peso_hoja',
				'notes'   => __( 'Cuando se digitan pliegos, calcula los kilos usados.', 'logistica' ),
			),
			'bobina_pliegos'       => array(
				'label'   => __( 'Bobina a pliego: pliegos', 'logistica' ),
				'formula' => 'kg_usados / peso_hoja',
				'notes'   => __( 'Cuando se digitan kilos, calcula la cantidad de pliegos.', 'logistica' ),
			),
			'gramaje_papel'        => array(
				'label'   => __( 'Gramaje papel', 'logistica' ),
				'formula' => '(peso_gr * 10000) / area_cm2',
				'notes'   => __( 'Calcula gramaje por metro cuadrado.', 'logistica' ),
			),
			'montaje_pliegos'      => array(
				'label'   => __( 'Montaje compartido: pliegos montaje', 'logistica' ),
				'formula' => 'ceil(sum(pliegos_por_referencia) / referencias_usadas)',
				'notes'   => __( 'Promedia los pliegos requeridos entre las referencias usadas.', 'logistica' ),
			),
			'montaje_unidades'     => array(
				'label'   => __( 'Montaje compartido: unidades posibles', 'logistica' ),
				'formula' => 'pliegos_montaje * cabidas',
				'notes'   => __( 'Valida faltantes o sobrantes por referencia.', 'logistica' ),
			),
			'hojas_factor'         => array(
				'label'   => __( 'Hojas a hojas: factor conversión', 'logistica' ),
				'formula' => 'area_tamano_inicial / area_corte',
				'notes'   => __( 'Compara el tamaño inicial contra cada corte.', 'logistica' ),
			),
			'hojas_validacion'     => array(
				'label'   => __( 'Hojas a hojas: validación de área', 'logistica' ),
				'formula' => 'area_inicial - sum(area_cortes)',
				'notes'   => __( 'Indica si falta área por usar o si los cortes exceden el tamaño inicial.', 'logistica' ),
			),
			'calibre_material'     => array(
				'label'   => __( 'Calibre material: mm, pulgadas y milésimas', 'logistica' ),
				'formula' => 'pulgadas = mm / 25.4; milesimas = round(pulgadas * 1000); mm = (milesimas / 1000) * 25.4',
				'notes'   => __( 'Convierte calibre entre milímetros, pulgadas decimales y calibre comercial (ej. 20").', 'logistica' ),
			),
			'plastico_consumo'     => array(
				'label'   => __( 'Plástico: consumo por molde', 'logistica' ),
				'formula' => 'consumo_unidad_kg = peso_tamano / (und_molde * 1000); peso_total_kg = unidades * consumo_unidad_kg',
				'notes'   => __( 'Calcula kg por unidad y peso total a partir de unidades fabricadas, und x molde y peso tamaño (gr).', 'logistica' ),
			),
		);
	}

	/**
	 * Gets saved conversion formula settings merged with defaults.
	 *
	 * @return array
	 */
	public static function get_formula_settings() {
		$saved    = get_option( self::FORMULA_OPTION, array() );
		$defaults = self::default_formula_settings();

		if ( ! is_array( $saved ) ) {
			return $defaults;
		}

		foreach ( $defaults as $key => $formula ) {
			if ( isset( $saved[ $key ] ) && is_array( $saved[ $key ] ) ) {
				$defaults[ $key ]['formula'] = $saved[ $key ]['formula'] ?? $formula['formula'];
				$defaults[ $key ]['notes']   = $saved[ $key ]['notes'] ?? $formula['notes'];
			}
		}

		return $defaults;
	}

	/**
	 * Saves conversion formula settings.
	 *
	 * @param array $data Raw posted settings.
	 * @return void
	 */
	public static function save_formula_settings( $data ) {
		$defaults = self::default_formula_settings();
		$clean    = array();

		foreach ( $defaults as $key => $formula ) {
			$posted = isset( $data[ $key ] ) && is_array( $data[ $key ] ) ? $data[ $key ] : array();

			$clean[ $key ] = array(
				'formula' => sanitize_text_field( wp_unslash( $posted['formula'] ?? $formula['formula'] ) ),
				'notes'   => sanitize_textarea_field( wp_unslash( $posted['notes'] ?? $formula['notes'] ) ),
			);
		}

		update_option( self::FORMULA_OPTION, $clean );
	}

	/**
	 * Converts kilograms to sheets.
	 *
	 * @param float $kg Total kilograms.
	 * @param float $kg_per_sheet Weight per sheet.
	 * @return float
	 */
	public static function kg_to_hojas( $kg, $kg_per_sheet ) {
		return $kg_per_sheet > 0 ? floor( $kg / $kg_per_sheet ) : 0;
	}

	/**
	 * Converts sheets to kilograms.
	 *
	 * @param float $hojas Sheet count.
	 * @param float $kg_per_sheet Weight per sheet.
	 * @return float
	 */
	public static function hojas_to_kg( $hojas, $kg_per_sheet ) {
		return $hojas * $kg_per_sheet;
	}

	/**
	 * Calculates production consumption.
	 *
	 * @param float $unidades Units to produce.
	 * @param float $consumo_por_unidad Consumption per unit.
	 * @return float
	 */
	public static function consumo_produccion( $unidades, $consumo_por_unidad ) {
		return $unidades * $consumo_por_unidad;
	}

	/**
	 * Calculates boxes required for a number of units.
	 *
	 * @param int $unidades Units.
	 * @param int $unidades_por_caja Units per box.
	 * @return int
	 */
	public static function cajas_necesarias( $unidades, $unidades_por_caja ) {
		return $unidades_por_caja > 0 ? (int) ceil( $unidades / $unidades_por_caja ) : 0;
	}

	/**
	 * Calculates total units based on boxes and loose units.
	 *
	 * @param int $cajas Boxes.
	 * @param int $unidades_por_caja Units per box.
	 * @param int $saldos Loose units.
	 * @return int
	 */
	public static function unidades_totales( $cajas, $unidades_por_caja, $saldos ) {
		return ( $cajas * $unidades_por_caja ) + $saldos;
	}

	/**
	 * Calculates remaining raw material.
	 *
	 * @param float $disponible Available amount.
	 * @param float $usado Used amount.
	 * @return float
	 */
	public static function saldo_materia_prima( $disponible, $usado ) {
		return max( 0, $disponible - $usado );
	}
}
