"""
远程数据同步服务
将本地完成的录音同步到远程 PostgreSQL 数据库
"""
import os
import time
import threading
from sqlalchemy import create_engine, inspect as sqlalchemy_inspect, text
from src.clients import db
from src.models import Recording
import logging

logger = logging.getLogger(__name__)

# 配置远程数据库连接
REMOTE_DB_URI = os.environ.get('REMOTE_DB_URI', 'postgresql://postgres:password@172.18.30.122:5433/planner')
# 同步间隔（秒），默认 5 分钟
SYNC_INTERVAL = int(os.environ.get('SYNC_INTERVAL', 300))


def resolve_remote_recording_table_name(remote_engine):
    """
    解析远程录音表名（支持单复数变体）
    
    Args:
        remote_engine: SQLAlchemy 引擎实例
    
    Returns:
        str: 远程表名
    
    Raises:
        RuntimeError: 如果找不到对应的表
    """
    candidate_table_names = []
    local_table_name = Recording.__table__.name

    for table_name in [local_table_name, f"{local_table_name}s", "recording", "recordings"]:
        if table_name not in candidate_table_names:
            candidate_table_names.append(table_name)

    inspector = sqlalchemy_inspect(remote_engine)
    for table_name in candidate_table_names:
        if inspector.has_table(table_name):
            return table_name

    raise RuntimeError(
        "远程数据库中未找到录音表，已尝试: "
        + ", ".join(candidate_table_names)
    )


def sync_completed_recordings_to_remote(app):
    """
    后台任务：将本地 COMPLETED 状态的录音同步到远程 PostgreSQL 数据库。
    增量同步：只推送 ID 不在远程数据库中的记录。
    
    Args:
        app: Flask 应用实例
    """
    app.logger.info(f"启动远程数据同步服务，目标: {REMOTE_DB_URI}，间隔: {SYNC_INTERVAL}秒")
    
    while True:
        try:
            # 使用应用上下文访问本地数据库
            with app.app_context():
                # 1. 获取本地所有 COMPLETED 的录音
                local_completed_recordings = Recording.query.filter_by(status='COMPLETED').all()
                
                if not local_completed_recordings:
                    app.logger.debug("本地没有 COMPLETED 的录音，跳过同步。")
                    time.sleep(SYNC_INTERVAL)
                    continue

                local_map = {r.id: r for r in local_completed_recordings}
                local_ids = set(local_map.keys())

                # 2. 连接远程 PostgreSQL 数据库
                remote_engine = create_engine(REMOTE_DB_URI)
                remote_table_name = resolve_remote_recording_table_name(remote_engine)
                
                with remote_engine.connect() as remote_conn:
                    # 3. 查询远程数据库已存在的 ID
                    result = remote_conn.execute(text(f"SELECT id FROM {remote_table_name}"))
                    remote_ids = set(row[0] for row in result)
                    
                    # 4. 计算增量（本地有但远程没有的 ID）
                    ids_to_sync = local_ids - remote_ids
                    
                    if not ids_to_sync:
                        app.logger.debug("远程数据库已是最新，无需同步。")
                    else:
                        app.logger.info(f"发现 {len(ids_to_sync)} 条新记录需要同步到远程数据库。")
                        
                        # 5. 准备插入数据
                        records_to_insert = []
                        for rid in ids_to_sync:
                            rec = local_map[rid]
                            
                            # 构建字典，确保字段与远程数据库列名一致
                            record_dict = {
                                'id': rec.id,
                                'user_id': rec.user_id,
                                'title': rec.title,
                                'participants': rec.participants,
                                'notes': rec.notes,
                                'transcription': rec.transcription,
                                'summary': rec.summary,
                                'status': rec.status,
                                'audio_path': rec.audio_path,
                                'created_at': rec.created_at,
                                'meeting_date': rec.meeting_date,
                                'file_size': rec.file_size,
                                'original_filename': rec.original_filename,
                                'is_inbox': rec.is_inbox,
                                'is_highlighted': rec.is_highlighted,
                                'mime_type': rec.mime_type,
                                'completed_at': rec.completed_at,
                                'processing_time_seconds': rec.processing_time_seconds,
                                'processing_source': rec.processing_source,
                                'error_message': rec.error_message,
                                'is_sync': 0
                            }
                            records_to_insert.append(record_dict)
                        
                        # 6. 执行批量插入
                        if records_to_insert:
                            keys = list(records_to_insert[0].keys())
                            columns = ", ".join(keys)
                            placeholders = ", ".join([f":{key}" for key in keys])
                            
                            insert_sql = text(
                                f"INSERT INTO {remote_table_name} ({columns}) VALUES ({placeholders})"
                            )
                            
                            remote_conn.execute(insert_sql, records_to_insert)
                            remote_conn.commit()
                            
                            app.logger.info(f"成功同步 {len(records_to_insert)} 条记录到远程 PostgreSQL。")

        except Exception as e:
            app.logger.error(f"远程同步过程中发生错误: {str(e)}")
        
        # 休眠指定时间
        time.sleep(SYNC_INTERVAL)


def start_sync_thread(app):
    """
    启动同步线程
    
    Args:
        app: Flask 应用实例
    """
    app.logger.info("启动同步线程")
    if os.environ.get('ENABLE_REMOTE_SYNC', 'false').lower() == 'true':
        sync_thread = threading.Thread(target=sync_completed_recordings_to_remote, args=(app,), daemon=True)
        sync_thread.start()
        app.logger.info("远程数据同步线程已启动")
    else:
        app.logger.info("远程数据同步功能未启用 (ENABLE_REMOTE_SYNC=false)")
