"""CSV and XLSX export helpers.

Callers pass already-flattened row data (iterables of scalars). Helpers return
either raw bytes (used for storage artefacts) or a ready-to-stream
:class:`~django.http.HttpResponse`.
"""
from __future__ import annotations

import csv
import io
from typing import Any, Iterable, Sequence

from django.http import HttpResponse


# ---------------------------------------------------------------------------
# CSV
# ---------------------------------------------------------------------------


def write_csv(headers: Sequence[str], rows: Iterable[Sequence[Any]]) -> bytes:
    """Return UTF-8-encoded CSV bytes for the given headers and rows."""
    buffer = io.StringIO()
    writer = csv.writer(buffer, quoting=csv.QUOTE_MINIMAL)
    writer.writerow(list(headers))
    for row in rows:
        writer.writerow(list(row))
    return buffer.getvalue().encode("utf-8")


def csv_response(
    headers: Sequence[str],
    rows: Iterable[Sequence[Any]],
    *,
    filename: str,
) -> HttpResponse:
    data = write_csv(headers, rows)
    response = HttpResponse(data, content_type="text/csv; charset=utf-8")
    safe = filename.replace('"', "")
    response["Content-Disposition"] = f'attachment; filename="{safe}"'
    return response


# ---------------------------------------------------------------------------
# XLSX
# ---------------------------------------------------------------------------


def write_xlsx(
    headers: Sequence[str],
    rows: Iterable[Sequence[Any]],
    *,
    sheet_name: str = "Sheet1",
) -> bytes:
    """Return XLSX bytes for the given headers and rows using openpyxl."""
    from openpyxl import Workbook  # lazy — openpyxl is only needed for export paths

    wb = Workbook()
    ws = wb.active
    ws.title = (sheet_name or "Sheet1")[:31]
    ws.append(list(headers))
    for row in rows:
        ws.append(list(row))
    buf = io.BytesIO()
    wb.save(buf)
    return buf.getvalue()


def xlsx_response(
    headers: Sequence[str],
    rows: Iterable[Sequence[Any]],
    *,
    filename: str,
    sheet_name: str = "Sheet1",
) -> HttpResponse:
    data = write_xlsx(headers, rows, sheet_name=sheet_name)
    response = HttpResponse(
        data,
        content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    )
    safe = filename.replace('"', "")
    response["Content-Disposition"] = f'attachment; filename="{safe}"'
    return response
