"""
表格线绘制服务
提供纯函数式的绘图接口，用于最终保存带线图片
"""

from PIL import Image, ImageDraw, ImageFont
from typing import Dict, List, Tuple, Optional


class DrawingService:
    """绘图服务"""
    
    @staticmethod
    def draw_clean_lines(
        image: Image.Image,
        structure: Dict,
        line_width: int = 2,
        line_color: Tuple[int, int, int] = (0, 0, 0)
    ) -> Image.Image:
        """
        绘制纯净的表格线（用于保存）
        
        Args:
            image: PIL Image 对象
            structure: 表格结构字典
            line_width: 线条宽度
            line_color: 线条颜色，默认黑色
        
        Returns:
            绘制了表格线的图片
        """
        img_with_lines = image.copy()
        # 只旋转图像，不旋转线坐标；线条保持横平竖直
        # expand=False 保持画布尺寸不变（与前端 Konva rotation 行为一致）
        skewed_angle = structure.get('skew_angle', 0.0)
        if abs(skewed_angle) > 1e-3:
            img_with_lines = img_with_lines.rotate(-skewed_angle, expand=False, resample=Image.Resampling.BICUBIC, fillcolor=(255, 255, 255))
            draw = ImageDraw.Draw(img_with_lines)
        else:
            draw = ImageDraw.Draw(img_with_lines)
        
        horizontal_lines = structure.get('horizontal_lines', [])
        vertical_lines = structure.get('vertical_lines', [])
        
        if not horizontal_lines or not vertical_lines:
            return img_with_lines
        
        # 计算绘制范围
        x_start = vertical_lines[0]
        x_end = vertical_lines[-1]
        y_start = horizontal_lines[0]
        y_end = horizontal_lines[-1]
        
        # 绘制横线
        for y in horizontal_lines:
            draw.line([(x_start, y), (x_end, y)], fill=line_color, width=line_width)
        
        # 绘制竖线
        for x in vertical_lines:
            draw.line([(x, y_start), (x, y_end)], fill=line_color, width=line_width)
        
        return img_with_lines

    @staticmethod
    def draw_lines_with_labels(
        image: Image.Image,
        structure: Dict,
        line_width: int = 2,
        normal_color: Tuple[int, int, int] = (0, 0, 255),
        modified_color: Tuple[int, int, int] = (255, 0, 0),
        show_labels: bool = True,
        font_size: int = 20
    ) -> Image.Image:
        """
        绘制带编号标签的表格线（用于预览，可选）
        
        Args:
            image: PIL Image 对象
            structure: 表格结构字典
            line_width: 线条宽度
            normal_color: 普通线条颜色
            modified_color: 修改过的线条颜色
            show_labels: 是否显示编号
            font_size: 字体大小
        
        Returns:
            绘制了表格线和编号的图片
        """
        img_with_lines = image.copy()
        draw = ImageDraw.Draw(img_with_lines)
        
        # 尝试加载字体
        try:
            font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", font_size)
        except:
            try:
                font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", font_size)
            except:
                font = ImageFont.load_default()
        
        horizontal_lines = structure.get('horizontal_lines', [])
        vertical_lines = structure.get('vertical_lines', [])
        modified_h_lines = set(structure.get('modified_h_lines', []))
        modified_v_lines = set(structure.get('modified_v_lines', []))
        
        if not horizontal_lines or not vertical_lines:
            return img_with_lines
        
        # 计算绘制范围
        x_start = vertical_lines[0]
        x_end = vertical_lines[-1]
        y_start = horizontal_lines[0]
        y_end = horizontal_lines[-1]
        
        # 绘制横线
        for idx, y in enumerate(horizontal_lines):
            color = modified_color if idx in modified_h_lines else normal_color
            draw.line([(x_start, y), (x_end, y)], fill=color, width=line_width)
            
            # 绘制行编号
            if show_labels:
                text = f"R{idx+1}"
                bbox = draw.textbbox((x_start - 35, y - 10), text, font=font)
                draw.rectangle(bbox, fill='white', outline='black')
                draw.text((x_start - 35, y - 10), text, fill=color, font=font)
        
        # 绘制竖线
        for idx, x in enumerate(vertical_lines):
            color = modified_color if idx in modified_v_lines else normal_color
            draw.line([(x, y_start), (x, y_end)], fill=color, width=line_width)
            
            # 绘制列编号
            if show_labels:
                text = f"C{idx+1}"
                # 上方编号
                bbox = draw.textbbox((x - 10, y_start - 25), text, font=font)
                draw.rectangle(bbox, fill='white', outline='black')
                draw.text((x - 10, y_start - 25), text, fill=color, font=font)
        
        return img_with_lines

    @staticmethod
    def create_thumbnail(
        image: Image.Image,
        structure: Dict,
        size: Tuple[int, int] = (200, 280)
    ) -> Image.Image:
        """
        创建带表格线的缩略图（用于模板预览）
        
        Args:
            image: 原始图片
            structure: 表格结构
            size: 缩略图尺寸
        
        Returns:
            缩略图
        """
        # 先绘制表格线
        img_with_lines = DrawingService.draw_clean_lines(
            image, structure, line_width=1, line_color=(0, 0, 255)
        )
        
        # 缩放到目标尺寸
        img_with_lines.thumbnail(size, Image.Resampling.LANCZOS)
        
        return img_with_lines
