"""
routes/appender_routes.py
--------------------------
Endpoints for the file appender feature.

Caller uploads multiple CSV/XLSX files → backend concatenates them → returns
the combined file. No state is stored between requests.
"""
import io
from typing import Literal

from fastapi import APIRouter, UploadFile, File, Form, HTTPException
from fastapi.responses import StreamingResponse
import pandas as pd

from functions.file_utils import read_uploaded_file, records_to_excel_bytes, records_to_csv_bytes

router = APIRouter()


# ── Append Files ──────────────────────────────────────────────────────────────

@router.post("/append")
async def append_files(
    files: list[UploadFile] = File(...),
    sort_mode: str = Form("manual"),
    sort_direction: str = Form("asc"),
    sort_condition: str = Form("filename"),
    sheet_name: str = Form("AppendedData"),
    output_format: str = Form("xlsx"),
    add_source_column: bool = Form(True),
):
    """
    Concatenate multiple uploaded CSV/XLSX files into one output file.

    - sort_mode: 'manual' (preserve upload order) or 'conditional' (sort by sort_condition)
    - sort_condition: 'filename' (other conditions can be added as needed)
    - sort_direction: 'asc' | 'desc'
    - add_source_column: if True, adds a '__source_file' column with the originating filename
    - output_format: 'xlsx' | 'csv'
    """
    if not files:
        raise HTTPException(status_code=400, detail="No files provided")

    # Read all uploads
    uploads = []
    for f in files:
        records, fname = await read_uploaded_file(f)
        uploads.append({"filename": fname, "records": records})

    # Sort if requested
    if sort_mode == "conditional":
        reverse = sort_direction.lower() == "desc"
        if sort_condition == "filename":
            uploads.sort(key=lambda x: (x["filename"] or "").lower(), reverse=reverse)
        else:
            raise HTTPException(
                status_code=400,
                detail=f"Unsupported sort_condition: {sort_condition}",
            )

    # Combine
    all_rows = []
    for item in uploads:
        for row in item["records"]:
            if add_source_column:
                row = {**row, "__source_file": item["filename"]}
            all_rows.append(row)

    if not all_rows:
        raise HTTPException(status_code=400, detail="All files were empty")

    # Build output
    safe_sheet = (sheet_name.strip() or "AppendedData")[:31]

    if output_format == "csv":
        content = records_to_csv_bytes(all_rows)
        return StreamingResponse(
            io.BytesIO(content),
            media_type="text/csv",
            headers={"Content-Disposition": 'attachment; filename="appended_output.csv"'},
        )

    # XLSX with openpyxl
    df = pd.DataFrame(all_rows)
    buf = io.BytesIO()
    with pd.ExcelWriter(buf, engine="openpyxl") as writer:
        df.to_excel(writer, index=False, sheet_name=safe_sheet)
    buf.seek(0)

    return StreamingResponse(
        buf,
        media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        headers={"Content-Disposition": 'attachment; filename="appended_output.xlsx"'},
    )


# ── Column Preview (single file) ──────────────────────────────────────────────

@router.post("/preview-columns")
async def preview_columns(file: UploadFile = File(...)):
    """
    Return columns and row count for a single uploaded file.
    Handy for showing a preview before appending.
    """
    records, filename = await read_uploaded_file(file)
    columns = list(records[0].keys()) if records else []
    return {
        "ok": True,
        "filename": filename,
        "rows": len(records),
        "columns": columns,
    }
