<?php
class Unit { 
  private $pdo; 
  
  public function __construct(){ 
    $this->pdo=$GLOBALS['pdo']; 
  }
  
  // Default: product-capable units
  public function all(){ return $this->pdo->query("SELECT * FROM units WHERE is_active=1 AND (scope='product' OR scope='both') ORDER BY sort_order ASC, name ASC")->fetchAll(); }
  public function allIngredient(){ return $this->pdo->query("SELECT * FROM units WHERE is_active=1 AND (scope='ingredient' OR scope='both') ORDER BY sort_order ASC, name ASC")->fetchAll(); }
  public function allProduct(){ return $this->pdo->query("SELECT * FROM units WHERE is_active=1 AND (scope='product' OR scope='both') ORDER BY sort_order ASC, name ASC")->fetchAll(); }
  public function allWithInactive(){ return $this->pdo->query("SELECT * FROM units ORDER BY sort_order ASC, name ASC")->fetchAll(); }
  public function find($id){ $st=$this->pdo->prepare("SELECT * FROM units WHERE id=?"); $st->execute([$id]); return $st->fetch(); }
  public function create($d){ $st=$this->pdo->prepare("INSERT INTO units (code,name,scope,sort_order,is_active,base_unit,conversion_factor) VALUES (?,?,?,?,?,?,?)"); return $st->execute([$d['code'],$d['name'],$d['scope']??'product',$d['sort_order']??0,$d['is_active']??1,$d['base_unit']??null,$d['conversion_factor']??null]); }
  public function update($id,$d){ $st=$this->pdo->prepare("UPDATE units SET code=?, name=?, scope=?, sort_order=?, is_active=?, base_unit=?, conversion_factor=? WHERE id=?"); return $st->execute([$d['code'],$d['name'],$d['scope']??'product',$d['sort_order']??0,$d['is_active']??1,$d['base_unit']??null,$d['conversion_factor']??null,$id]); }
  public function delete($id){ $st=$this->pdo->prepare("DELETE FROM units WHERE id=?"); return $st->execute([$id]); }
  
  /**
   * Get all units with their conversion relationships
   */
  public function getAllWithConversions() {
    return $this->pdo->query("
      SELECT u.*, bu.code as base_unit_code, bu.name as base_unit_name 
      FROM units u 
      LEFT JOIN units bu ON u.base_unit = bu.id 
      WHERE u.is_active=1 
      ORDER BY u.sort_order ASC, u.name ASC
    ")->fetchAll();
  }
  
  /**
   * Convert value from one unit to another
   * @param float $value - The value to convert
   * @param string $fromUnit - Source unit code (e.g., 'g')
   * @param string $toUnit - Target unit code (e.g., 'kg')
   * @return float|null - Converted value or null if conversion not possible
   */
  public function convert($value, $fromUnit, $toUnit) {
    if ($fromUnit === $toUnit) return $value;
    
    // Hardcoded common conversions (fallback if DB not configured)
    $commonConversions = [
      'g->kg' => 0.001,
      'kg->g' => 1000,
      'mg->g' => 0.001,
      'g->mg' => 1000,
      'ml->l' => 0.001,
      'l->ml' => 1000,
    ];
    
    $key = $fromUnit . '->' . $toUnit;
    if (isset($commonConversions[$key])) {
      return $value * $commonConversions[$key];
    }
    
    // Get unit details from database
    $from = $this->pdo->prepare("SELECT * FROM units WHERE code=?");
    $from->execute([$fromUnit]);
    $fromData = $from->fetch();
    
    $to = $this->pdo->prepare("SELECT * FROM units WHERE code=?");
    $to->execute([$toUnit]);
    $toData = $to->fetch();
    
    if (!$fromData || !$toData) return null;
    
    // Convert to base unit first
    $baseValue = $value;
    if ($fromData['base_unit'] && $fromData['conversion_factor']) {
      $baseValue = $value * $fromData['conversion_factor'];
    }
    
    // Convert from base unit to target
    $result = $baseValue;
    if ($toData['base_unit'] && $toData['conversion_factor']) {
      $result = $baseValue / $toData['conversion_factor'];
    }
    
    return $result;
  }
  
  /**
   * Format value with best suitable unit (auto-convert large values)
   * @param float $value - The value
   * @param string $unit - Current unit code
   * @param array $options - Options: decimals, locale, forceUnit
   * @return array - ['value' => formatted_value, 'unit' => unit_code, 'display' => 'value unit']
   */
  public function formatWithBestUnit($value, $unit, $options = []) {
    $decimals = $options['decimals'] ?? 2;
    $forceUnit = $options['forceUnit'] ?? null;
    
    if ($forceUnit) {
      $converted = $this->convert($value, $unit, $forceUnit);
      if ($converted !== null) {
        return [
          'value' => round($converted, $decimals),
          'unit' => $forceUnit,
          'display' => number_format($converted, $decimals, ',', ' ') . ' ' . $forceUnit
        ];
      }
    }
    
    // Get unit with conversions
    $unitData = $this->pdo->prepare("SELECT u.*, bu.code as base_code FROM units u LEFT JOIN units bu ON u.base_unit = bu.id WHERE u.code=?");
    $unitData->execute([$unit]);
    $current = $unitData->fetch();
    
    if (!$current || !$current['base_unit']) {
      // No conversion available, return as-is
      return [
        'value' => round($value, $decimals),
        'unit' => $unit,
        'display' => number_format($value, $decimals, ',', ' ') . ' ' . $unit
      ];
    }
    
    // Auto-convert if value is large
    $baseCode = $current['base_code'];
    
    // g -> kg if >= 1000
    if ($unit === 'g' && $value >= 1000) {
      $converted = $this->convert($value, 'g', 'kg');
      return [
        'value' => round($converted, $decimals),
        'unit' => 'kg',
        'display' => number_format($converted, $decimals, ',', ' ') . ' kg'
      ];
    }
    
    // ml -> l if >= 1000
    if ($unit === 'ml' && $value >= 1000) {
      $converted = $this->convert($value, 'ml', 'l');
      return [
        'value' => round($converted, $decimals),
        'unit' => 'l',
        'display' => number_format($converted, $decimals, ',', ' ') . ' l'
      ];
    }
    
    // mg -> g if >= 1000
    if ($unit === 'mg' && $value >= 1000) {
      $converted = $this->convert($value, 'mg', 'g');
      return [
        'value' => round($converted, $decimals),
        'unit' => 'g',
        'display' => number_format($converted, $decimals, ',', ' ') . ' g'
      ];
    }
    
    // Return original
    return [
      'value' => round($value, $decimals),
      'unit' => $unit,
      'display' => number_format($value, $decimals, ',', ' ') . ' ' . $unit
    ];
  }
}

