#!/usr/bin/env python3

import re
import sys
from pathlib import Path

import openpyxl
import ezodf
from openpyxl.utils import column_index_from_string


def find_suffix_in_column(ws, column_letter, prefix):
    """Search column for a cell starting with prefix and return the suffix."""
    col_idx = column_index_from_string(column_letter)
    for row in ws.iter_rows(min_col=col_idx, max_col=col_idx, values_only=False):
        cell = row[0]
        if isinstance(cell.value, str):
            m = re.search(rf'{re.escape(prefix)}(.+)', cell.value)
            if m:
                return m.group(1)
    return None


def find_cell_containing(ws, substring):
    """Return the first cell whose value contains the given substring."""
    for row in ws.iter_rows(values_only=False):
        for cell in row:
            if isinstance(cell.value, str) and substring in cell.value:
                return cell
    return None


def address_to_indices(addr):
    """Convert an A1-style address to zero‑based (row, col) indices."""
    match = re.match(r'([A-Z]+)(\\d+)', addr)
    col_letter, row_str = match.groups()
    col = column_index_from_string(col_letter) - 1
    row = int(row_str) - 1
    return row, col


def fill_range(sheet, start_addr, end_addr, value):
    """Fill a rectangular range in the ODS sheet with the same value."""
    start_row, start_col = address_to_indices(start_addr)
    end_row, end_col = address_to_indices(end_addr)
    for r in range(start_row, end_row + 1):
        for c in range(start_col, end_col + 1):
            sheet[r, c].set_value(value)


def main():
    # Paths are relative to this script's location
    source_path = Path(__file__).parent / "Production Order (mrp.production).xlsx"
    template_path = Path(__file__).parent / "A4004_v3.0-260617.ods"

    # Load source workbook
    wb = openpyxl.load_workbook(source_path, data_only=True)
    ws = wb.active

    # 1. Serial number suffix after 'FA-'
    suffix = find_suffix_in_column(ws, "B", "FA-")
    if not suffix:
        print("FA- suffix not found", file=sys.stderr)
        sys.exit(1)

    # 2. Component values
    components = {
        "All / Components / Barebone": "C10:D10",
        "All / Components / GPU": "C20:D23",
        "All / Components / RAM": "C12:D19",
        "All / Components / CPU": "C11:D11",
        "All / Components / SSD": "C24:D25",
        "All / Components / RAID": "C27:D27",
    }

    comp_values = {}
    for label, target_range in components.items():
        cell = find_cell_containing(ws, label)
        if cell:
            right_cell = ws.cell(row=cell.row, column=cell.column + 1)
            comp_values[label] = right_cell.value
        else:
            comp_values[label] = None
            print(f"Warning: '{label}' not found", file=sys.stderr)

    # Load ODS template
    doc = ezodf.opendoc(str(template_path))
    sheet = doc.sheets[0]

    # Fill serial suffix into B1:C2
    fill_range(sheet, "B1", "C2", suffix)

    # Fill component ranges
    for label, target_range in components.items():
        value = comp_values[label]
        if value is not None:
            start_addr, end_addr = target_range.split(":")
            fill_range(sheet, start_addr, end_addr, value)

    # Output file name from A2
    a2_value = ws["A2"].value
    if not a2_value:
        print("Cell A2 is empty; cannot determine output filename.", file=sys.stderr)
        sys.exit(1)

    output_name = f"{a2_value}.ods"
    output_path = Path(__file__).parent / output_name
    doc.saveas(str(output_path))
