"""
functions/file_utils.py
-----------------------
Utilities for reading uploaded files (CSV / XLSX / XLS) into list[dict].
No shared state — each call is independent.
"""
import io
import pandas as pd
from fastapi import UploadFile, HTTPException


async def read_uploaded_file(file: UploadFile) -> tuple[list[dict], str]:
    """
    Read an uploaded CSV or Excel file and return (records, filename).
    Raises HTTPException 400 on unsupported format or parse failure.
    """
    filename = (file.filename or "").lower()
    content = await file.read()
    buf = io.BytesIO(content)

    try:
        if filename.endswith(".csv"):
            df = pd.read_csv(buf)
        elif filename.endswith((".xlsx", ".xls")):
            df = pd.read_excel(buf)
        else:
            raise HTTPException(
                status_code=400,
                detail=f"Unsupported file type: {file.filename}. Use CSV or XLSX.",
            )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"Failed to parse file: {e}")

    # Convert to plain Python dicts (JSON-serialisable)
    records = df.where(pd.notnull(df), None).to_dict(orient="records")
    return records, file.filename or "unknown"


def records_to_excel_bytes(records: list[dict]) -> bytes:
    """Serialise list[dict] to XLSX bytes."""
    df = pd.DataFrame(records)
    buf = io.BytesIO()
    with pd.ExcelWriter(buf, engine="openpyxl") as writer:
        df.to_excel(writer, index=False, sheet_name="Sample")
    buf.seek(0)
    return buf.read()


def records_to_csv_bytes(records: list[dict]) -> bytes:
    """Serialise list[dict] to CSV bytes (UTF-8 with BOM for Excel compatibility)."""
    df = pd.DataFrame(records)
    return df.to_csv(index=False).encode("utf-8-sig")
