from fastapi import FastAPI, Response, Request
from fastapi.staticfiles import StaticFiles
import os

app = FastAPI()

# Serve static files (HTML)
app.mount("/static", StaticFiles(directory="static"), name="static")


@app.get("/")
async def serve_html():
    with open("static/index.html", "r") as f:
        html_content = f.read()
    return Response(content=html_content, media_type="text/html")


@app.get("/audio.webm")
async def get_webm_file(request: Request):
    # Read the file size
    file_size = os.path.getsize("static/audio.webm")

    # Define max bytes to return in a single request
    # max_bytes = 1048576  # 1MB chunks
    # max_bytes = 2213122
    max_bytes = 256 * 1024

    # Set default range
    start = 0
    end = min(max_bytes - 1, file_size - 1)

    # Check for Range header
    range_header = request.headers.get("Range", "")
    if range_header.startswith("bytes="):
        range_str = range_header.split("=")[1]
        ranges = range_str.split("-")

        if ranges[0]:
            start = int(ranges[0])

        if len(ranges) > 1 and ranges[1]:
            requested_end = int(ranges[1])
            # Limit the end to max_bytes from start
            end = min(start + max_bytes - 1, requested_end, file_size - 1)
        else:
            end = min(start + max_bytes - 1, file_size - 1)

    # Calculate content length
    content_length = end - start + 1

    # Create headers
    headers = {
        # "Content-Disposition": "attachment; filename=audio.opus",
        "Content-Type": "audio/webm; codecs=opus",
        "Content-Length": str(content_length),
        "Content-Range": f"bytes {start}-{end}/{file_size}",
        "Accept-Ranges": "bytes",
        # "X-Content-Duration": "201.0",
        "X-Custom-Header": "Custom Value",
    }

    # Read the requested portion of the file
    with open("static/audio.webm", "rb") as f:
        f.seek(start)
        file_content = f.read(content_length)

    # Return partial content with 206 status code
    return Response(
        content=file_content, status_code=206, media_type="audio/webm", headers=headers
    )


@app.get("/audio.opus")
async def get_opus_file(request: Request):
    # Read the file size
    file_size = os.path.getsize("static/audio.opus")

    # Define max bytes to return in a single request
    # max_bytes = 1048576  # 1MB chunks
    # max_bytes = 2213122
    max_bytes = 256 * 1024

    # Set default range
    start = 0
    end = min(max_bytes - 1, file_size - 1)

    # Check for Range header
    range_header = request.headers.get("Range", "")
    if range_header.startswith("bytes="):
        range_str = range_header.split("=")[1]
        ranges = range_str.split("-")

        if ranges[0]:
            start = int(ranges[0])

        if len(ranges) > 1 and ranges[1]:
            requested_end = int(ranges[1])
            # Limit the end to max_bytes from start
            end = min(start + max_bytes - 1, requested_end, file_size - 1)
        else:
            end = min(start + max_bytes - 1, file_size - 1)

    # Calculate content length
    content_length = end - start + 1

    # Create headers
    headers = {
        # "Content-Disposition": "attachment; filename=audio.opus",
        "Content-Type": "audio/ogg; codecs=opus",
        # "Content-Length": str(content_length),
        # "Content-Range": f"bytes {start}-{end}",
        "Content-Range": f"bytes {start}-{end}/*",
        "Transfer-Encoding": "chunked",
        "Accept-Ranges": "bytes",
        "Keep-Alive": "true",
        # "X-Content-Duration": "201.0",
        "X-Custom-Header": "Custom Value",
    }

    # Read the requested portion of the file
    with open("static/audio.opus", "rb") as f:
        f.seek(start)
        file_content = f.read(content_length)

    # Return partial content with 206 status code
    return Response(
        content=file_content, status_code=206, media_type="audio/opus", headers=headers
    )


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8081)
