"""
同步API路由 - M21

功能: Git同步、跨项目查询、状态反馈

API端点:
- POST /api/sync/project/{project_name} - 手动触发同步
- POST /api/sync/all - 同步所有项目
- GET /api/sync/status - 获取同步状态
- GET /api/sync/logs - 获取同步日志
- GET /api/sync/permission - 获取同步权限

"""

import logging
from typing import Optional, List
from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from sqlalchemy.orm import Session

from backend.models.database import get_db, Project, ProjectSyncStatus, SyncLog
from backend.services.git_sync_service import GitSyncService
from backend.services.oc_collab_client import OcCollabClient, OcCollabError
from backend.services.status_feedback_service import StatusFeedbackService
from backend.services.sync_permission_service import SyncPermissionService
from backend.services.confidential_checker import SensitiveContentChecker

router = APIRouter()

git_sync_service = GitSyncService()
oc_collab_client = OcCollabClient()
status_feedback_service = StatusFeedbackService(client=oc_collab_client)
sync_permission_service = SyncPermissionService()
confidential_checker = SensitiveContentChecker()


class SyncRequest(BaseModel):
    """同步请求"""
    project_name: str
    git_repo: Optional[str] = None


class SyncResponse(BaseModel):
    """同步响应"""
    status: str
    project_name: str
    synced_at: datetime = None
    files_synced: int = 0
    error: Optional[str] = None


class SyncStatusResponse(BaseModel):
    """同步状态响应"""
    project_name: str
    last_sync: Optional[datetime] = None
    status: str
    files_count: int = 0
    progress: int = 0
    confidentiality: str = "normal"


class SyncPermissionResponse(BaseModel):
    """同步权限响应"""
    can_auto_sync: bool
    auto_sync_reason: str
    confidential_projects_count: int
    confidential_projects: List[str]
    recommendations: List[str]


class SensitiveCheckResponse(BaseModel):
    """敏感信息检查响应"""
    can_sync: bool
    warning: Optional[str] = None
    sensitive_files_count: int = 0
    files: List[dict] = []


@router.post("/api/sync/project/{project_name}")
async def sync_project(
    project_name: str,
    git_repo: Optional[str] = None,
    db: Session = Depends(get_db)
):
    """
    手动触发项目同步
    
    Args:
        project_name: 项目名称
        git_repo: Git仓库路径（可选）
        
    Returns:
        SyncResponse: 同步结果
    """
    permission = sync_permission_service.can_sync_project(project_name)
    
    if not permission.allowed:
        raise HTTPException(status_code=403, detail=permission.reason)
    
    if permission.requires_confirmation:
        return {
            "status": "confirmation_required",
            "project_name": project_name,
            "message": permission.reason,
            "warnings": permission.warnings
        }
    
    result = git_sync_service.sync_project(project_name, git_repo)
    
    if result.success:
        project = db.query(Project).filter(Project.name == project_name).first()
        if project:
            project.updated_at = datetime.now()
            db.commit()
    
    return {
        "status": "success" if result.success else "failed",
        "project_name": project_name,
        "synced_at": result.completed_at.isoformat() if result.completed_at else None,
        "files_synced": result.files_synced,
        "error": result.error_message
    }


@router.post("/api/sync/all")
async def sync_all_projects(db: Session = Depends(get_db)):
    """
    同步所有项目
    
    Returns:
        dict: 同步结果汇总
    """
    permission = sync_permission_service.can_auto_sync()
    
    if not permission.allowed:
        raise HTTPException(status_code=403, detail=permission.reason)
    
    results = git_sync_service.sync_all()
    
    return {
        "status": "completed",
        "total_projects": len(results),
        "successful": sum(1 for r in results.values() if r.success),
        "failed": sum(1 for r in results.values() if not r.success),
        "projects": {
            name: {
                "status": "success" if r.success else "failed",
                "files_synced": r.files_synced,
                "error": r.error_message
            }
            for name, r in results.items()
        }
    }


@router.get("/api/sync/status")
async def get_sync_status(
    project_name: Optional[str] = None,
    db: Session = Depends(get_db)
):
    """
    获取同步状态
    
    Args:
        project_name: 项目名称（可选）
        
    Returns:
        dict: 同步状态
    """
    if project_name:
        status = git_sync_service.get_sync_status(project_name)
        
        project = db.query(Project).filter(Project.name == project_name).first()
        if project:
            status['confidentiality'] = getattr(project, 'confidentiality', 'normal')
        
        return status
    
    projects = db.query(Project).filter(Project.status == 'active').all()
    
    status_dict = {}
    for project in projects:
        status = git_sync_service.get_sync_status(project.name)
        status['confidentiality'] = getattr(project, 'confidentiality', 'normal')
        status_dict[project.name] = status
    
    return {"projects": status_dict}


@router.get("/api/sync/logs")
async def get_sync_logs(
    project_name: Optional[str] = None,
    limit: int = Query(default=50, le=100),
    db: Session = Depends(get_db)
):
    """
    获取同步日志
    
    Args:
        project_name: 项目名称（可选）
        limit: 返回数量限制
        
    Returns:
        list: 同步日志列表
    """
    query = db.query(SyncLog)
    
    if project_name:
        project = db.query(Project).filter(Project.name == project_name).first()
        if project:
            query = query.filter(SyncLog.project_id == project.id)
        else:
            return {"logs": [], "message": f"项目 '{project_name}' 不存在"}
    
    logs = query.order_by(SyncLog.started_at.desc()).limit(limit).all()
    
    return {
        "logs": [
            {
                "id": log.id,
                "project_id": log.project_id,
                "sync_type": log.sync_type,
                "status": log.status,
                "files_synced": log.files_synced,
                "files_added": log.files_added,
                "files_modified": log.files_modified,
                "files_deleted": log.files_deleted,
                "error_message": log.error_message,
                "started_at": log.started_at.isoformat() if log.started_at else None,
                "completed_at": log.completed_at.isoformat() if log.completed_at else None
            }
            for log in logs
        ]
    }


@router.get("/api/sync/permission")
async def get_sync_permission():
    """
    获取同步权限信息
    
    Returns:
        SyncPermissionResponse: 同步权限信息
    """
    return sync_permission_service.get_sync_recommendation()


@router.post("/api/sync/validate")
async def validate_sync(
    project_name: str,
    db: Session = Depends(get_db)
):
    """
    同步前验证
    
    Args:
        project_name: 项目名称
        
    Returns:
        SensitiveCheckResponse: 验证结果
    """
    permission = sync_permission_service.can_sync_project(project_name)
    
    project_path = git_sync_service.base_path
    project_full_path = None
    if project_path and project_name:
        project_full_path = f"{project_path}/{project_name}"
    
    if project_full_path and confidential_checker:
        validation = confidential_checker.validate_before_sync(project_full_path)
    else:
        validation = {"can_sync": True, "warning": None}
    
    return {
        "project_name": project_name,
        "permission": {
            "allowed": permission.allowed,
            "reason": permission.reason,
            "requires_confirmation": permission.requires_confirmation,
            "warnings": permission.warnings or []
        },
        "security": validation
    }


@router.get("/api/sync/changes")
async def get_changes(
    project_name: str,
    since: Optional[str] = None
):
    """
    获取变更记录
    
    Args:
        project_name: 项目名称
        since: ISO格式时间戳
        
    Returns:
        list: 变更记录列表
    """
    try:
        changes = oc_collab_client.get_changes(project_name, since=since)
        
        return {
            "project_name": project_name,
            "changes": [
                {
                    "id": change.id,
                    "type": change.change_type,
                    "title": change.title,
                    "old_status": change.old_status,
                    "new_status": change.new_status,
                    "changed_at": change.changed_at.isoformat() if change.changed_at else None,
                    "description": change.description
                }
                for change in changes
            ]
        }
    except OcCollabError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/api/sync/cli/status")
async def get_cli_status():
    """
    获取CLI状态
    
    Returns:
        dict: CLI状态信息
    """
    return {
        "cli_available": oc_collab_client.is_cli_available(),
        "cli_path": oc_collab_client._find_cli()
    }


@router.post("/api/sync/permission/check")
async def check_sync_permission(
    project_name: Optional[str] = None
):
    """
    检查同步权限
    
    Args:
        project_name: 项目名称（可选）
        
    Returns:
        dict: 权限检查结果
    """
    if project_name:
        return sync_permission_service.get_sync_recommendation(project_name)
    
    return sync_permission_service.get_sync_recommendation()


@router.get("/api/sync/confidential/summary")
async def get_confidential_summary():
    """
    获取保密项目汇总
    
    Returns:
        dict: 保密项目汇总
    """
    return sync_permission_service.get_confidential_projects_summary()


@router.post("/api/sync/confidential/check")
async def check_confidential_safety(
    project_name: str
):
    """
    检查保密项目安全性
    
    Args:
        project_name: 项目名称
        
    Returns:
        dict: 安全性检查结果
    """
    return sync_permission_service.check_sync_safety(project_name)
