"""
CSV解析工具模块

提供CSV文件的读写功能，支持：
- 迭代器模式逐行读取
- 自定义字段映射
- 字典或对象列表写入
- 自动处理逗号和引号

Example:
    >>> parser = CsvParser("data.csv", ["name", "age"])
    >>> for row in parser:
    ...     print(row["name"])
    >>> parser.close()
"""
import csv
import logging
from typing import List, Dict, Any, Optional, Tuple, Iterator, IO

logger = logging.getLogger(__name__)


class CsvParser:
    """
    CSV解析器类

    使用迭代器模式逐行读取CSV文件，并将每行映射为字典。

    Attributes:
        file_path: CSV文件路径
        field_list: 字段名列表
        encoding: 文件编码
        file_io: 文件句柄
        file_reader: CSV读取器

    Example:
        >>> fields = ["id", "name", "value"]
        >>> parser = CsvParser("data.csv", fields)
        >>> for row in parser:
        ...     print(row)
        >>> parser.close()

        # 使用上下文管理器
        >>> with CsvParser("data.csv", fields) as parser:
        ...     for row in parser:
        ...         print(row)
    """

    def __init__(
        self,
        file_path: str,
        field_list: List[str],
        encoding: str = "utf-8"
    ):
        """
        初始化CSV解析器

        Args:
            file_path: CSV文件路径
            field_list: 字段名列表，用于将每行数据映射为字典
            encoding: 文件编码，默认utf-8
        """
        self.file_path: str = file_path
        self.field_list: List[str] = field_list
        self.encoding: str = encoding
        self.file_io: Optional[IO[str]] = None
        self.file_reader: Optional[Iterator[List[str]]] = None

    def __iter__(self) -> "CsvParser":
        """
        初始化迭代器

        打开CSV文件并创建读取器。

        Returns:
            CsvParser实例自身
        """
        self.file_io = open(self.file_path, "r", encoding=self.encoding)
        self.file_reader = csv.reader(self.file_io)
        return self

    def __next__(self) -> Dict[str, str]:
        """
        获取下一行数据

        Returns:
            字段名到字段值的字典

        Raises:
            StopIteration: 文件读取完毕时抛出
        """
        line = next(self.file_reader)
        line_dict = dict(zip(self.field_list, line))
        return line_dict

    def close(self) -> None:
        """
        关闭文件句柄

        释放文件资源。
        """
        if self.file_io:
            self.file_io.close()
            self.file_io = None
            self.file_reader = None

    def __enter__(self) -> "CsvParser":
        """
        上下文管理器入口

        Returns:
            CsvParser实例自身
        """
        return self.__iter__()

    def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
        """
        上下文管理器退出

        Args:
            exc_type: 异常类型
            exc_val: 异常值
            exc_tb: 异常追溯
        """
        self.close()

    @staticmethod
    def _escape_csv_value(value: str) -> str:
        """
        转义CSV字段值

        处理包含逗号或引号的字段值。

        Args:
            value: 原始字段值

        Returns:
            转义后的字段值
        """
        value = str(value).strip()
        if "," in value or '"' in value:
            # 转义内部引号
            value = value.replace('"', '""')
            value = f'"{value}"'
        return value

    @staticmethod
    def write_csv(
        data_list: List[Any],
        csv_file_path: str,
        write_title: bool = True
    ) -> Tuple[bool, str]:
        """
        写入数据到CSV文件

        数据列表中的元素可以是字典或对象（会自动转换为__dict__）。

        Args:
            data_list: 数据列表
            csv_file_path: 输出文件路径
            write_title: 是否写入标题行

        Returns:
            元组 (是否成功, 消息)

        Example:
            >>> data = [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]
            >>> success, msg = CsvParser.write_csv(data, "output.csv")
        """
        if data_list is None or len(data_list) == 0:
            msg = "No data to write!"
            logger.warning(msg)
            return False, msg

        # 转换对象为字典
        converted_data: List[Dict[str, Any]] = []
        for data in data_list:
            if not isinstance(data, dict):
                converted_data.append(data.__dict__)
            else:
                converted_data.append(data)

        with open(csv_file_path, "w", encoding="utf-8", newline="") as file_writer:
            # 获取字段列表
            field_list = list(converted_data[0].keys())

            # 写入标题行
            if write_title:
                title_values = [CsvParser._escape_csv_value(key) for key in field_list]
                file_writer.write(",".join(title_values) + "\n")

            # 写入数据内容
            for line in converted_data:
                line_values = [
                    CsvParser._escape_csv_value(line.get(key, ""))
                    for key in field_list
                ]
                file_writer.write(",".join(line_values) + "\n")

        msg = f"Successfully wrote file: {csv_file_path}"
        logger.info(msg)
        return True, msg


if __name__ == "__main__":
    test_data = [
        {"name": "henry", "job": "dev"},
        {"name": "henry2", "job": "dev2"}
    ]
    CsvParser.write_csv(test_data, "./test_attach.csv", write_title=True)
