import io
import os
from datetime import datetime

from jinja2 import Template

from app.core.s3 import s3_service
from app.models.interview_report import InterviewReport, RecommendationType


class PDFReportService:
    """Сервис для генерации и загрузки PDF отчетов в S3 хранилище"""

    def __init__(self):
        self.template_path = "templates/interview_report.html"

    def _load_html_template(self) -> str:
        """Загружает HTML шаблон из файла"""
        try:
            with open(self.template_path, encoding="utf-8") as file:
                return file.read()
        except FileNotFoundError:
            raise FileNotFoundError(f"HTML шаблон не найден: {self.template_path}")

    def _format_concerns_field(self, concerns):
        """Форматирует поле concerns для отображения"""
        if not concerns:
            return "—"

        if isinstance(concerns, list):
            return "; ".join(concerns)
        elif isinstance(concerns, str):
            return concerns
        else:
            return str(concerns)

    def _format_list_field(self, field_value) -> str:
        """Форматирует поле со списком для отображения"""
        if not field_value:
            return "Не указаны"

        if isinstance(field_value, list):
            return "\n".join([f"• {item}" for item in field_value])
        elif isinstance(field_value, str):
            return field_value
        else:
            return str(field_value)

    def _get_score_class(self, score: int) -> str:
        """Возвращает CSS класс для цвета оценки"""
        if score >= 90:
            return "score-green"  # STRONGLY_RECOMMEND
        elif score >= 75:
            return "score-green"  # RECOMMEND
        elif score >= 60:
            return "score-orange"  # CONSIDER
        else:
            return "score-red"  # REJECT

    def _format_recommendation(self, recommendation: RecommendationType) -> tuple:
        """Форматирует рекомендацию для отображения"""
        if recommendation == RecommendationType.STRONGLY_RECOMMEND:
            return ("Настоятельно рекомендуем", "recommend-button")
        elif recommendation == RecommendationType.RECOMMEND:
            return ("Рекомендуем", "recommend-button")
        elif recommendation == RecommendationType.CONSIDER:
            return ("К рассмотрению", "consider-button")
        else:  # REJECT
            return ("Не рекомендуем", "reject-button")

    async def generate_html_report(
        self,
        interview_report: InterviewReport,
        candidate_name: str = None,
        position: str = None,
        resume_file_url: str = None,
    ) -> str:
        """
        Генерирует HTML отчет на основе Jinja2 шаблона

        Args:
            interview_report: Данные отчета по интервью
            candidate_name: Имя кандидата
            position: Позиция
            resume_file_url: URL резюме

        Returns:
            str: HTML содержимое отчета
        """
        try:
            # Загружаем HTML шаблон
            html_template = self._load_html_template()

            # Подготавливаем данные для шаблона
            template_data = self._prepare_template_data(
                interview_report,
                candidate_name or "Не указано",
                position or "Не указана",
                resume_file_url,
            )

            # Рендерим HTML с данными
            template = Template(html_template)
            rendered_html = template.render(**template_data)

            # Сохраняем debug.html для отладки
            with open("debug.html", "w", encoding="utf-8") as f:
                f.write(rendered_html)

            return rendered_html

        except Exception as e:
            raise Exception(f"Ошибка при генерации HTML отчета: {str(e)}")

    def _prepare_template_data(
        self,
        interview_report: InterviewReport,
        candidate_name: str,
        position: str,
        resume_file_url: str = None,
    ) -> dict:
        """Подготавливает данные для HTML шаблона"""

        # Используем переданные параметры
        resume_url = resume_file_url or "#"

        # Форматируем дату интервью
        interview_date = "Не указана"
        if (
            interview_report.interview_session
            and interview_report.interview_session.interview_start_time
        ):
            interview_date = (
                interview_report.interview_session.interview_start_time.strftime(
                    "%d.%m.%Y %H:%M"
                )
            )

        # Общий балл и рекомендация
        overall_score = interview_report.overall_score or 0
        recommendation_text, recommendation_class = self._format_recommendation(
            interview_report.recommendation
        )

        # Сильные стороны и области развития
        strengths = (
            self._format_list_field(interview_report.strengths)
            if interview_report.strengths
            else "Не указаны"
        )
        areas_for_development = (
            self._format_list_field(interview_report.weaknesses)
            if interview_report.weaknesses
            else "Не указаны"
        )

        # Детальная оценка - всегда все критерии
        evaluation_criteria = [
            {
                "name": "Технические навыки",
                "score": interview_report.technical_skills_score or 0,
                "score_class": self._get_score_class(
                    interview_report.technical_skills_score or 0
                ),
                "justification": interview_report.technical_skills_justification or "—",
                "concerns": self._format_concerns_field(
                    interview_report.technical_skills_concerns
                ),
            },
            {
                "name": "Релевантность опыта",
                "score": interview_report.experience_relevance_score or 0,
                "score_class": self._get_score_class(
                    interview_report.experience_relevance_score or 0
                ),
                "justification": interview_report.experience_relevance_justification
                or "—",
                "concerns": self._format_concerns_field(
                    interview_report.experience_relevance_concerns
                ),
            },
            {
                "name": "Коммуникация",
                "score": interview_report.communication_score or 0,
                "score_class": self._get_score_class(
                    interview_report.communication_score or 0
                ),
                "justification": interview_report.communication_justification or "—",
                "concerns": self._format_concerns_field(
                    interview_report.communication_concerns
                ),
            },
            {
                "name": "Решение задач",
                "score": interview_report.problem_solving_score or 0,
                "score_class": self._get_score_class(
                    interview_report.problem_solving_score or 0
                ),
                "justification": interview_report.problem_solving_justification or "—",
                "concerns": self._format_concerns_field(
                    interview_report.problem_solving_concerns
                ),
            },
            {
                "name": "Культурное соответствие",
                "score": interview_report.cultural_fit_score or 0,
                "score_class": self._get_score_class(
                    interview_report.cultural_fit_score or 0
                ),
                "justification": interview_report.cultural_fit_justification or "—",
                "concerns": self._format_concerns_field(
                    interview_report.cultural_fit_concerns
                ),
            },
        ]

        # Красные флаги
        red_flags = interview_report.red_flags or []

        # ID отчета
        report_id = f"#{interview_report.id}" if interview_report.id else "#0"

        # Дата генерации отчета
        generation_date = datetime.now().strftime("%d.%m.%Y %H:%M")

        return {
            "report_id": report_id,
            "candidate_name": candidate_name,
            "position": position,
            "interview_date": interview_date,
            "overall_score": overall_score,
            "recommendation_text": recommendation_text,
            "recommendation_class": recommendation_class,
            "strengths": strengths,
            "areas_for_development": areas_for_development,
            "evaluation_criteria": evaluation_criteria,
            "red_flags": red_flags,
            "resume_url": resume_url,
            "generation_date": generation_date,
        }

    async def upload_pdf_to_s3(self, pdf_bytes: bytes, filename: str) -> str:
        """
        Загружает PDF файл в S3 и возвращает публичную ссылку

        Args:
            pdf_bytes: PDF файл в виде байтов
            filename: Имя файла

        Returns:
            str: Публичная ссылка на файл в S3
        """
        try:
            pdf_stream = io.BytesIO(pdf_bytes)

            # Загружаем с публичным доступом
            file_url = await s3_service.upload_file(
                pdf_stream, filename, content_type="application/pdf", public=True
            )

            return file_url

        except Exception as e:
            raise Exception(f"Ошибка при загрузке PDF в S3: {str(e)}")



# Экземпляр сервиса
pdf_report_service = PDFReportService()
