import requests
import zipfile
import tempfile
import xml.etree.ElementTree as ET

def getFilamentsUsageFrom3mf(url):
  """
  Download a 3MF file from a URL, unzip it, and parse filament usage.

  Args:
      url (str): URL to the 3MF file.

  Returns:
      list[dict]: List of dictionaries with `tray_info_idx` and `used_g`.
  """
  try:
    # Create a temporary file
    with tempfile.NamedTemporaryFile(delete=False, suffix=".3mf") as temp_file:
      temp_file_name = temp_file.name
      print("Downloading 3MF file...")

      # Download the file and save it to the temporary file
      response = requests.get(url)
      response.raise_for_status()
      temp_file.write(response.content)
      print(f"3MF file downloaded and saved as {temp_file_name}.")

    # Unzip the 3MF file
    with zipfile.ZipFile(temp_file_name, 'r') as z:
      # Check for the Metadata/slice_info.config file
      slice_info_path = "Metadata/slice_info.config"
      if slice_info_path in z.namelist():
        with z.open(slice_info_path) as slice_info_file:
          # Parse the XML content of the file
          tree = ET.parse(slice_info_file)
          root = tree.getroot()

          # Extract id and used_g from each filament
          result = []
          for plate in root.findall(".//plate"):
            for filament in plate.findall(".//filament"):
              used_g = filament.attrib.get("used_g")
              if used_g:
                result.append(used_g)
              else:
                result.append('0.0')
          return result
      else:
        print(f"File '{slice_info_path}' not found in the archive.")
        return []
  except requests.exceptions.RequestException as e:
    print(f"Error downloading file: {e}")
    return []
  except zipfile.BadZipFile:
    print("The downloaded file is not a valid 3MF archive.")
    return []
  except ET.ParseError:
    print("Error parsing the XML file.")
    return []
  except Exception as e:
    print(f"An unexpected error occurred: {e}")
    return []
  finally:
    # Cleanup: Delete the temporary file
    try:
      import os
      if os.path.exists(temp_file_name):
        os.remove(temp_file_name)
    except Exception as cleanup_error:
      print(f"Error during cleanup: {cleanup_error}")
