#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
xlsx_create.py — Create xlsx from JSON data using openpyxl.

Usage:
    python3 xlsx_create.py --data data.json --out output.xlsx
    python3 xlsx_create.py --data-inline '{"headers":["A","B"],"rows":[["1","2"]]}' --out output.xlsx

JSON format:
    {
        "title": "Sheet title (optional, used as sheet name)",
        "headers": ["Col1", "Col2", ...],
        "rows": [["val1", "val2", ...], ...],
        "col_widths": [15, 20, ...]  // optional
    }

Exit codes: 0 success, 1 bad args, 2 missing dep
"""
import argparse
import json
import os
import sys

try:
    from openpyxl import Workbook
    from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
except ImportError:
    print(json.dumps({"status": "error", "error": "openpyxl not installed", "hint": "pip install openpyxl"}))
    sys.exit(2)


def create_xlsx(data: dict, out_path: str) -> dict:
    wb = Workbook()
    ws = wb.active
    ws.title = data.get("title", "Sheet1")[:31]

    headers = data.get("headers", [])
    rows = data.get("rows", [])
    col_widths = data.get("col_widths", [])

    # Header row styling
    header_font = Font(bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
    header_align = Alignment(horizontal="center", vertical="center")
    thin_border = Border(
        left=Side(style="thin"),
        right=Side(style="thin"),
        top=Side(style="thin"),
        bottom=Side(style="thin"),
    )

    # Write headers
    for col_idx, header in enumerate(headers, 1):
        cell = ws.cell(row=1, column=col_idx, value=header)
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = header_align
        cell.border = thin_border

    # Write data rows
    for row_idx, row_data in enumerate(rows, 2):
        for col_idx, value in enumerate(row_data, 1):
            cell = ws.cell(row=row_idx, column=col_idx, value=_auto_type(value))
            cell.border = thin_border
            cell.alignment = Alignment(vertical="center")

    # Column widths
    for col_idx, width in enumerate(col_widths, 1):
        ws.column_dimensions[chr(64 + col_idx) if col_idx <= 26 else f"{chr(64 + (col_idx-1)//26)}{chr(65 + (col_idx-1)%26)}"].width = width

    # Auto-width for columns without explicit width
    if not col_widths:
        for col_idx in range(1, len(headers) + 1):
            max_len = len(str(headers[col_idx - 1])) if col_idx <= len(headers) else 8
            for row_idx in range(2, min(len(rows) + 2, 52)):
                if col_idx <= len(rows[row_idx - 2]):
                    cell_len = len(str(rows[row_idx - 2][col_idx - 1]))
                    max_len = max(max_len, cell_len)
            col_letter = chr(64 + col_idx) if col_idx <= 26 else f"{chr(64 + (col_idx-1)//26)}{chr(65 + (col_idx-1)%26)}"
            ws.column_dimensions[col_letter].width = min(max_len + 4, 50)

    # Freeze header row
    ws.freeze_panes = "A2"

    # Auto-filter
    if headers:
        last_col = chr(64 + len(headers)) if len(headers) <= 26 else f"{chr(64 + (len(headers)-1)//26)}{chr(65 + (len(headers)-1)%26)}"
        ws.auto_filter.ref = f"A1:{last_col}{len(rows) + 1}"

    os.makedirs(os.path.dirname(out_path) or ".", exist_ok=True)
    wb.save(out_path)

    return {
        "status": "ok",
        "out": out_path,
        "rows": len(rows),
        "columns": len(headers),
        "size_kb": os.path.getsize(out_path) // 1024,
    }


def _auto_type(value):
    if value is None:
        return ""
    if isinstance(value, (int, float)):
        return value
    s = str(value)
    try:
        return int(s)
    except ValueError:
        pass
    try:
        return float(s)
    except ValueError:
        pass
    return s


def main():
    parser = argparse.ArgumentParser(description="Create xlsx from JSON data")
    parser.add_argument("--data", help="Path to JSON data file")
    parser.add_argument("--data-inline", help="Inline JSON data string")
    parser.add_argument("--out", required=True, help="Output xlsx file path")
    args = parser.parse_args()

    if args.data and os.path.exists(args.data):
        with open(args.data, encoding="utf-8") as f:
            data = json.load(f)
    elif args.data_inline:
        data = json.loads(args.data_inline)
    elif args.data and (args.data.strip().startswith("{") or args.data.strip().startswith("[")):
        data = json.loads(args.data)
    else:
        print(json.dumps({"status": "error", "error": "No data provided. Use --data <file> or --data-inline '<json>'"}))
        sys.exit(1)

    result = create_xlsx(data, args.out)
    print(json.dumps(result, ensure_ascii=False))


if __name__ == "__main__":
    main()
