import modal

# ──────────────────────────────────────────────────────────
#  1) AWS S3
# ──────────────────────────────────────────────────────────

aws_secret = modal.Secret.from_name("aws-bucket")
UPLOADS_S3_BUCKET = "suno-data-uploads"

# ──────────────────────────────────────────────────────────
#  2) Model App Setup
# ──────────────────────────────────────────────────────────

app = modal.App("suno-shader-base-assets")

# This name is the one you will see as the folder on Modal under
VOLUME_NAME = "shader-outputs"

outputs = modal.Volume.from_name(VOLUME_NAME, create_if_missing=True)
OUTPUTS_PATH = "/outputs"

image = (
    modal.Image.from_registry("ghcr.io/selkies-project/nvidia-egl-desktop:latest", add_python="3.11")
    .apt_install(
        "ffmpeg",
        "fontconfig",
    )
    .run_commands(
        [
            "fc-cache -f -v",
        ]
    )
    # Install moderngl with headless support and ensure dependencies are installed
    .pip_install(
        "moderngl[headless]==5.8.2",  # Specify version to ensure compatibility
        "skia-python==87.7",
        "requests",
        "tqdm",
        "numpy>=1.20.0",  # Ensure numpy is installed for arrays
        "pydub",  # For audio processing
        "scipy",  # For FFT and other signal processing
        "Pillow",
        "boto3",
    )
    .entrypoint([])
)

# ──────────────────────────────────────────────────────────
#  3) Ephemeral App Endpoints
# ──────────────────────────────────────────────────────────


@app.function(image=image, volumes={OUTPUTS_PATH: outputs}, timeout=600)
@modal.fastapi_endpoint(method="POST")
def upload_to_volume_resources(item: dict):
    import os
    import urllib.request

    resource_url = item["resource_url"]
    resource_filename = item["filename"]
    resource_subdir_path = item["resource_subdir_path"]

    resource_dir = os.path.join(OUTPUTS_PATH, "resources")
    if resource_subdir_path != None:
        resource_dir = os.path.join(resource_dir, resource_subdir_path)

    os.makedirs(resource_dir, exist_ok=True)
    file_path = os.path.join(resource_dir, resource_filename)

    try:
        filename = os.path.basename(resource_url)
        urllib.request.urlretrieve(resource_url, file_path)
    except Exception as e:
        print(f"Error downloading resource file: {e}")
        raise


@app.function(image=image, volumes={OUTPUTS_PATH: outputs}, secrets=[aws_secret])
@modal.fastapi_endpoint(method="POST")
def upload_to_s3_resources(item: dict):
    import os
    import uuid
    import urllib.request
    import boto3

    # Example config references (replace with your own logic/variables)
    resource_url = item["resource_url"]  # The HTTP(s) URL of the file to download
    resource_keypath = item["resource_keypath"]  # S3 key sub-path

    # Create a temp filename locally
    temp_uuid_str = str(uuid.uuid4())
    temp_path = f"/tmp/temp_{temp_uuid_str}"  # local path inside the container

    # Prepare S3 upload path
    s3_key = f"shader_output/resources/{resource_keypath}"

    try:
        filename = os.path.basename(resource_url)
        urllib.request.urlretrieve(resource_url, temp_path)
    except Exception as e:
        print(f"Error downloading resource file: {e}")
        raise

    # 2) Upload the file to S3
    try:
        s3 = boto3.client("s3")
        with open(temp_path, "rb") as f:
            s3.upload_fileobj(
                Fileobj=f,
                Bucket=UPLOADS_S3_BUCKET,
                Key=s3_key,
            )

        # 3) Create a presigned URL
        presigned_url = s3.generate_presigned_url(
            ClientMethod="get_object",
            Params={"Bucket": UPLOADS_S3_BUCKET, "Key": s3_key},
            ExpiresIn=3600,  # 1 hour
        )

        print(f"Presigned URL: {presigned_url}")
        return {"presigned_url": presigned_url}

    except Exception as e:
        print(f"Failed to upload file to S3: {e}")
        return {"presigned_url": ""}
