from pathlib import Path
from PIL import Image, ImageDraw, ImageFont

# Import configurable constants and helpers
from .constants import (
    GRID_LINE_COLOR_RGBA,
    GRID_LABEL_TEXT_COLOR_RGBA,
    GRID_LABEL_FONT_SIZE,
    GRID_LABEL_BG_COLOR_RGBA,
    GRID_COL_LABEL_STYLE,
    GRID_COL_LABEL_POSITIONS,
    GRID_USE_HEADER_BANDS,
)
from .utils import column_index_to_label


def save_grid_overlay(screenshot_path, out_path, cols, rows) -> None:
    """Render the legacy/internal grid overlay and save to out_path.

    This reproduces the previous internal overlay used by the analyzer, with:
    - Optional header bands for labels (top/bottom for columns, left gutter for rows)
    - Numeric/alpha/both column label styles
    - Optional in-cell labels can be drawn by callers if desired
    """
    try:
        # Use RGBA so we can draw semi-transparent label backgrounds
        base = Image.open(screenshot_path).convert('RGBA')
        img = base.copy()
        draw = ImageDraw.Draw(img, 'RGBA')
        w, h = img.size
        cols = max(1, int(cols)); rows = max(1, int(rows))

        # Optional header bands: reserve a band at top and a gutter at left for labels
        header_top = int(GRID_LABEL_FONT_SIZE * 1.6) if GRID_USE_HEADER_BANDS else 0
        footer_bottom = int(GRID_LABEL_FONT_SIZE * 1.6) if (GRID_USE_HEADER_BANDS and GRID_COL_LABEL_POSITIONS in ('bottom','both')) else 0
        left_gutter = int(GRID_LABEL_FONT_SIZE * 1.8) if GRID_USE_HEADER_BANDS else 0

        grid_w = max(1, w - left_gutter)
        grid_h = max(1, h - header_top - footer_bottom)
        cell_w = grid_w / cols
        cell_h = grid_h / rows
        line_color = GRID_LINE_COLOR_RGBA

        # Grid lines
        for c in range(1, cols):
            x = int(left_gutter + c * cell_w)
            draw.line([(x, header_top), (x, header_top + grid_h)], fill=line_color, width=1)
        for r in range(1, rows):
            y = int(header_top + r * cell_h)
            draw.line([(left_gutter, y), (left_gutter + grid_w, y)], fill=line_color, width=1)

        # Label styling
        try:
            try:
                font = ImageFont.truetype("arial.ttf", GRID_LABEL_FONT_SIZE)
            except Exception:
                font = ImageFont.truetype("DejaVuSans-Bold.ttf", GRID_LABEL_FONT_SIZE)
        except Exception:
            font = ImageFont.load_default()
        pad = 2
        label_fill = GRID_LABEL_TEXT_COLOR_RGBA
        bg_fill = GRID_LABEL_BG_COLOR_RGBA

        def _draw_col_label(c: int, y: int):
            # Support numeric or alpha or both labels for columns
            alpha_label = column_index_to_label(c) or ""
            numeric_label = str(c)
            if GRID_COL_LABEL_STYLE == 'alpha':
                label = alpha_label
            elif GRID_COL_LABEL_STYLE == 'both':
                label = f"{alpha_label}\n{numeric_label}"
            else:
                # default to numeric for strongest anchoring
                label = numeric_label
            x = int(left_gutter + (c - 0.5) * cell_w)
            # If multiline, compute bbox for full text
            bbox = draw.multiline_textbbox((0, 0), label, font=font, spacing=0)
            tw = bbox[2] - bbox[0]; th = bbox[3] - bbox[1]
            draw.rectangle([(x - tw // 2 - pad, y - pad), (x + tw // 2 + pad, y + th + pad)], fill=bg_fill)
            try:
                draw.multiline_text((x - tw // 2, y), label, fill=label_fill, font=font, align='center', spacing=0)
            except Exception:
                draw.text((x - tw // 2, y), label, fill=label_fill, font=font)

        # Column labels (top/bottom/both)
        if GRID_COL_LABEL_POSITIONS in ('top', 'both'):
            for c in range(1, cols + 1):
                _draw_col_label(c, 2 if not GRID_USE_HEADER_BANDS else max(2, (GRID_LABEL_FONT_SIZE - GRID_LABEL_FONT_SIZE)))
        if GRID_COL_LABEL_POSITIONS in ('bottom', 'both'):
            bottom_y = h - (int(GRID_LABEL_FONT_SIZE * 1.6) if GRID_USE_HEADER_BANDS else int(GRID_LABEL_FONT_SIZE * 1.6))
            for c in range(1, cols + 1):
                _draw_col_label(c, bottom_y)

        # Row labels (left)
        for r in range(1, rows + 1):
            label = str(r)
            x = 2
            y = int(header_top + (r - 0.5) * cell_h) - 8
            bbox = draw.textbbox((0, 0), label, font=font)
            tw = bbox[2] - bbox[0]; th = bbox[3] - bbox[1]
            # Draw row labels inside the left gutter
            draw.rectangle([(x - pad, y - pad), (x + tw + pad), (y + th + pad)], fill=bg_fill)
            draw.text((x, y), label, fill=label_fill, font=font)

        # Save as PNG/JPEG depending on extension
        out = Path(out_path)
        img.convert('RGB').save(out)
    except Exception:
        # Swallow to avoid crashing callers; this mirrors existing behavior
        pass


