from typing import Annotated

from fastapi import Depends

from app.repositories.interview_repository import InterviewRepository
from app.repositories.resume_repository import ResumeRepository
from app.services.interview_finalization_service import InterviewFinalizationService
from app.services.interview_service import InterviewRoomService


class AdminService:
    def __init__(
        self,
        interview_repo: Annotated[InterviewRepository, Depends(InterviewRepository)],
        resume_repo: Annotated[ResumeRepository, Depends(ResumeRepository)],
        interview_service: Annotated[
            InterviewRoomService, Depends(InterviewRoomService)
        ],
        finalization_service: Annotated[
            InterviewFinalizationService, Depends(InterviewFinalizationService)
        ],
    ):
        self.interview_repo = interview_repo
        self.resume_repo = resume_repo
        self.interview_service = interview_service
        self.finalization_service = finalization_service

    async def get_active_interview_processes(self):
        """Получить список активных AI процессов"""
        active_sessions = await self.interview_service.get_active_agent_processes()

        import psutil

        processes_info = []

        for session in active_sessions:
            process_info = {
                "session_id": session.id,
                "resume_id": session.resume_id,
                "room_name": session.room_name,
                "pid": session.ai_agent_pid,
                "status": session.ai_agent_status,
                "started_at": session.started_at.isoformat()
                if session.started_at
                else None,
                "is_running": False,
                "memory_mb": 0,
                "cpu_percent": 0,
            }

            if session.ai_agent_pid:
                try:
                    process = psutil.Process(session.ai_agent_pid)
                    if process.is_running():
                        process_info["is_running"] = True
                        process_info["memory_mb"] = round(
                            process.memory_info().rss / 1024 / 1024, 1
                        )
                        process_info["cpu_percent"] = round(
                            process.cpu_percent(interval=0.1), 1
                        )
                except (psutil.NoSuchProcess, psutil.AccessDenied):
                    pass

            processes_info.append(process_info)

        return {
            "active_processes": len([p for p in processes_info if p["is_running"]]),
            "total_sessions": len(processes_info),
            "processes": processes_info,
        }

    async def stop_interview_process(self, session_id: int):
        """Остановить AI процесс интервью"""
        success = await self.interview_service.stop_agent_process(session_id)

        return {
            "success": success,
            "message": f"Process for session {session_id} {'stopped' if success else 'failed to stop'}",
        }

    async def cleanup_dead_processes(self):
        """Очистить информацию о мертвых процессах"""
        cleaned_count = await self.finalization_service.cleanup_dead_processes()

        return {
            "cleaned_processes": cleaned_count,
            "message": f"Cleaned up {cleaned_count} dead processes",
        }

    async def get_analytics_dashboard(self) -> dict:
        """Основная аналитическая панель"""

        all_resumes = await self.resume_repo.get_all()

        status_stats = {}
        for resume in all_resumes:
            status = (
                resume.status.value
                if hasattr(resume.status, "value")
                else str(resume.status)
            )
            status_stats[status] = status_stats.get(status, 0) + 1

        analyzed_count = 0
        recommendation_stats = {
            "strongly_recommend": 0,
            "recommend": 0,
            "consider": 0,
            "reject": 0,
        }

        for resume in all_resumes:
            if resume.notes and "ОЦЕНКА КАНДИДАТА" in resume.notes:
                analyzed_count += 1
                notes = resume.notes.lower()

                if "strongly_recommend" in notes:
                    recommendation_stats["strongly_recommend"] += 1
                elif "recommend" in notes and "strongly_recommend" not in notes:
                    recommendation_stats["recommend"] += 1
                elif "consider" in notes:
                    recommendation_stats["consider"] += 1
                elif "reject" in notes:
                    recommendation_stats["reject"] += 1

        recent_resumes = sorted(all_resumes, key=lambda x: x.updated_at, reverse=True)[
            :10
        ]
        recent_activity = []

        for resume in recent_resumes:
            activity_item = {
                "resume_id": resume.id,
                "candidate_name": resume.applicant_name,
                "status": resume.status.value
                if hasattr(resume.status, "value")
                else str(resume.status),
                "updated_at": resume.updated_at.isoformat()
                if resume.updated_at
                else None,
                "has_analysis": resume.notes and "ОЦЕНКА КАНДИДАТА" in resume.notes,
            }
            recent_activity.append(activity_item)

        return {
            "summary": {
                "total_candidates": len(all_resumes),
                "interviewed_candidates": status_stats.get("interviewed", 0),
                "analyzed_candidates": analyzed_count,
                "analysis_completion_rate": round(
                    (analyzed_count / max(len(all_resumes), 1)) * 100, 1
                ),
            },
            "status_distribution": status_stats,
            "recommendation_distribution": recommendation_stats,
            "recent_activity": recent_activity,
        }

    async def get_vacancy_analytics(self, vacancy_id: int) -> dict:
        """Аналитика кандидатов по конкретной вакансии"""

        vacancy_resumes = await self.resume_repo.get_by_vacancy_id(vacancy_id)

        if not vacancy_resumes:
            return {
                "vacancy_id": vacancy_id,
                "message": "No candidates found for this vacancy",
                "candidates": [],
            }

        candidates_info = []

        for resume in vacancy_resumes:
            overall_score = None
            recommendation = None

            if resume.notes and "ОЦЕНКА КАНДИДАТА" in resume.notes:
                notes = resume.notes
                if "Общий балл:" in notes:
                    try:
                        score_line = [
                            line for line in notes.split("\n") if "Общий балл:" in line
                        ][0]
                        overall_score = int(
                            score_line.split("Общий балл:")[1].split("/")[0].strip()
                        )
                    except:
                        pass

                if "Рекомендация:" in notes:
                    try:
                        rec_line = [
                            line
                            for line in notes.split("\n")
                            if "Рекомендация:" in line
                        ][0]
                        recommendation = rec_line.split("Рекомендация:")[1].strip()
                    except:
                        pass

            candidate_info = {
                "resume_id": resume.id,
                "candidate_name": resume.applicant_name,
                "email": resume.applicant_email,
                "status": resume.status.value
                if hasattr(resume.status, "value")
                else str(resume.status),
                "created_at": resume.created_at.isoformat()
                if resume.created_at
                else None,
                "updated_at": resume.updated_at.isoformat()
                if resume.updated_at
                else None,
                "has_analysis": resume.notes and "ОЦЕНКА КАНДИДАТА" in resume.notes,
                "overall_score": overall_score,
                "recommendation": recommendation,
                "has_parsed_data": bool(resume.parsed_data),
                "has_interview_plan": bool(resume.interview_plan),
            }

            candidates_info.append(candidate_info)

        candidates_info.sort(
            key=lambda x: (x["overall_score"] or 0, x["updated_at"] or ""), reverse=True
        )

        return {
            "vacancy_id": vacancy_id,
            "total_candidates": len(candidates_info),
            "candidates": candidates_info,
        }

    async def generate_reports_for_vacancy(self, vacancy_id: int) -> dict:
        """Запустить генерацию отчетов для всех кандидатов вакансии"""

        from celery_worker.interview_analysis_task import analyze_multiple_candidates

        vacancy_resumes = await self.resume_repo.get_by_vacancy_id(vacancy_id)

        interviewed_resumes = [
            r for r in vacancy_resumes if r.status in ["interviewed"]
        ]

        if not interviewed_resumes:
            return {
                "error": "No interviewed candidates found for this vacancy",
                "vacancy_id": vacancy_id,
            }

        resume_ids = [r.id for r in interviewed_resumes]

        task = analyze_multiple_candidates.delay(resume_ids)

        return {
            "vacancy_id": vacancy_id,
            "task_id": task.id,
            "message": f"Analysis started for {len(resume_ids)} candidates",
            "resume_ids": resume_ids,
        }

    async def get_system_stats(self) -> dict:
        """Общая статистика системы"""
        import psutil

        try:
            cpu_percent = psutil.cpu_percent(interval=1)
            memory = psutil.virtual_memory()
            disk = psutil.disk_usage("/")

            python_processes = []
            for proc in psutil.process_iter(
                ["pid", "name", "memory_info", "cpu_percent", "cmdline"]
            ):
                try:
                    if proc.info["name"] and "python" in proc.info["name"].lower():
                        cmdline = (
                            " ".join(proc.info["cmdline"])
                            if proc.info["cmdline"]
                            else ""
                        )
                        if "ai_interviewer_agent" in cmdline:
                            python_processes.append(
                                {
                                    "pid": proc.info["pid"],
                                    "memory_mb": round(
                                        proc.info["memory_info"].rss / 1024 / 1024, 1
                                    ),
                                    "cpu_percent": proc.info["cpu_percent"] or 0,
                                    "cmdline": cmdline,
                                }
                            )
                except (
                    psutil.NoSuchProcess,
                    psutil.AccessDenied,
                    psutil.ZombieProcess,
                ):
                    pass

            return {
                "system": {
                    "cpu_percent": cpu_percent,
                    "memory_percent": memory.percent,
                    "memory_available_gb": round(
                        memory.available / 1024 / 1024 / 1024, 1
                    ),
                    "disk_percent": disk.percent,
                    "disk_free_gb": round(disk.free / 1024 / 1024 / 1024, 1),
                },
                "ai_agents": {
                    "count": len(python_processes),
                    "total_memory_mb": sum(p["memory_mb"] for p in python_processes),
                    "processes": python_processes,
                },
            }

        except Exception as e:
            return {"error": f"Error getting system stats: {str(e)}"}
