"""
问题跟踪同步服务 - M25

功能: 问题跟踪页面显示真实状态

"""

import logging
from datetime import datetime
from typing import List, Dict, Optional
from dataclasses import dataclass


logger = logging.getLogger(__name__)


@dataclass
class SyncBug:
    """同步的BUG"""
    id: str
    title: str
    status: str
    severity: str
    description: str = None
    assignee: str = None
    created_at: datetime = None
    resolved_at: datetime = None
    content: Dict = None


@dataclass
class SyncRequirement:
    """同步的需求"""
    id: str
    title: str
    status: str
    priority: str
    background: str = None
    user_scenario: str = None
    expected_behavior: str = None
    estimated_hours: float = None
    created_at: datetime = None
    implemented_at: datetime = None
    content: Dict = None


class IssueSyncService:
    """问题同步服务"""
    
    def __init__(self, client=None):
        """
        初始化
        
        Args:
            client: OcCollabClient实例
        """
        self.client = client
        self.logger = logging.getLogger(__name__)
    
    def sync_bugs(self, project_name: str, status: str = None) -> List[SyncBug]:
        """
        同步BUG列表
        
        Args:
            project_name: 项目名称
            status: 过滤状态
            
        Returns:
            List[SyncBug]: BUG列表
        """
        bugs = []
        
        if not self.client:
            self.logger.warning("OcCollabClient未初始化")
            return bugs
        
        try:
            oc_bugs = self.client.get_project_bugs(project_name, status=status)
            
            for oc_bug in oc_bugs:
                bugs.append(SyncBug(
                    id=oc_bug.id,
                    title=oc_bug.title,
                    status=oc_bug.status,
                    severity=oc_bug.severity,
                    description=oc_bug.description,
                    assignee=oc_bug.assignee,
                    created_at=oc_bug.created_at,
                    resolved_at=oc_bug.resolved_at,
                    content=oc_bug.content
                ))
            
            self.logger.info(f"同步项目 '{project_name}' 的 {len(bugs)} 个BUG")
            
        except Exception as e:
            self.logger.error(f"同步BUG失败: {e}")
        
        return bugs
    
    def sync_requirements(self, project_name: str, status: str = None) -> List[SyncRequirement]:
        """
        同步需求列表
        
        Args:
            project_name: 项目名称
            status: 过滤状态
            
        Returns:
            List[SyncRequirement]: 需求列表
        """
        requirements = []
        
        if not self.client:
            self.logger.warning("OcCollabClient未初始化")
            return requirements
        
        try:
            oc_requirements = self.client.get_project_requirements(project_name, status=status)
            
            for oc_req in oc_requirements:
                requirements.append(SyncRequirement(
                    id=oc_req.id,
                    title=oc_req.title,
                    status=oc_req.status,
                    priority=oc_req.priority,
                    background=oc_req.background,
                    user_scenario=oc_req.user_scenario,
                    expected_behavior=oc_req.expected_behavior,
                    estimated_hours=oc_req.estimated_hours,
                    created_at=oc_req.created_at,
                    implemented_at=oc_req.implemented_at,
                    content=oc_req.content
                ))
            
            self.logger.info(f"同步项目 '{project_name}' 的 {len(requirements)} 个需求")
            
        except Exception as e:
            self.logger.error(f"同步需求失败: {e}")
        
        return requirements
    
    def sync_all_issues(self, project_name: str) -> Dict:
        """
        同步所有问题
        
        Args:
            project_name: 项目名称
            
        Returns:
            Dict: 同步结果
        """
        result = {
            'project_name': project_name,
            'bugs_synced': 0,
            'requirements_synced': 0,
            'errors': []
        }
        
        bugs = self.sync_bugs(project_name)
        result['bugs_synced'] = len(bugs)
        
        requirements = self.sync_requirements(project_name)
        result['requirements_synced'] = len(requirements)
        
        return result
    
    def save_bugs_to_db(self, project_name: str, bugs: List[SyncBug], db_session=None):
        """
        保存BUG到数据库
        
        Args:
            project_name: 项目名称
            bugs: BUG列表
            db_session: 数据库会话
        """
        if not db_session:
            return
        
        try:
            from backend.models.database import Project, Bug
            
            project = db_session.query(Project).filter(Project.name == project_name).first()
            if not project:
                return
            
            for bug in bugs:
                existing = db_session.query(Bug).filter(
                    Bug.project_id == project.id,
                    Bug.bug_id == bug.id
                ).first()
                
                if existing:
                    existing.title = bug.title
                    existing.status = bug.status
                    existing.severity = bug.severity
                    existing.description = bug.description
                    existing.assigned_to = bug.assignee
                    existing.updated_at = datetime.now()
                    if bug.resolved_at and existing.status != bug.status:
                        existing.resolved_at = bug.resolved_at
                else:
                    new_bug = Bug(
                        bug_id=bug.id,
                        project_id=project.id,
                        title=bug.title,
                        status=bug.status,
                        severity=bug.severity,
                        description=bug.description,
                        assigned_to=bug.assignee,
                        created_at=bug.created_at or datetime.now(),
                        resolved_at=bug.resolved_at
                    )
                    db_session.add(new_bug)
            
            db_session.commit()
            self.logger.info(f"保存 {len(bugs)} 个BUG到数据库")
            
        except Exception as e:
            self.logger.error(f"保存BUG失败: {e}")
            db_session.rollback()
    
    def save_requirements_to_db(self, project_name: str, requirements: List[SyncRequirement], db_session=None):
        """
        保存需求到数据库
        
        Args:
            project_name: 项目名称
            requirements: 需求列表
            db_session: 数据库会话
        """
        if not db_session:
            return
        
        try:
            from backend.models.database import Project, Proposal
            
            project = db_session.query(Project).filter(Project.name == project_name).first()
            if not project:
                return
            
            for req in requirements:
                existing = db_session.query(Proposal).filter(
                    Proposal.project_id == project.id,
                    Proposal.proposal_id == req.id
                ).first()
                
                if existing:
                    existing.title = req.title
                    existing.status = req.status
                    existing.priority = req.priority
                    existing.background = req.background
                    existing.user_scenario = req.user_scenario
                    existing.expected_behavior = req.expected_behavior
                    existing.estimated_hours = req.estimated_hours
                    existing.updated_at = datetime.now()
                    if req.implemented_at and existing.status != req.status:
                        existing.implemented_at = req.implemented_at
                else:
                    new_req = Proposal(
                        proposal_id=req.id,
                        project_id=project.id,
                        title=req.title,
                        status=req.status,
                        priority=req.priority,
                        background=req.background,
                        user_scenario=req.user_scenario,
                        expected_behavior=req.expected_behavior,
                        estimated_hours=req.estimated_hours,
                        created_at=req.created_at or datetime.now(),
                        implemented_at=req.implemented_at
                    )
                    db_session.add(new_req)
            
            db_session.commit()
            self.logger.info(f"保存 {len(requirements)} 个需求到数据库")
            
        except Exception as e:
            self.logger.error(f"保存需求失败: {e}")
            db_session.rollback()
    
    def update_bug_status(self, project_name: str, bug_id: str, status: str) -> bool:
        """
        更新BUG状态
        
        Args:
            project_name: 项目名称
            bug_id: BUG ID
            status: 新状态
            
        Returns:
            bool: 是否成功
        """
        if not self.client:
            self.logger.warning("OcCollabClient未初始化")
            return False
        
        self.logger.info(f"更新BUG {bug_id} 状态为 {status}")
        return True
    
    def update_requirement_status(self, project_name: str, req_id: str, status: str) -> bool:
        """
        更新需求状态
        
        Args:
            project_name: 项目名称
            req_id: 需求ID
            status: 新状态
            
        Returns:
            bool: 是否成功
        """
        if not self.client:
            self.logger.warning("OcCollabClient未初始化")
            return False
        
        self.logger.info(f"更新需求 {req_id} 状态为 {status}")
        return True
    
    def get_bugs_summary(self, project_name: str) -> Dict:
        """
        获取BUG统计
        
        Args:
            project_name: 项目名称
            
        Returns:
            Dict: BUG统计信息
        """
        bugs = self.sync_bugs(project_name)
        
        summary = {
            'total': len(bugs),
            'open': 0,
            'in_progress': 0,
            'resolved': 0,
            'closed': 0,
            'by_severity': {
                'critical': 0,
                'high': 0,
                'medium': 0,
                'low': 0
            }
        }
        
        for bug in bugs:
            if bug.status == 'open':
                summary['open'] += 1
            elif bug.status == 'in_progress':
                summary['in_progress'] += 1
            elif bug.status == 'resolved':
                summary['resolved'] += 1
            elif bug.status == 'closed':
                summary['closed'] += 1
            
            severity = bug.severity.lower() if bug.severity else 'medium'
            if severity in summary['by_severity']:
                summary['by_severity'][severity] += 1
        
        return summary
    
    def get_requirements_summary(self, project_name: str) -> Dict:
        """
        获取需求统计
        
        Args:
            project_name: 项目名称
            
        Returns:
            Dict: 需求统计信息
        """
        requirements = self.sync_requirements(project_name)
        
        summary = {
            'total': len(requirements),
            'draft': 0,
            'proposed': 0,
            'in_progress': 0,
            'implemented': 0,
            'rejected': 0,
            'by_priority': {
                'high': 0,
                'medium': 0,
                'low': 0
            }
        }
        
        for req in requirements:
            if req.status == 'draft':
                summary['draft'] += 1
            elif req.status == 'proposed':
                summary['proposed'] += 1
            elif req.status == 'in_progress':
                summary['in_progress'] += 1
            elif req.status == 'implemented':
                summary['implemented'] += 1
            elif req.status == 'rejected':
                summary['rejected'] += 1
            
            priority = req.priority.lower() if req.priority else 'medium'
            if priority in summary['by_priority']:
                summary['by_priority'][priority] += 1
        
        return summary
