"""
STEP to GLB Converter - Clean Version
Minimal, robust, with comprehensive logging
"""

import sys
import json
from pathlib import Path
from datetime import datetime

print("=" * 70)
print("STEP to GLB Converter - Starting...")
print("=" * 70)

# Import FreeCAD modules
try:
    print("Importing FreeCAD modules...")
    import FreeCAD
    import Import
    import Mesh
    print(f"✓ FreeCAD Version: {FreeCAD.Version()}")
except ImportError as e:
    print(f"✗ ERROR: FreeCAD modules not found: {e}")
    print("This script must be run with FreeCAD Python environment")
    sys.exit(1)

# ============================================================================
# CONFIGURATION
# ============================================================================
STEP_FILE = Path("D:\\__sistem__\\ProgramFiles\\FreeCAD\\bin\\freecad.stp")
OUTPUT_FILE = None  # None = auto (same name, same folder)

# Mesh settings
MESH_TOLERANCE = 0.05
EXPORT_EDGES = True
EXPORT_VERTICES = False

# Metadata options
INCLUDE_BOUNDING_BOX = True
INCLUDE_VOLUME = True
INCLUDE_HASH = True

# Colors
DEFAULT_COLOR = (0.8, 0.8, 0.8)
EDGE_COLOR = (0.1, 0.1, 0.1)

# ============================================================================

def safe_get_color(body, face_index):
    """Get color safely"""
    try:
        if hasattr(body, 'ViewObject') and hasattr(body.ViewObject, 'DiffuseColor'):
            colors = body.ViewObject.DiffuseColor
            if colors:
                return colors[face_index % len(colors)]
    except:
        pass
    return DEFAULT_COLOR


def safe_get_alpha(body):
    """Get transparency safely"""
    try:
        if hasattr(body, 'ViewObject'):
            trans = getattr(body.ViewObject, 'Transparency', 0)
            return 1.0 - (trans / 100.0)
    except:
        pass
    return 1.0


def create_face_mesh(face, body, body_idx, face_idx, body_label):
    """Create mesh from face"""
    try:
        print(f"    Tessellating face {face_idx}...")
        mesh = Mesh.Mesh(face.tessellate(MESH_TOLERANCE))
        
        if mesh.CountFacets == 0:
            print(f"    ✗ Face {face_idx}: No facets")
            return None
        
        print(f"    ✓ Face {face_idx}: {mesh.CountFacets} facets")
        
        # Apply colors
        color = safe_get_color(body, face_idx)
        alpha = safe_get_alpha(body)
        colors = [(color[0], color[1], color[2], alpha)] * len(mesh.Facets)
        mesh.VertexColors = colors
        
        # Set name
        mesh.Label = f"B{body_idx + 1}_F{face_idx}__{body_label}"
        
        # Metadata
        metadata = {
            "body_id": body_idx + 1,
            "face_id": face_idx,
            "body_label": body_label,
            "type": "Face",
            "area": round(face.Area, 6)
        }
        mesh.Label2 = json.dumps(metadata)
        
        return mesh
    except Exception as e:
        print(f"    ✗ Face {face_idx} failed: {e}")
        return None


def create_edge_mesh(edge, body, body_idx, face_idx, edge_idx, body_label):
    """Create mesh from edge"""
    try:
        mesh = Mesh.Mesh(edge.tessellate(MESH_TOLERANCE))
        
        if mesh.CountFacets == 0:
            return None
        
        # Apply edge color
        colors = [(EDGE_COLOR[0], EDGE_COLOR[1], EDGE_COLOR[2], 1.0)] * len(mesh.Facets)
        mesh.VertexColors = colors
        
        mesh.Label = f"B{body_idx + 1}_F{face_idx}_E{edge_idx}__{body_label}"
        
        metadata = {
            "body_id": body_idx + 1,
            "face_id": face_idx,
            "edge_id": edge_idx,
            "type": "Edge",
            "length": round(edge.Length, 6)
        }
        mesh.Label2 = json.dumps(metadata)
        
        return mesh
    except Exception as e:
        return None


def main():
    print("\n" + "=" * 70)
    print("Configuration:")
    print(f"  Input: {STEP_FILE}")
    print(f"  Exists: {STEP_FILE.exists()}")
    if STEP_FILE.exists():
        print(f"  Size: {STEP_FILE.stat().st_size} bytes")
    print(f"  Mesh Tolerance: {MESH_TOLERANCE}")
    print(f"  Export Edges: {EXPORT_EDGES}")
    print("=" * 70)
    
    # Validate input
    if not STEP_FILE.exists():
        print(f"\n✗ ERROR: File not found: {STEP_FILE}")
        return 1
    
    if STEP_FILE.suffix.lower() not in ['.stp', '.step']:
        print(f"\n✗ ERROR: Invalid file type: {STEP_FILE.suffix}")
        return 1
    
    # Determine output
    if OUTPUT_FILE:
        output_path = OUTPUT_FILE
    else:
        output_path = STEP_FILE.with_suffix('.glb')
    
    print(f"\nOutput: {output_path}")
    
    doc = None
    
    try:
        # Open STEP file
        print("\n" + "=" * 70)
        print("STEP 1: Opening STEP file...")
        print("=" * 70)
        
        Import.open(str(STEP_FILE))
        doc = FreeCAD.ActiveDocument
        
        if not doc:
            print("✗ Failed to open document")
            return 1
        
        print(f"✓ Document opened: {doc.Name}")
        print(f"✓ Total objects: {len(doc.Objects)}")
        
        # List all objects
        print("\nObjects in document:")
        for i, obj in enumerate(doc.Objects):
            has_shape = hasattr(obj, 'Shape') and obj.Shape
            shape_info = ""
            if has_shape:
                shape_info = f" - Faces: {len(obj.Shape.Faces)}, Edges: {len(obj.Shape.Edges)}"
            print(f"  [{i}] {obj.Label} (Type: {obj.TypeId}){shape_info}")
        
        # Process bodies
        print("\n" + "=" * 70)
        print("STEP 2: Processing bodies...")
        print("=" * 70)
        
        meshes = []
        stats = {"faces": 0, "edges": 0, "bodies": 0}
        
        for body_idx, body in enumerate(doc.Objects):
            if not hasattr(body, 'Shape') or not body.Shape:
                print(f"Skipping {body.Label} - no Shape")
                continue
            
            body_label = getattr(body, 'Label', f'Body{body_idx}')
            face_count = len(body.Shape.Faces)
            
            print(f"\nBody {body_idx}: {body_label}")
            print(f"  Faces: {face_count}")
            
            if face_count == 0:
                print("  ✗ No faces to process")
                continue
            
            stats["bodies"] += 1
            
            # Process faces
            for face_idx, face in enumerate(body.Shape.Faces):
                face_mesh = create_face_mesh(face, body, body_idx, face_idx, body_label)
                if face_mesh:
                    meshes.append(face_mesh)
                    stats["faces"] += 1
                
                # Process edges
                if EXPORT_EDGES:
                    for edge_idx, edge in enumerate(face.Edges):
                        edge_mesh = create_edge_mesh(edge, body, body_idx, face_idx, edge_idx, body_label)
                        if edge_mesh:
                            meshes.append(edge_mesh)
                            stats["edges"] += 1
            
            print(f"  ✓ Created {stats['faces']} face meshes")
        
        # Check results
        print("\n" + "=" * 70)
        print("STEP 3: Export")
        print("=" * 70)
        print(f"Total meshes to export: {len(meshes)}")
        print(f"  Bodies: {stats['bodies']}")
        print(f"  Faces: {stats['faces']}")
        print(f"  Edges: {stats['edges']}")
        
        if len(meshes) == 0:
            print("\n✗ ERROR: No meshes created!")
            print("\nPossible reasons:")
            print("  1. STEP file contains no solid geometry")
            print("  2. Tessellation failed (try increasing MESH_TOLERANCE)")
            print("  3. File is corrupted")
            return 1
        
        # Create metadata mesh
        try:
            meta = Mesh.Mesh()
            meta.Label = "__METADATA__"
            meta.Label2 = json.dumps({
                "source": STEP_FILE.name,
                "date": datetime.now().isoformat(),
                "stats": stats
            })
            meshes.insert(0, meta)
            print("✓ Metadata mesh created")
        except:
            print("⚠ Could not create metadata mesh")
        
        # Export
        print(f"\nExporting to: {output_path}")
        Import.export(meshes, str(output_path))
        
        # Verify
        if not output_path.exists():
            print("✗ ERROR: Output file was not created!")
            return 1
        
        size_kb = output_path.stat().st_size / 1024
        print(f"✓ File created: {size_kb:.2f} KB")
        
        print("\n" + "=" * 70)
        print("✓ SUCCESS!")
        print("=" * 70)
        
        return 0
        
    except Exception as e:
        print(f"\n✗ FATAL ERROR: {e}")
        import traceback
        traceback.print_exc()
        return 1
        
    finally:
        if doc:
            try:
                print("\nClosing document...")
                FreeCAD.closeDocument(doc.Name)
                print("✓ Document closed")
            except Exception as e:
                print(f"⚠ Could not close document: {e}")


if __name__ == "__main__":
    try:
        exit_code = main()
        print(f"\nExit code: {exit_code}")
        sys.exit(exit_code)
    except KeyboardInterrupt:
        print("\n\n✗ Interrupted by user")
        sys.exit(1)
    except Exception as e:
        print(f"\n✗ Unexpected error: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)