import dash
from dash import Dash, Input, Output, State, html, dcc, callback, MATCH



def format_file_size(contents):
    """Calculate and format file size from base64 encoded contents."""
    content_string = contents.split(",")[1] if "," in contents else contents
    size_bytes = len(content_string) * 3 / 4
    if size_bytes < 1024:
        return f"{size_bytes:.0f} B"
    elif size_bytes < 1024 * 1024:
        return f"{size_bytes / 1024:.2f} KB"
    else:
        return f"{size_bytes / (1024 * 1024):.2f} MB"


def display_uploaded_files(contents, filenames):
    """Display name and filesize of uploaded files."""
    if contents is None or filenames is None:
        return html.Div("No files uploaded yet.")

    # Normalize to lists for uniform handling
    if not isinstance(contents, list):
        contents = [contents]
    if not isinstance(filenames, list):
        filenames = [filenames]

    file_items = [
        html.Li(f"{filename} - {format_file_size(content)}")
        for filename, content in zip(filenames, contents)
    ]

    return html.Div(
        [
            html.H5(f"Uploaded {len(filenames)} file(s):"),
            html.Ul(file_items),
        ]
    )


layout = [
    html.Div(
        [
            html.H3("Single File Upload"),
            dcc.Upload(
                id={"type": "upload", "index": "single"},
                children=html.Div(["Drag and Drop or ", html.Button("Select Files")]),
                accept="application/pdf",
            ),
            html.Div(id={"type": "upload-output", "index": "single"}),
        ]
    ),
    html.Div(
        [
            html.H3("Multiple File Upload - List Names"),
            dcc.Upload(
                id={"type": "upload", "index": "multi"},
                children=html.Div(
                    ["Drag and Drop or ", html.Button("Select Multiple Files")]
                ),
                multiple=True,
                accept="application/pdf",
            ),
            html.Div(id={"type": "upload-output", "index": "multi"}),
        ]
    ),
]


@callback(
    Output({"type": "upload-output", "index": MATCH}, "children"),
    Input({"type": "upload", "index": MATCH}, "contents"),
    State({"type": "upload", "index": MATCH}, "filename"),
)
def update_upload_output(contents, filenames):
    return display_uploaded_files(contents, filenames)


if __name__ == "__main__":
    app = Dash(__name__)
    server = app.server
    app.layout = layout
    app.run(debug=True, host="0.0.0.0")
else:
    dash.register_page(__name__)
