import subprocess
import os
import re
import logging
import shutil
from config import SLICER_PATH, SLICER_CONFIG

logger = logging.getLogger(__name__)

def slice_model(file_path: str):
    """
    Runs PrusaSlicer CLI to extract the EXACT 3D volume of the STL/OBJ file using --info.
    Returns a dict with estimated print_time (str) and filament_used (g).
    """
    if not shutil.which(SLICER_PATH):
        logger.error(f"Slicer not found at {SLICER_PATH}")
        return None
    
    cmd = [
        SLICER_PATH,
        "--info",
        file_path
    ]

    try:
        # Run info extraction (very fast, no full G-code generation)
        process = subprocess.run(cmd, capture_output=True, text=True, check=True)
        content = process.stdout
        
        # Regex to find volume and sizes
        volume_match = re.search(r"volume\s*=\s*([\d\.]+)", content)
        size_x_match = re.search(r"size_x\s*=\s*([\d\.]+)", content)
        size_y_match = re.search(r"size_y\s*=\s*([\d\.]+)", content)
        size_z_match = re.search(r"size_z\s*=\s*([\d\.]+)", content)

        if not volume_match:
            logger.error("Volume could not be parsed from PrusaSlicer output.")
            return None
            
        volume_mm3 = float(volume_match.group(1))
        volume_cm3 = volume_mm3 / 1000.0
        
        dimensions_str = ""
        if size_x_match and size_y_match and size_z_match:
            x = round(float(size_x_match.group(1)), 1)
            y = round(float(size_y_match.group(1)), 1)
            z = round(float(size_z_match.group(1)), 1)
            dimensions_str = f"{x} x {y} x {z} mm"

        # Estimate weight assuming average density of PLA/PETG (~1.25 g/cm3)
        filament_g = round(volume_cm3 * 1.25, 2)
        
        # Estimate printing time assuming average volumetric flow rate of ~10 mm3/s
        time_seconds = int(volume_mm3 / 10.0)
        
        hours = time_seconds // 3600
        minutes = (time_seconds % 3600) // 60
        
        if hours > 0:
            time_str = f"{hours}h {minutes}m"
        else:
            time_str = f"{minutes}m"
            
        return {
            "filament_g": filament_g,
            "print_time_str": time_str,
            "dimensions": dimensions_str,
            "success": True
        }
        
    except subprocess.CalledProcessError as e:
        logger.error(f"Slicing info error: {e.stderr}")
        return None
    except Exception as e:
        logger.error(f"General error in slice_model: {e}")
        return None
