"""
Excel图像集成工具
"""

import io
from pathlib import Path
from typing import Any

from openpyxl.drawing.image import Image as OpenPyXLImage
from openpyxl.utils import column_index_from_string, get_column_letter
from PIL import Image as PILImage

from ..core.worksheet import Worksheet
from ..images.image_processor import CellImageOptions, ImageProcessor
from ..utils.exceptions import ValidationError
from ..utils.helpers import validate_cell_reference


class ExcelImage:
    """
    Excel图像集成类
    """

    def __init__(self, image_processor: ImageProcessor | None = None) -> None:
        """
        初始化Excel图像集成

        参数:
            image_processor: 图像处理器实例
        """
        self.image_processor = image_processor or ImageProcessor()

    def insert_image(
        self,
        worksheet: Worksheet,
        image_source: str | Path | bytes | io.BytesIO,
        cell_reference: str,
        width: int | None = None,
        height: int | None = None,
        options: CellImageOptions | None = None,
    ) -> None:
        """
        在工作表中插入图像

        参数:
            worksheet: 目标工作表
            image_source: 图像源
            cell_reference: 目标单元格 (例如: 'A1')
            width: 可选宽度（像素）
            height: 可选高度（像素）
            options: 图像选项

        异常:
            ValidationError: 如果插入失败
        """
        try:
            # 验证单元格引用
            validate_cell_reference(cell_reference)

            # 加载和处理图像
            image = self.image_processor.load_image(image_source)

            # 如果指定了尺寸则调整大小
            if width or height:
                image = self.image_processor.resize_image(image, width, height)

            # 保持原图，不进行优化
            image_buffer = io.BytesIO()
            try:
                image.save(image_buffer, format=image.format)
            except Exception:
                image.save(image_buffer, format="PNG")
            # 重要：不关闭缓冲区，保持打开状态以供保存时使用
            image_buffer.seek(0)

            # 创建OpenPyXL图像
            excel_image = OpenPyXLImage(image_buffer)

            # 使用 TwoCellAnchor 真正嵌入到单元格，并设置默认边距
            # 默认边距：2像素
            margin_px = options.margin if options and hasattr(options, "margin") else 2
            self._insert_image_with_anchor(
                excel_image, worksheet, cell_reference, options, margin_px=margin_px
            )

        except Exception as e:
            raise ValidationError(f"插入图像失败: {e}")

    def insert_image_with_size(
        self,
        worksheet: Worksheet,
        image_source: str | Path | bytes | io.BytesIO,
        cell_reference: str,
        cell_width: int | None = None,
        cell_height: int | None = None,
        options: CellImageOptions | None = None,
    ) -> None:
        """
        插入图像并适配单元格大小

        参数:
            worksheet: 目标工作表
            image_source: 图像源
            cell_reference: 目标单元格
            cell_width: 单元格宽度（像素，可选）
            cell_height: 单元格高度（像素，可选）
            options: 图像选项
        """
        try:
            # 加载图像
            image = self.image_processor.load_image(image_source)

            # 如果未提供则获取单元格尺寸
            if cell_width is None or cell_height is None:
                cell_width, cell_height = self._get_cell_dimensions(
                    worksheet, cell_reference
                )

            # 计算适配单元格的图像尺寸
            if options and options.maintain_aspect_ratio:
                # 保持宽高比
                img_width, img_height = image.size
                aspect_ratio = img_width / img_height

                if cell_width / aspect_ratio <= cell_height:
                    width = cell_width - (options.margin * 2 if options else 4)
                    height = int(width / aspect_ratio)
                else:
                    height = cell_height - (options.margin * 2 if options else 4)
                    width = int(height * aspect_ratio)
            else:
                # 填充整个单元格
                width = cell_width - (options.margin * 2 if options else 4)
                height = cell_height - (options.margin * 2 if options else 4)

            # 调整图像大小
            resized_image = self.image_processor.resize_image(image, width, height)

            # 将PIL图像转换为BytesIO以插入
            image_buffer = io.BytesIO()
            try:
                resized_image.save(image_buffer, format=resized_image.format or "PNG")
            except Exception:
                resized_image.save(image_buffer, format="PNG")
            image_buffer.seek(0)

            # 插入调整大小的图像
            excel_image = OpenPyXLImage(image_buffer)

            # 设置默认边距：2像素
            margin_px = options.margin if options and hasattr(options, "margin") else 2
            self._insert_image_with_anchor(
                excel_image, worksheet, cell_reference, options, margin_px=margin_px
            )

        except Exception as e:
            raise ValidationError(f"按单元格大小插入图像失败: {e}")

    def insert_image_in_cell(
        self,
        worksheet: Worksheet,
        image_source: str | Path | bytes | io.BytesIO,
        cell_reference: str,
        options: CellImageOptions | None = None,
    ) -> None:
        """
        在单元格中插入图片

        方法会根据单元格大小自动调整图片尺寸，
        让图片适配单元格范围，并留出边距。

        参数:
            worksheet: 目标工作表
            image_source: 图像源（路径、字节或BytesIO）
            cell_reference: 目标单元格引用（如：A1）
            options: 图片选项（锚定和定位配置）
        """
        try:
            # 加载图像
            image = self.image_processor.load_image(image_source)

            # 初始化工作簿状态
            # 1. 激活工作表
            if (
                hasattr(worksheet._worksheet, "workbook")
                and worksheet._worksheet.workbook
            ):
                worksheet._worksheet.workbook.active = worksheet._worksheet

            # 2. 初始化worksheet基本信息
            ws = worksheet._worksheet
            try:
                # 访问基本属性触发初始化
                _ = ws.max_row
                _ = ws.max_column
                _ = ws.sheet_format.defaultRowHeight
            except Exception:
                pass

            # 3. 计算维度
            try:
                ws._calculate_dimensions()
            except Exception:
                pass

            # 4. 预加载列宽和行高
            # 遍历已设置的列宽
            for col_letter in list(ws.column_dimensions.keys()):
                try:
                    width = ws.column_dimensions[col_letter].width
                    ws.column_dimensions[col_letter].width = width
                except Exception:
                    pass

            # 遍历已设置的行高
            for row_num in list(ws.row_dimensions.keys()):
                try:
                    height = ws.row_dimensions[row_num].height
                    ws.row_dimensions[row_num].height = height
                except Exception:
                    pass

            # 5. 不修改列宽度，保持用户原有设置

            # 6. 重新获取单元格尺寸
            cell_width_px, cell_height_px = self._get_cell_dimensions(
                worksheet, cell_reference
            )

            # 计算适配单元格的图片尺寸
            # 填充整个单元格，预留边距避免压边框
            img_width, img_height = image.size
            aspect_ratio = img_width / img_height

            # 获取用户设置的边距，默认8像素
            margin = options.margin if options and hasattr(options, "margin") else 8

            # 以单元格宽度为基准，预留边距
            fit_width = max(cell_width_px - margin * 2, 10)  # 至少留10像素
            fit_height = int(fit_width / aspect_ratio)

            # 设置行高，避免Excel自动调整
            col, row = self._parse_cell_reference(cell_reference)
            # 像素高度转换为Excel行高单位（除以1.33）
            # 包含边距的总高度
            excel_row_height = max((fit_height + margin * 2) / 1.33, 15.0)

            # 刷新工作簿状态
            try:
                worksheet._worksheet._calculate_dimensions()
            except Exception:
                pass

            worksheet._worksheet.row_dimensions[row].height = excel_row_height

            # 刷新列宽计算
            from openpyxl.utils import get_column_letter

            col_letter = get_column_letter(col)
            if col_letter in worksheet._worksheet.column_dimensions:
                # 更新列宽缓存
                worksheet._worksheet.column_dimensions[
                    col_letter
                ].width = worksheet._worksheet.column_dimensions[col_letter].width

            # 图像缩放处理，提高清晰度
            # 多阶段缩放：逐步调整，确保质量
            if fit_width > 0 and fit_height > 0:
                # 使用LANCZOS高质量重采样
                max_scale = 4

                # 阶段1：放大4倍
                scale1_width = fit_width * max_scale
                scale1_height = fit_height * max_scale
                image = self.image_processor.resize_image(
                    image,
                    width=scale1_width,
                    height=scale1_height,
                    maintain_aspect_ratio=True,
                    resample=PILImage.Resampling.LANCZOS,
                )

                # 阶段2：缩到3倍
                scale2_width = fit_width * 3
                scale2_height = fit_height * 3
                image = self.image_processor.resize_image(
                    image,
                    width=scale2_width,
                    height=scale2_height,
                    maintain_aspect_ratio=True,
                    resample=PILImage.Resampling.LANCZOS,
                )

                # 阶段3：缩到2倍
                scale3_width = fit_width * 2
                scale3_height = fit_height * 2
                image = self.image_processor.resize_image(
                    image,
                    width=scale3_width,
                    height=scale3_height,
                    maintain_aspect_ratio=True,
                    resample=PILImage.Resampling.LANCZOS,
                )

                # 阶段4：缩到1.5倍
                scale4_width = int(fit_width * 1.5)
                scale4_height = int(fit_height * 1.5)
                image = self.image_processor.resize_image(
                    image,
                    width=scale4_width,
                    height=scale4_height,
                    maintain_aspect_ratio=True,
                    resample=PILImage.Resampling.LANCZOS,
                )

                # 阶段5：缩到目标尺寸
                image = self.image_processor.resize_image(
                    image,
                    width=fit_width,
                    height=fit_height,
                    maintain_aspect_ratio=True,
                    resample=PILImage.Resampling.LANCZOS,
                )

            # 将图像转换为BytesIO
            image_buffer = io.BytesIO()
            try:
                # 保存为PNG格式，不压缩
                if image.mode == "RGBA":
                    image.save(
                        image_buffer, format="PNG", optimize=False, compress_level=0
                    )
                else:
                    image.save(
                        image_buffer, format="PNG", optimize=False, compress_level=0
                    )
            except Exception:
                image.save(image_buffer, format="PNG")

            # 重置缓冲区位置
            image_buffer.seek(0)

            # 创建OpenPyXL图像
            excel_image = OpenPyXLImage(image_buffer)

            # 保存缓冲区引用
            excel_image._image_buffer = image_buffer

            # 插入图片到单元格
            self._insert_image_with_anchor(
                excel_image, worksheet, cell_reference, options, margin_px=margin
            )

        except Exception as e:
            raise ValidationError(f"在单元格中插入图像失败: {e}")

    def insert_images_batch(
        self, worksheet: Worksheet, images_data: list[dict[str, Any]]
    ) -> None:
        """
        高效插入多个图像

        参数:
            worksheet: 目标工作表
            images_data: 图像数据字典列表
                每个字典应包含:
                - 'image': 图像源
                - 'cell': 单元格引用
                - 'width': 可选宽度
                - 'height': 可选高度
                - 'options': 可选的CellImageOptions
        """
        for image_data in images_data:
            try:
                self.insert_image(
                    worksheet=worksheet,
                    image_source=image_data["image"],
                    cell_reference=image_data["cell"],
                    width=image_data.get("width"),
                    height=image_data.get("height"),
                    options=image_data.get("options"),
                )
            except Exception as e:
                import logging

                logger = logging.getLogger(__name__)
                logger.warning(
                    f"警告: 在 {image_data.get('cell', 'unknown')} 插入图像失败: {e}"
                )

    def create_image_from_cell_range(
        self,
        worksheet: Worksheet,
        range_reference: str,
        output_path: str | Path | None = None,
    ) -> io.BytesIO:
        """
        从单元格范围创建图像（类似截图功能）

        参数:
            worksheet: 源工作表
            range_reference: 单元格范围 (例如: 'A1:D10')
            output_path: 可选输出路径

        返回:
            图像缓冲区
        """
        # 这是一个占位符实现
        # 在实际实现中，这会将单元格范围渲染为图像
        # 现在，我们将创建一个简单的占位符图像

        from PIL import Image, ImageDraw

        # 解析范围
        start_cell, end_cell = range_reference.split(":")
        start_col, start_row = self._parse_cell_reference(start_cell)
        end_col, end_row = self._parse_cell_reference(end_cell)

        # 创建占位符图像
        width = (end_col - start_col + 1) * 100
        height = (end_row - start_row + 1) * 20

        image = Image.new("RGB", (width, height), color="white")
        draw = ImageDraw.Draw(image)

        # 绘制范围边框
        draw.rectangle([0, 0, width - 1, height - 1], outline="black", width=2)

        # 添加文本
        draw.text((10, 10), f"范围: {range_reference}", fill="black")

        # 保存到缓冲区
        buffer = io.BytesIO()
        image.save(buffer, format="PNG")
        buffer.seek(0)

        if output_path:
            image.save(output_path, format="PNG")

        return buffer

    def _get_cell_dimensions(
        self, worksheet: Worksheet, cell_reference: str
    ) -> tuple[int, int]:
        """
        获取单元格尺寸（像素）

        关键改进：正确处理合并单元格的宽度

        参数:
            worksheet: 工作表
            cell_reference: 单元格引用

        返回:
            (宽度, 高度)元组（像素）
        """
        col, row = self._parse_cell_reference(cell_reference)

        # 检查当前单元格是否属于合并单元格
        ws = worksheet._worksheet
        is_merged = False
        total_width = 0
        total_cols = 0

        # 遍历所有合并单元格，检查当前单元格是否在其中
        for merged_range in ws.merged_cells.ranges:
            # 检查当前单元格是否在合并范围内
            if (
                merged_range.min_col <= col <= merged_range.max_col
                and merged_range.min_row <= row <= merged_range.max_row
            ):
                # 计算合并单元格的宽度
                is_merged = True
                total_width = 0
                total_cols = 0
                for merged_col in range(merged_range.min_col, merged_range.max_col + 1):
                    col_letter = get_column_letter(merged_col)
                    col_width = ws.column_dimensions[col_letter].width or 8.43
                    total_width += col_width
                    total_cols += 1
                break

        # 获取列宽和行高
        if is_merged:
            # 使用合并单元格的宽度
            col_width = total_width
        else:
            # 使用单列宽度
            col_width = ws.column_dimensions[get_column_letter(col)].width or 8.43

        row_height = ws.row_dimensions[row].height or 15

        # 确保行高设置正确（避免Excel自动调整）
        # 如果没有显式设置行高，使用默认值
        if row_height == 15:
            # 使用标准行高，但不让Excel自动调整
            pass  # 保持默认

        # 转换为像素（近似转换）
        width_pixels = int(col_width * 7.5)  # 近似转换
        height_pixels = int(row_height * 1.33)  # 近似转换

        return width_pixels, height_pixels

    def _parse_cell_reference(self, cell_reference: str) -> tuple[int, int]:
        """
        解析单元格引用为列号和行号

        参数:
            cell_reference: 单元格引用 (例如: 'A1')

        返回:
            (列号, 行号)元组
        """
        col_str = "".join(filter(str.isalpha, cell_reference)).upper()
        row_str = "".join(filter(str.isdigit, cell_reference))

        col_num = column_index_from_string(col_str)
        row_num = int(row_str)

        return col_num, row_num

    def _insert_image_with_anchor(
        self,
        excel_image: OpenPyXLImage,
        worksheet: Worksheet,
        cell_reference: str,
        options: CellImageOptions | None = None,
        margin_px: int = 0,
    ) -> None:
        """
        根据锚点类型插入图片

        支持两种锚点类型：
        - "twoCell": TwoCellAnchor锚点（图片随单元格变化）
        - "oneCell": OneCellAnchor锚点（图片固定大小）

        功能说明：
        1. 根据anchor_type选择对应锚点类型
        2. 设置边距偏移，避免图片压边框
        3. TwoCellAnchor：图片锚定两个点，随单元格大小调整
        4. OneCellAnchor：图片锚定一个点，固定大小
        5. 仅使用标准属性，确保兼容性

        参数:
            excel_image: OpenPyXL图像对象
            worksheet: 目标工作表
            cell_reference: 目标单元格引用（如：A1）
            options: 图片选项（包含anchor_type参数）
            margin_px: 边距像素数
        """
        try:
            # 解析单元格引用（0-based）
            col, row = self._parse_cell_reference(cell_reference)
            col_num = col - 1  # 转换为0-based
            row_num = row - 1  # 转换为0-based

            # 获取图片尺寸
            img_width_px = excel_image.width if hasattr(excel_image, "width") else 100
            img_height_px = (
                excel_image.height if hasattr(excel_image, "height") else 100
            )

            # 像素转换为EMU (Excel Units)
            # 1像素 = 9525 EMU
            img_width_emu = img_width_px * 9525
            img_height_emu = img_height_px * 9525

            # 计算边距偏移（转换为EMU单位）
            margin_emu = margin_px * 9525

            # 获取锚点类型
            anchor_type = options.anchor_type if options else "oneCell"

            if anchor_type == "twoCell":
                # 使用TwoCellAnchor锚点
                from openpyxl.drawing.spreadsheet_drawing import (
                    TwoCellAnchor,
                    AnchorMarker,
                )

                # 起始锚点位置（包含边距）
                start_marker = AnchorMarker(
                    col=col_num,
                    colOff=margin_emu,  # 左边距
                    row=row_num,
                    rowOff=margin_emu,  # 上边距
                )

                # 结束锚点位置（起始位置+图片大小）
                end_col_off = img_width_emu + margin_emu
                end_row_off = img_height_emu + margin_emu
                end_marker = AnchorMarker(
                    col=col_num,
                    colOff=end_col_off,
                    row=row_num,
                    rowOff=end_row_off,
                )

                # 创建TwoCellAnchor锚点
                anchor = TwoCellAnchor(_from=start_marker, to=end_marker)

                # 设置锚定模式
                anchor.editAs = "twoCell"

            else:  # oneCell
                # 使用OneCellAnchor锚点
                from openpyxl.drawing.spreadsheet_drawing import (
                    OneCellAnchor,
                    AnchorMarker,
                )
                from openpyxl.drawing.xdr import XDRPositiveSize2D

                # 起始锚点位置（包含边距）
                start_marker = AnchorMarker(
                    col=col_num,
                    colOff=margin_emu,  # 左边距
                    row=row_num,
                    rowOff=margin_emu,  # 上边距
                )

                # 图片尺寸（仅图片本身，不包含边距）
                ext = XDRPositiveSize2D(
                    cx=img_width_emu,    # 图片宽度
                    cy=img_height_emu,   # 图片高度
                )

                # 创建OneCellAnchor锚点
                anchor = OneCellAnchor(_from=start_marker, ext=ext)

                # 设置锚定模式
                anchor.editAs = "oneCell"

            # 传递锚点给 add_image 方法
            worksheet._worksheet.add_image(excel_image, anchor=anchor)  # type: ignore[arg-type]

        except Exception as e:
            import logging

            logger = logging.getLogger(__name__)

            if anchor_type == "twoCell":
                logger.warning(f"TwoCellAnchor插入失败，使用备用方案: {e}")
            else:
                logger.warning(f"OneCellAnchor插入失败，使用备用方案: {e}")

            # 备用方案：使用字符串锚点
            try:
                worksheet._worksheet.add_image(excel_image, cell_reference)
            except Exception as e2:
                raise ValidationError(f"插入图片失败: {e2}")

    def _configure_image_anchoring_new(
        self,
        excel_image: OpenPyXLImage,
        worksheet: Worksheet,
        cell_reference: str,
        options: CellImageOptions | None = None,
        margin_px: int = 0,
    ) -> None:
        """
        锚点配置方法 - 根据锚点类型创建对应锚点

        支持两种锚点类型：
        - "twoCell": TwoCellAnchor锚点（图片随单元格变化）
        - "oneCell": OneCellAnchor锚点（图片固定大小）

        功能说明：
        1. 根据anchor_type创建对应锚点类型
        2. 设置正确的锚定模式
        3. TwoCellAnchor：图片随单元格移动和调整大小
           OneCellAnchor：图片固定大小，不随单元格变化
        4. 添加边距偏移，避免图片压边框

        参数:
            excel_image: OpenPyXL图像对象
            worksheet: 目标工作表
            cell_reference: 目标单元格引用（如：A1）
            options: 图片选项（包含anchor_type参数）
            margin_px: 边距像素数
        """
        try:
            from openpyxl.drawing.spreadsheet_drawing import (
                TwoCellAnchor,
                OneCellAnchor,
                AnchorMarker,
            )
            from openpyxl.drawing.xdr import XDRPositiveSize2D
            from openpyxl.utils import column_index_from_string

            # 获取单元格的列号和行号（0-based）
            col_str = "".join(filter(str.isalpha, cell_reference)).upper()
            row_str = "".join(filter(str.isdigit, cell_reference))
            col_num = column_index_from_string(col_str) - 1  # 转换为0-based
            row_num = int(row_str) - 1  # 转换为0-based

            # 获取图片的尺寸（EMU单位）
            img_width_px = excel_image.width if hasattr(excel_image, "width") else 100
            img_height_px = (
                excel_image.height if hasattr(excel_image, "height") else 100
            )

            # 像素转换为EMU (Excel Units)
            # 1像素 = 9525 EMU
            img_width_emu = img_width_px * 9525
            img_height_emu = img_height_px * 9525

            # 计算边距偏移（转换为EMU单位）
            margin_emu = margin_px * 9525

            # 获取锚点类型
            anchor_type = options.anchor_type if options else "oneCell"

            if anchor_type == "twoCell":
                # 创建TwoCellAnchor锚点
                # 起始锚点位置（包含边距）
                start_marker = AnchorMarker(
                    col=col_num,
                    colOff=margin_emu,  # 水平偏移
                    row=row_num,
                    rowOff=margin_emu,  # 垂直偏移
                )

                # 结束锚点位置
                end_col_off = img_width_emu + margin_emu
                end_row_off = img_height_emu + margin_emu
                end_marker = AnchorMarker(
                    col=col_num,
                    colOff=end_col_off,
                    row=row_num,
                    rowOff=end_row_off,
                )

                anchor = TwoCellAnchor(_from=start_marker, to=end_marker)

                # 设置锚定模式
                anchor.editAs = "twoCell"

            else:  # oneCell
                # 创建OneCellAnchor锚点
                start_marker = AnchorMarker(
                    col=col_num,
                    colOff=margin_emu,  # 水平偏移
                    row=row_num,
                    rowOff=margin_emu,  # 垂直偏移
                )

                # 图片尺寸（仅图片本身，不包含边距）
                ext = XDRPositiveSize2D(
                    cx=img_width_emu,    # 图片宽度
                    cy=img_height_emu,   # 图片高度
                )

                anchor = OneCellAnchor(_from=start_marker, ext=ext)

                # 设置锚定模式
                anchor.editAs = "oneCell"

            # 仅使用标准属性，确保兼容性
            # 将新锚点应用到图片
            excel_image.anchor = anchor

        except Exception as e:
            # 锚定配置失败，记录警告但不中断主流程
            import logging

            logger = logging.getLogger(__name__)
            logger.warning(f"配置图片锚点失败: {e}")

    def _configure_image_anchoring(
        self,
        excel_image: OpenPyXLImage,
        worksheet: Worksheet,
        cell_reference: str,
        options: CellImageOptions,
    ) -> None:
        """
        配置图像锚定选项（降级方案）

        参数:
            excel_image: OpenPyXL图像对象
            worksheet: 工作表
            cell_reference: 单元格引用
            options: 图像选项
        """
        try:
            from openpyxl.drawing.spreadsheet_drawing import (
                OneCellAnchor,
            )
            from openpyxl.drawing.xdr import XDRPositiveSize2D
            from openpyxl.drawing.spreadsheet_drawing import AnchorMarker
            from openpyxl.utils import column_index_from_string

            # 获取单元格的列号和行号（0-based）
            col_str = "".join(filter(str.isalpha, cell_reference)).upper()
            row_str = "".join(filter(str.isdigit, cell_reference))
            col_num = column_index_from_string(col_str) - 1  # 转换为0-based
            row_num = int(row_str) - 1  # 转换为0-based

            # 获取最新的图片对象（刚刚添加的）
            images = worksheet._worksheet._images  # type: ignore[attr-defined]
            if not images:
                return

            # 获取刚刚添加的图片
            latest_image = images[-1]

            # 检查锚点类型
            if isinstance(latest_image.anchor, str):
                # 字符串类型的锚点，需要重新创建
                marker = AnchorMarker(col=col_num, colOff=0, row=row_num, rowOff=0)
                # 使用默认尺寸创建OneCellAnchor
                ext = XDRPositiveSize2D(cx=14554200, cy=7543800)  # 使用默认尺寸
                anchor = OneCellAnchor(_from=marker, ext=ext)
                latest_image.anchor = anchor
            elif hasattr(latest_image.anchor, "_from"):
                # 更新现有锚点的位置
                latest_image.anchor._from.col = col_num
                latest_image.anchor._from.row = row_num

            # 设置锚定选项
            if hasattr(latest_image.anchor, "editAs"):
                if not options.move_with_cells and not options.resize_with_cells:
                    latest_image.anchor.editAs = "absolute"  # type: ignore[attr-defined]
                elif options.move_with_cells and not options.resize_with_cells:
                    latest_image.anchor.editAs = "oneCell"  # type: ignore[attr-defined]
                elif options.move_with_cells and options.resize_with_cells:
                    latest_image.anchor.editAs = "twoCell"  # type: ignore[attr-defined]
            elif hasattr(latest_image, "anchor") and hasattr(
                latest_image.anchor, "_from"
            ):
                # 对于OneCellAnchor，设置editAs属性
                latest_image.anchor.editAs = "oneCell"  # type: ignore[attr-defined]  # 默认设置为oneCell模式
        except Exception:
            # 如果锚定配置失败，不中断主流程
            pass

    def get_image_info(
        self, image_source: str | Path | bytes | io.BytesIO
    ) -> dict[str, Any]:
        """
        获取全面的图像信息

        参数:
            image_source: 图像源

        返回:
            图像信息字典
        """
        try:
            image = self.image_processor.load_image(image_source)
            props = self.image_processor.get_image_properties(image)

            return {
                "width": props.width,
                "height": props.height,
                "format": props.format.value,
                "size_bytes": props.size_bytes,
                "size_mb": props.size_bytes / (1024 * 1024),
                "dpi": props.dpi,
                "mode": props.mode,
                "is_valid_for_excel": self.image_processor.validate_image_for_excel(
                    image
                ),
            }

        except Exception as e:
            return {"error": str(e), "is_valid": False}

    def batch_optimize_images(
        self,
        image_sources: list[Any],
        max_width: int = 800,
        max_height: int = 600,
        quality: int = 80,
    ) -> list[io.BytesIO | None]:
        """
        批量优化多个图像以适配Excel

        参数:
            image_sources: 图像源列表
            max_width: 最大宽度
            max_height: 最大高度
            quality: JPEG质量

        返回:
            优化后的图像缓冲区列表
        """
        optimized_images: list[io.BytesIO | None] = []

        for image_source in image_sources:
            try:
                # 加载图像
                image = self.image_processor.load_image(image_source)

                # 优化
                optimized_buffer = self.image_processor.optimize_for_excel(
                    image, max_width, max_height, quality
                )

                optimized_images.append(optimized_buffer)

            except Exception as e:
                import logging

                logger = logging.getLogger(__name__)
                logger.warning(f"警告: 优化图像失败: {e}")
                optimized_images.append(None)

        return optimized_images
