"""同步日志管理模块。

提供同步操作日志记录和查询功能，追踪每次数据同步的详细信息。
设计理念：日志只插入不更新，无需主键 ID。
"""

from datetime import datetime
from typing import Optional, Dict, Any, List
import pandas as pd
from dataclasses import dataclass

from src.data.storage import Storage


@dataclass
class SyncLogEntry:
    """同步日志条目。

    Attributes:
        table_name: 同步的表名
        sync_type: 同步类型（full/incremental/quarterly/daily 等）
        start_time: 同步开始时间
        end_time: 同步结束时间
        status: 同步状态（success/failed/partial/running）
        records_before: 同步前记录数
        records_after: 同步后记录数
        records_inserted: 插入的记录数
        records_updated: 更新的记录数
        records_deleted: 删除的记录数
        date_range_start: 数据日期范围起始
        date_range_end: 数据日期范围结束
        error_message: 错误信息（如果有）
        metadata: 额外元数据（JSON 格式）
    """

    table_name: str
    sync_type: str
    start_time: datetime
    end_time: Optional[datetime] = None
    status: str = "running"
    records_before: int = 0
    records_after: int = 0
    records_inserted: int = 0
    records_updated: int = 0
    records_deleted: int = 0
    date_range_start: Optional[str] = None
    date_range_end: Optional[str] = None
    error_message: Optional[str] = None
    metadata: Optional[str] = None


class SyncLogManager:
    """同步日志管理器。

    管理同步日志表的创建、记录插入和查询。
    设计原则：日志只插入，不更新，无需主键。

    使用方式:
        # 记录一次同步操作（开始和结束分别记录）
        log_manager = SyncLogManager()
        log_manager.start_sync("daily", "incremental")  # 记录开始
        try:
            # 执行同步...
            log_manager.complete_sync("daily", "success", records_inserted=1000)  # 记录完成
        except Exception as e:
            log_manager.complete_sync("daily", "failed", error_message=str(e))  # 记录失败

        # 查询同步历史
        logs = log_manager.get_sync_history("daily", limit=10)
    """

    TABLE_NAME = "_sync_logs"

    def __init__(self, storage: Optional[Storage] = None):
        """初始化日志管理器。

        Args:
            storage: Storage 实例，如果为 None 则创建新实例
        """
        self.storage = storage or Storage(read_only=False)
        self._ensure_table_exists()

    def _ensure_table_exists(self) -> None:
        """确保日志表存在。"""
        create_sql = f"""
        CREATE TABLE IF NOT EXISTS {self.TABLE_NAME} (
            table_name VARCHAR(64) NOT NULL,
            sync_type VARCHAR(32) NOT NULL,
            start_time TIMESTAMP NOT NULL,
            end_time TIMESTAMP,
            status VARCHAR(16) DEFAULT 'running',
            records_before INTEGER DEFAULT 0,
            records_after INTEGER DEFAULT 0,
            records_inserted INTEGER DEFAULT 0,
            records_updated INTEGER DEFAULT 0,
            records_deleted INTEGER DEFAULT 0,
            date_range_start VARCHAR(8),
            date_range_end VARCHAR(8),
            error_message TEXT,
            metadata TEXT,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
        """

        # 创建索引
        index_sql = f"""
        CREATE INDEX IF NOT EXISTS idx_sync_logs_table_time 
        ON {self.TABLE_NAME}(table_name, start_time DESC);
        
        CREATE INDEX IF NOT EXISTS idx_sync_logs_status 
        ON {self.TABLE_NAME}(status);
        
        CREATE INDEX IF NOT EXISTS idx_sync_logs_type_time
        ON {self.TABLE_NAME}(sync_type, start_time DESC);
        """

        try:
            self.storage._connection.execute(create_sql)
            self.storage._connection.execute(index_sql)
        except Exception as e:
            print(f"[SyncLogManager] Error creating log table: {e}")
            raise

    def start_sync(
        self,
        table_name: str,
        sync_type: str,
        date_range_start: Optional[str] = None,
        date_range_end: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None,
    ) -> None:
        """记录同步开始。

        Args:
            table_name: 同步的表名
            sync_type: 同步类型（full/incremental/quarterly 等）
            date_range_start: 数据日期范围起始
            date_range_end: 数据日期范围结束
            metadata: 额外元数据字典
        """
        entry = SyncLogEntry(
            table_name=table_name,
            sync_type=sync_type,
            start_time=datetime.now(),
            status="running",
            records_before=0,  # 不统计记录数，避免额外查询
            date_range_start=date_range_start,
            date_range_end=date_range_end,
            metadata=str(metadata) if metadata else None,
        )

        try:
            self.storage._connection.execute(
                f"""
                INSERT INTO {self.TABLE_NAME} (
                    table_name, sync_type, start_time, status,
                    records_before, date_range_start, date_range_end, metadata
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            """,
                (
                    entry.table_name,
                    entry.sync_type,
                    entry.start_time,
                    entry.status,
                    entry.records_before,
                    entry.date_range_start,
                    entry.date_range_end,
                    entry.metadata,
                ),
            )
        except Exception as e:
            print(f"[SyncLogManager] Error logging sync start: {e}")

    def complete_sync(
        self,
        table_name: str,
        status: str = "success",
        records_inserted: int = 0,
        records_updated: int = 0,
        records_deleted: int = 0,
        error_message: Optional[str] = None,
        sync_type: str = "incremental",
        date_range_start: Optional[str] = None,
        date_range_end: Optional[str] = None,
        metadata: Optional[Dict[str, Any]] = None,
    ) -> None:
        """记录同步完成。

        作为一条新的日志记录插入，不更新之前的记录。

        Args:
            table_name: 同步的表名
            status: 同步状态（success/failed/partial）
            records_inserted: 插入的记录数
            records_updated: 更新的记录数
            records_deleted: 删除的记录数
            error_message: 错误信息（如果失败）
            sync_type: 同步类型
            date_range_start: 日期范围起始
            date_range_end: 日期范围结束
            metadata: 元数据
        """
        entry = SyncLogEntry(
            table_name=table_name,
            sync_type=sync_type,
            start_time=datetime.now(),
            end_time=datetime.now(),
            status=status,
            records_inserted=records_inserted,
            records_updated=records_updated,
            records_deleted=records_deleted,
            date_range_start=date_range_start,
            date_range_end=date_range_end,
            error_message=error_message,
            metadata=str(metadata) if metadata else None,
        )

        try:
            self.storage._connection.execute(
                f"""
                INSERT INTO {self.TABLE_NAME} (
                    table_name, sync_type, start_time, end_time, status,
                    records_inserted, records_updated, records_deleted,
                    date_range_start, date_range_end, error_message, metadata
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            """,
                (
                    entry.table_name,
                    entry.sync_type,
                    entry.start_time,
                    entry.end_time,
                    entry.status,
                    entry.records_inserted,
                    entry.records_updated,
                    entry.records_deleted,
                    entry.date_range_start,
                    entry.date_range_end,
                    entry.error_message,
                    entry.metadata,
                ),
            )
        except Exception as e:
            print(f"[SyncLogManager] Error logging sync complete: {e}")

    def get_sync_history(
        self,
        table_name: Optional[str] = None,
        status: Optional[str] = None,
        limit: int = 100,
        offset: int = 0,
    ) -> pd.DataFrame:
        """查询同步历史。

        Args:
            table_name: 按表名过滤
            status: 按状态过滤
            limit: 返回记录数限制
            offset: 分页偏移

        Returns:
            同步历史 DataFrame
        """
        conditions = []
        params = []

        if table_name:
            conditions.append("table_name = ?")
            params.append(table_name)

        if status:
            conditions.append("status = ?")
            params.append(status)

        where_clause = f"WHERE {' AND '.join(conditions)}" if conditions else ""

        query = f"""
            SELECT * FROM {self.TABLE_NAME}
            {where_clause}
            ORDER BY start_time DESC
            LIMIT ? OFFSET ?
        """
        params.extend([limit, offset])

        try:
            return self.storage._connection.execute(query, params).fetchdf()
        except Exception as e:
            print(f"[SyncLogManager] Error querying sync history: {e}")
            return pd.DataFrame()

    def get_last_sync(
        self, table_name: str, status: Optional[str] = "success"
    ) -> Optional[Dict[str, Any]]:
        """获取指定表的最近一次同步记录。

        Args:
            table_name: 表名
            status: 状态过滤，None 表示不限制

        Returns:
            同步记录字典，如果没有则返回 None
        """
        conditions = ["table_name = ?"]
        params = [table_name]

        if status:
            conditions.append("status = ?")
            params.append(status)

        query = f"""
            SELECT * FROM {self.TABLE_NAME}
            WHERE {" AND ".join(conditions)}
            ORDER BY start_time DESC
            LIMIT 1
        """

        try:
            df = self.storage._connection.execute(query, params).fetchdf()
            if not df.empty:
                return df.iloc[0].to_dict()
            return None
        except Exception as e:
            print(f"[SyncLogManager] Error getting last sync: {e}")
            return None

    def get_sync_summary(
        self, table_name: Optional[str] = None, days: int = 30
    ) -> Dict[str, Any]:
        """获取同步汇总统计。

        Args:
            table_name: 按表名过滤
            days: 最近多少天的统计

        Returns:
            汇总统计字典
        """
        conditions = [f"start_time >= CURRENT_DATE - INTERVAL '{days} days'"]
        params = []

        if table_name:
            conditions.append("table_name = ?")
            params.append(table_name)

        where_clause = f"WHERE {' AND '.join(conditions)}"

        query = f"""
            SELECT 
                COUNT(*) as total_syncs,
                COUNT(CASE WHEN status = 'success' THEN 1 END) as success_count,
                COUNT(CASE WHEN status = 'failed' THEN 1 END) as failed_count,
                COUNT(CASE WHEN status = 'partial' THEN 1 END) as partial_count,
                SUM(records_inserted) as total_inserted,
                SUM(records_updated) as total_updated,
                SUM(records_deleted) as total_deleted
            FROM {self.TABLE_NAME}
            {where_clause}
        """

        try:
            df = self.storage._connection.execute(query, params).fetchdf()
            if not df.empty:
                return {
                    "total_syncs": int(df.iloc[0]["total_syncs"]),
                    "success_count": int(df.iloc[0]["success_count"]),
                    "failed_count": int(df.iloc[0]["failed_count"]),
                    "partial_count": int(df.iloc[0]["partial_count"]),
                    "total_inserted": int(df.iloc[0]["total_inserted"] or 0),
                    "total_updated": int(df.iloc[0]["total_updated"] or 0),
                    "total_deleted": int(df.iloc[0]["total_deleted"] or 0),
                }
        except Exception as e:
            print(f"[SyncLogManager] Error getting sync summary: {e}")

        return {
            "total_syncs": 0,
            "success_count": 0,
            "failed_count": 0,
            "partial_count": 0,
            "total_inserted": 0,
            "total_updated": 0,
            "total_deleted": 0,
        }


# 便捷函数


def log_sync_start(
    table_name: str,
    sync_type: str,
    date_range_start: Optional[str] = None,
    date_range_end: Optional[str] = None,
    metadata: Optional[Dict[str, Any]] = None,
) -> None:
    """便捷函数：记录同步开始。

    Args:
        table_name: 表名
        sync_type: 同步类型
        date_range_start: 日期范围起始
        date_range_end: 日期范围结束
        metadata: 元数据
    """
    manager = SyncLogManager()
    manager.start_sync(
        table_name, sync_type, date_range_start, date_range_end, metadata
    )


def log_sync_complete(
    table_name: str,
    status: str = "success",
    records_inserted: int = 0,
    records_updated: int = 0,
    records_deleted: int = 0,
    error_message: Optional[str] = None,
    sync_type: str = "incremental",
) -> None:
    """便捷函数：记录同步完成。

    Args:
        table_name: 表名
        status: 状态
        records_inserted: 插入数
        records_updated: 更新数
        records_deleted: 删除数
        error_message: 错误信息
        sync_type: 同步类型
    """
    manager = SyncLogManager()
    manager.complete_sync(
        table_name,
        status,
        records_inserted,
        records_updated,
        records_deleted,
        error_message,
        sync_type,
    )
