"""
Prepare spreadsheet files for PDF conversion via LibreOffice.

Sets landscape orientation and fit-to-width on all sheets so that
LibreOffice's --convert-to pdf produces output with all columns visible.

Supports: .xlsx, .xls, .csv
Output: Always an .xlsx file with proper page layout settings.

Usage:
    python3 spreadsheet_prepare.py <input_file> <output_xlsx>
"""

import sys
import csv
import io
from pathlib import Path


def prepare_xlsx(input_path: str, output_path: str) -> None:
    """Convert input spreadsheet to an XLSX with landscape + fit-to-width page setup."""
    from openpyxl import Workbook, load_workbook
    from openpyxl.worksheet.properties import PageSetupProperties

    ext = Path(input_path).suffix.lower()

    if ext == ".xlsx":
        wb = load_workbook(input_path)
    elif ext == ".xls":
        wb = _xls_to_workbook(input_path)
    elif ext == ".csv":
        wb = _csv_to_workbook(input_path)
    else:
        raise ValueError(f"Unsupported spreadsheet type: {ext}")

    # Apply page layout to every sheet
    for ws in wb.worksheets:
        # Enable fit-to-page mode (MUST be set before fitToWidth/fitToHeight)
        if ws.sheet_properties.pageSetUpPr is None:
            ws.sheet_properties.pageSetUpPr = PageSetupProperties()
        ws.sheet_properties.pageSetUpPr.fitToPage = True

        # Landscape orientation
        ws.page_setup.orientation = "landscape"

        # Fit all columns on 1 page width, unlimited vertical pages
        ws.page_setup.fitToWidth = 1
        ws.page_setup.fitToHeight = 0

        # Use wider paper (A3 landscape) for very wide sheets
        # OOXML paper size codes: 1=Letter, 8=A3, 9=A4
        if ws.max_column and ws.max_column > 10:
            ws.page_setup.paperSize = 8  # A3
        else:
            ws.page_setup.paperSize = 9  # A4

        # Reduce margins for maximum data area
        ws.page_margins.left = 0.3
        ws.page_margins.right = 0.3
        ws.page_margins.top = 0.4
        ws.page_margins.bottom = 0.4
        ws.page_margins.header = 0.2
        ws.page_margins.footer = 0.2

        # Auto-fit column widths (approximate)
        _autofit_columns(ws)

    wb.save(output_path)
    print(f'{{"success": true, "output": "{output_path}", "sheets": {len(wb.worksheets)}}}')


def _autofit_columns(ws) -> None:
    """Approximate auto-fit by measuring max content length per column."""
    for col_cells in ws.columns:
        max_length = 0
        col_letter = col_cells[0].column_letter
        for cell in col_cells:
            if cell.value is not None:
                cell_len = len(str(cell.value))
                if cell_len > max_length:
                    max_length = cell_len
        # Set width with some padding, cap at 50
        adjusted_width = min(max_length + 3, 50)
        if adjusted_width < 8:
            adjusted_width = 8
        ws.column_dimensions[col_letter].width = adjusted_width


def _xls_to_workbook(input_path: str):
    """Convert .xls to openpyxl Workbook using xlrd."""
    import xlrd
    from openpyxl import Workbook

    xls_wb = xlrd.open_workbook(input_path)
    wb = Workbook()
    # Remove default sheet
    wb.remove(wb.active)

    for sheet_idx in range(xls_wb.nsheets):
        xls_ws = xls_wb.sheet_by_index(sheet_idx)
        ws = wb.create_sheet(title=xls_ws.name)

        for row_idx in range(xls_ws.nrows):
            for col_idx in range(xls_ws.ncols):
                val = xls_ws.cell_value(row_idx, col_idx)
                cell_type = xls_ws.cell_type(row_idx, col_idx)

                if cell_type == xlrd.XL_CELL_DATE:
                    try:
                        val = xlrd.xldate_as_datetime(val, xls_wb.datemode)
                    except Exception:
                        pass
                elif cell_type == xlrd.XL_CELL_BOOLEAN:
                    val = bool(val)
                elif cell_type == xlrd.XL_CELL_EMPTY:
                    val = None

                ws.cell(row=row_idx + 1, column=col_idx + 1, value=val)

    xls_wb.release_resources()
    return wb


def _csv_to_workbook(input_path: str):
    """Convert .csv to openpyxl Workbook."""
    from openpyxl import Workbook

    wb = Workbook()
    ws = wb.active
    ws.title = Path(input_path).stem

    # Try UTF-8 first, fall back to latin-1
    try:
        content = Path(input_path).read_text(encoding="utf-8-sig")  # handles BOM
    except UnicodeDecodeError:
        content = Path(input_path).read_text(encoding="latin-1")

    reader = csv.reader(io.StringIO(content))
    for row_idx, row in enumerate(reader, 1):
        for col_idx, val in enumerate(row, 1):
            # Try to convert numeric strings to numbers
            if val:
                cleaned = val.replace(",", "").strip()
                try:
                    if "." in cleaned:
                        ws.cell(row=row_idx, column=col_idx, value=float(cleaned))
                    else:
                        ws.cell(row=row_idx, column=col_idx, value=int(cleaned))
                except ValueError:
                    ws.cell(row=row_idx, column=col_idx, value=val)
            else:
                ws.cell(row=row_idx, column=col_idx, value=val)

    # Bold the header row
    from openpyxl.styles import Font
    for cell in ws[1]:
        cell.font = Font(bold=True)

    return wb


if __name__ == "__main__":
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} <input_file> <output_xlsx>", file=sys.stderr)
        sys.exit(1)

    try:
        prepare_xlsx(sys.argv[1], sys.argv[2])
    except Exception as e:
        print(f'{{"success": false, "error": "{e}"}}', file=sys.stderr)
        sys.exit(1)
