import logging
import sys
from datetime import datetime, timedelta

from pydantic import ValidationError

sys.path.append(".")
# from utils.logger import ServiceLogger
import logging

from services.ppt_generator.data_classes.project import Project
from services.ppt_training.analyze_ppt import AnalyzePPT
from services.ppt_training.combine_presentation_analysis import \
    CombinePresentationsAnalysis
from services.ppt_training.training_data_models import (PPTData,
                                                        PresentationAnalysis,
                                                        SlideAnalysis)
from utils.dynamo_db import DynamoDB

XCM_logger = logging.getLogger()


class ClientTraining:

    db = DynamoDB()

    def __init__(self, cutoff_date=datetime.now().strftime("%Y-%m-%d")):
        self.cutoff_date = cutoff_date

    def get_modified_projects(self):
        """Retrieve all projects that have been modified today."""

        projects = self.db.get_all_table_items(self.db.projects)

        projects_to_process = []
        for project in projects:
            if project["modified_date"] >= self.cutoff_date:
                try:
                    projects_to_process.append(Project(**project))
                except Exception:
                    XCM_logger.error(
                        "Error processing project: %s",
                        project["project_id"],
                        exc_info=True,
                    )

        return projects_to_process

    def has_been_analyzed(self, project: Project):
        """Check if the pptx path in the project has been analyzed."""
        presentation_analysis = PPTData.get_ppt_data(project.project_id)
        if (
            presentation_analysis is None
            or presentation_analysis.is_latest_same() is False
        ):
            return False
        return True

    def analyze_project(self, project):
        """Analyze the PPT and upload the analysis."""
        analyze_ppt = AnalyzePPT(project)
        analyze_ppt.process_ppt()
        ppt_analysis = analyze_ppt.analyze_ppt()
        analyze_ppt.PPTData.PPT_analysis = PresentationAnalysis(
            **ppt_analysis["ppt_overview"]
        )
        analyze_ppt.PPTData.slides_analysis = [
            SlideAnalysis(**slide) for slide in ppt_analysis["slides_analysis"]
        ]
        analyze_ppt.PPTData.save_to_db()
        return analyze_ppt

    def combine_analysis(self, client: str, pitch_type: str, new_ppt_data: PPTData):
        """Combine analyses by client and pitch type."""
        combine_presentation_analysis = CombinePresentationsAnalysis(
            client, pitch_type, new_ppt_data
        )
        combined_analysis_result = combine_presentation_analysis.consolidate_analysis()
        if combined_analysis_result is False:
            XCM_logger.error(
                "Error combining analysis for client: %s and pitch type: %s",
                client,
                pitch_type,
            )
            raise RuntimeError("Failed to combine analysis")
        return combined_analysis_result

    def process_projects(self):
        """Process all modified projects."""
        XCM_logger.info("Processing modified projects")
        modified_projects = self.get_modified_projects()
        XCM_logger.info(
            "Modified projects: %s",
            ", ".join([project.project_id for project in modified_projects]),
        )

        consolidated_projects_analysis = []
        # TODO: fix the exceptions that are coming up here
        for project in modified_projects:
            if not self.has_been_analyzed(project):
                try:
                    if project.final_ppt_path is None:
                        XCM_logger.warning(
                            "Project %s doesn't have a final ppt path",
                            project.project_id,
                        )
                        continue
                    ppt_data = self.analyze_project(project).PPTData
                    combined_analysis = self.combine_analysis(
                        project.client, project.pitch_type, ppt_data
                    )
                    consolidated_projects_analysis.append(combined_analysis)
                except Exception:  # pylint: disable=broad-except
                    XCM_logger.error(
                        "TRAINING ERROR: Error processing project: %s",
                        project.project_id,
                        exc_info=True,
                    )

        return consolidated_projects_analysis


# For AWS Lambda
def handler(event, context):

    print("hi")
    ppt_training_date_cutoff = (datetime.now() - timedelta(days=10)).strftime(
        "%Y-%m-%d"
    )
    logging.info(
        "Starting Presentation Trainig with cutoff date: %s", ppt_training_date_cutoff
    )
    client_training = ClientTraining(ppt_training_date_cutoff)
    consolidated_projects_analysis = client_training.process_projects()
    import json

    logging.info(
        "Consolidated projects analysis: %s", json.dumps(consolidated_projects_analysis)
    )
    logging.info(
        "End Presentation Trainig with cutoff date: %s", ppt_training_date_cutoff
    )

    return consolidated_projects_analysis


if __name__ == "__main__":

    client_training = ClientTraining(
        (datetime.now() - timedelta(days=10)).strftime("%Y-%m-%d")
    )
    consolidated_projects_analysis = client_training.process_projects()
