"""
导出服务

提供统计分析数据的导出功能，支持多种格式：
- JSON格式导出
- CSV格式导出
- PDF格式导出（可选）
- Excel格式导出（可选）
"""

import sys
import os
import json
import csv
from datetime import datetime
from typing import Dict, List, Optional, Any
from io import StringIO, BytesIO

# 将项目根目录添加到 sys.path
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
if project_root not in sys.path:
    sys.path.insert(0, project_root)

from src.core.logger import get_logger
from src.core.config import Config


class ExportService:
    """
    导出服务

    提供统计分析数据的多格式导出功能。
    """

    def __init__(
        self,
        config: Config,
        logger=None
    ):
        """
        初始化导出服务

        Args:
            config: 配置对象
            logger: 日志记录器实例
        """
        self.config = config
        self.logger = logger or get_logger()
        
        # 导出配置
        self.export_dir = self.config.get("export.directory", "./data/exports")
        os.makedirs(self.export_dir, exist_ok=True)

    # -------------------------------------------------------------------------
    # JSON导出
    # -------------------------------------------------------------------------

    def export_to_json(
        self,
        data: Dict[str, Any],
        filename: Optional[str] = None,
        pretty: bool = True
    ) -> Dict[str, Any]:
        """
        导出数据为JSON格式

        Args:
            data: 要导出的数据
            filename: 文件名，为None则返回JSON字符串
            pretty: 是否格式化输出

        Returns:
            Dict: 导出结果信息

        Raises:
            Exception: 导出过程出错
        """
        try:
            self.logger.info(f"开始导出JSON格式数据...")

            # 生成JSON字符串
            json_str = json.dumps(
                data,
                ensure_ascii=False,
                indent=2 if pretty else None,
                default=str
            )

            # 如果指定文件名，保存到文件
            if filename:
                filepath = os.path.join(self.export_dir, filename)
                os.makedirs(os.path.dirname(filepath), exist_ok=True)

                with open(filepath, 'w', encoding='utf-8') as f:
                    f.write(json_str)

                file_size = os.path.getsize(filepath)
                self.logger.info(f"JSON数据已导出到文件: {filepath} ({file_size}字节)")

                return {
                    'status': 'success',
                    'format': 'json',
                    'filename': filename,
                    'filepath': filepath,
                    'file_size': file_size,
                    'records_count': len(data) if isinstance(data, list) else 1,
                    'timestamp': datetime.now().isoformat()
                }
            else:
                self.logger.info("JSON数据已生成")
                return {
                    'status': 'success',
                    'format': 'json',
                    'data': json_str,
                    'data_size': len(json_str),
                    'timestamp': datetime.now().isoformat()
                }

        except Exception as e:
            self.logger.error(f"JSON导出失败: {e}")
            raise

    # -------------------------------------------------------------------------
    # CSV导出
    # -------------------------------------------------------------------------

    def export_to_csv(
        self,
        data: List[Dict[str, Any]],
        filename: Optional[str] = None,
        include_headers: bool = True
    ) -> Dict[str, Any]:
        """
        导出数据为CSV格式

        Args:
            data: 要导出的数据列表
            filename: 文件名，为None则返回CSV字符串
            include_headers: 是否包含表头

        Returns:
            Dict: 导出结果信息

        Raises:
            Exception: 导出过程出错
        """
        try:
            self.logger.info(f"开始导出CSV格式数据...")

            if not data:
                raise ValueError("导出数据不能为空")

            # 获取所有列名
            fieldnames = set()
            for row in data:
                fieldnames.update(row.keys())
            fieldnames = sorted(list(fieldnames))

            # 生成CSV
            csv_buffer = StringIO()
            writer = csv.DictWriter(
                csv_buffer,
                fieldnames=fieldnames,
                extrasaction='ignore',
                quoting=csv.QUOTE_MINIMAL
            )

            if include_headers:
                writer.writeheader()

            writer.writerows(data)
            csv_str = csv_buffer.getvalue()

            # 如果指定文件名，保存到文件
            if filename:
                filepath = os.path.join(self.export_dir, filename)
                os.makedirs(os.path.dirname(filepath), exist_ok=True)

                with open(filepath, 'w', newline='', encoding='utf-8-sig') as f:
                    f.write(csv_str)

                file_size = os.path.getsize(filepath)
                self.logger.info(f"CSV数据已导出到文件: {filepath} ({file_size}字节)")

                return {
                    'status': 'success',
                    'format': 'csv',
                    'filename': filename,
                    'filepath': filepath,
                    'file_size': file_size,
                    'records_count': len(data),
                    'columns_count': len(fieldnames),
                    'timestamp': datetime.now().isoformat()
                }
            else:
                self.logger.info("CSV数据已生成")
                return {
                    'status': 'success',
                    'format': 'csv',
                    'data': csv_str,
                    'data_size': len(csv_str),
                    'records_count': len(data),
                    'columns_count': len(fieldnames),
                    'timestamp': datetime.now().isoformat()
                }

        except Exception as e:
            self.logger.error(f"CSV导出失败: {e}")
            raise

    # -------------------------------------------------------------------------
    # 批量导出功能
    # -------------------------------------------------------------------------

    def export_overall_statistics(
        self,
        data: Dict[str, Any],
        formats: Optional[List[str]] = None,
        base_filename: str = "statistics"
    ) -> Dict[str, Any]:
        """
        导出整体统计数据

        Args:
            data: 统计数据
            formats: 导出格式列表 ['json', 'csv']
            base_filename: 基础文件名

        Returns:
            Dict: 导出结果

        Raises:
            Exception: 导出过程出错
        """
        try:
            formats = formats or ['json', 'csv']
            results = {}

            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')

            # JSON导出
            if 'json' in formats:
                json_filename = f"{base_filename}_{timestamp}.json"
                results['json'] = self.export_to_json(data, json_filename)

            # CSV导出（转换格式）
            if 'csv' in formats:
                # 为CSV导出转换数据
                csv_data = self._convert_stats_to_csv_format(data)
                csv_filename = f"{base_filename}_{timestamp}.csv"
                results['csv'] = self.export_to_csv(csv_data, csv_filename)

            self.logger.info(f"统计数据导出完成: {list(results.keys())}")
            return {
                'status': 'success',
                'base_filename': base_filename,
                'timestamp': timestamp,
                'formats': list(results.keys()),
                'exports': results
            }

        except Exception as e:
            self.logger.error(f"统计数据导出失败: {e}")
            raise

    def export_category_statistics(
        self,
        data: Dict[str, Any],
        formats: Optional[List[str]] = None,
        base_filename: str = "category_statistics"
    ) -> Dict[str, Any]:
        """
        导出分类统计数据

        Args:
            data: 分类统计数据
            formats: 导出格式列表
            base_filename: 基础文件名

        Returns:
            Dict: 导出结果
        """
        try:
            formats = formats or ['json', 'csv']
            results = {}

            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')

            # JSON导出
            if 'json' in formats:
                json_filename = f"{base_filename}_{timestamp}.json"
                results['json'] = self.export_to_json(data, json_filename)

            # CSV导出
            if 'csv' in formats:
                csv_data = data.get('categories', [])
                csv_filename = f"{base_filename}_{timestamp}.csv"
                results['csv'] = self.export_to_csv(csv_data, csv_filename)

            self.logger.info(f"分类统计数据导出完成")
            return {
                'status': 'success',
                'base_filename': base_filename,
                'timestamp': timestamp,
                'exports': results
            }

        except Exception as e:
            self.logger.error(f"分类统计数据导出失败: {e}")
            raise

    def export_quality_metrics(
        self,
        data: Dict[str, Any],
        formats: Optional[List[str]] = None,
        base_filename: str = "quality_metrics"
    ) -> Dict[str, Any]:
        """
        导出质量评估数据

        Args:
            data: 质量评估数据
            formats: 导出格式列表
            base_filename: 基础文件名

        Returns:
            Dict: 导出结果
        """
        try:
            formats = formats or ['json', 'csv']
            results = {}

            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')

            # JSON导出
            if 'json' in formats:
                json_filename = f"{base_filename}_{timestamp}.json"
                results['json'] = self.export_to_json(data, json_filename)

            # CSV导出
            if 'csv' in formats:
                csv_data = data.get('metrics', [])
                csv_filename = f"{base_filename}_{timestamp}.csv"
                results['csv'] = self.export_to_csv(csv_data, csv_filename)

            self.logger.info(f"质量评估数据导出完成")
            return {
                'status': 'success',
                'base_filename': base_filename,
                'timestamp': timestamp,
                'exports': results
            }

        except Exception as e:
            self.logger.error(f"质量评估数据导出失败: {e}")
            raise

    def export_time_series(
        self,
        data: Dict[str, Any],
        formats: Optional[List[str]] = None,
        base_filename: str = "time_series"
    ) -> Dict[str, Any]:
        """
        导出时间序列数据

        Args:
            data: 时间序列数据
            formats: 导出格式列表
            base_filename: 基础文件名

        Returns:
            Dict: 导出结果
        """
        try:
            formats = formats or ['json', 'csv']
            results = {}

            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')

            # JSON导出
            if 'json' in formats:
                json_filename = f"{base_filename}_{timestamp}.json"
                results['json'] = self.export_to_json(data, json_filename)

            # CSV导出
            if 'csv' in formats:
                csv_data = data.get('time_series', [])
                csv_filename = f"{base_filename}_{timestamp}.csv"
                results['csv'] = self.export_to_csv(csv_data, csv_filename)

            self.logger.info(f"时间序列数据导出完成")
            return {
                'status': 'success',
                'base_filename': base_filename,
                'timestamp': timestamp,
                'exports': results
            }

        except Exception as e:
            self.logger.error(f"时间序列数据导出失败: {e}")
            raise

    # -------------------------------------------------------------------------
    # 辅助方法
    # -------------------------------------------------------------------------

    def _convert_stats_to_csv_format(self, data: Dict[str, Any]) -> List[Dict[str, Any]]:
        """
        将统计数据转换为CSV格式

        Args:
            data: 统计数据字典

        Returns:
            List: CSV格式的数据列表
        """
        try:
            csv_data = []

            # 将主要统计指标转换为行
            for key, value in data.items():
                if not isinstance(value, (dict, list)):
                    csv_data.append({
                        'metric': key,
                        'value': value
                    })

            return csv_data

        except Exception as e:
            self.logger.warning(f"数据格式转换失败: {e}")
            return []

    def list_export_files(self) -> Dict[str, Any]:
        """
        列出所有导出的文件

        Returns:
            Dict: 导出文件列表
        """
        try:
            files = []
            
            if os.path.exists(self.export_dir):
                for filename in os.listdir(self.export_dir):
                    filepath = os.path.join(self.export_dir, filename)
                    if os.path.isfile(filepath):
                        file_size = os.path.getsize(filepath)
                        file_mtime = os.path.getmtime(filepath)
                        modified_time = datetime.fromtimestamp(file_mtime).isoformat()

                        files.append({
                            'filename': filename,
                            'filepath': filepath,
                            'size': file_size,
                            'modified_time': modified_time
                        })

            # 按修改时间排序
            files.sort(key=lambda x: x['modified_time'], reverse=True)

            return {
                'status': 'success',
                'export_directory': self.export_dir,
                'total_files': len(files),
                'files': files
            }

        except Exception as e:
            self.logger.error(f"获取导出文件列表失败: {e}")
            raise

    def delete_export_file(self, filename: str) -> Dict[str, Any]:
        """
        删除导出的文件

        Args:
            filename: 要删除的文件名

        Returns:
            Dict: 删除结果

        Raises:
            Exception: 删除过程出错
        """
        try:
            filepath = os.path.join(self.export_dir, filename)

            # 安全检查：确保文件在导出目录内
            if not os.path.abspath(filepath).startswith(os.path.abspath(self.export_dir)):
                raise ValueError("无效的文件路径")

            if not os.path.exists(filepath):
                raise FileNotFoundError(f"文件不存在: {filename}")

            os.remove(filepath)
            self.logger.info(f"导出文件已删除: {filename}")

            return {
                'status': 'success',
                'filename': filename,
                'message': '文件已成功删除'
            }

        except Exception as e:
            self.logger.error(f"删除导出文件失败: {e}")
            raise

    def cleanup_old_exports(self, days: int = 30) -> Dict[str, Any]:
        """
        清理旧的导出文件

        Args:
            days: 保留多少天以内的文件

        Returns:
            Dict: 清理结果
        """
        try:
            deleted_count = 0
            deleted_size = 0
            cutoff_time = datetime.now().timestamp() - (days * 24 * 3600)

            if os.path.exists(self.export_dir):
                for filename in os.listdir(self.export_dir):
                    filepath = os.path.join(self.export_dir, filename)
                    if os.path.isfile(filepath):
                        file_mtime = os.path.getmtime(filepath)
                        if file_mtime < cutoff_time:
                            file_size = os.path.getsize(filepath)
                            os.remove(filepath)
                            deleted_count += 1
                            deleted_size += file_size

            self.logger.info(f"导出文件清理完成: 删除{deleted_count}个文件，释放{deleted_size}字节")

            return {
                'status': 'success',
                'deleted_count': deleted_count,
                'deleted_size': deleted_size,
                'retention_days': days,
                'timestamp': datetime.now().isoformat()
            }

        except Exception as e:
            self.logger.error(f"清理导出文件失败: {e}")
            raise

