"""Database-based report storage implementation."""

from typing import Dict, Any, Optional
from loguru import logger
from sqlalchemy.orm import Session

from .base import ReportStorage
from ..database.models import ResearchHistory
from ..memory_cache.cached_services import CachedResearchService


class DatabaseReportStorage(ReportStorage):
    """Store reports in the database with caching support."""

    def __init__(self, session: Session):
        """Initialize database storage.

        Args:
            session: SQLAlchemy database session
        """
        self.session = session

    def save_report(
        self,
        research_id: str,
        content: str,
        metadata: Optional[Dict[str, Any]] = None,
        username: Optional[str] = None,
    ) -> bool:
        """Save report to database."""
        try:
            if username:
                # Use cached service if username is provided
                cached_service = CachedResearchService(self.session, username)
                return cached_service.save_report(
                    research_id, content, metadata
                )
            else:
                # Direct database save without caching
                research = (
                    self.session.query(ResearchHistory)
                    .filter_by(id=research_id)
                    .first()
                )

                if not research:
                    logger.error(f"Research {research_id} not found")
                    return False

                research.report_content = content

                if metadata:
                    if research.research_meta:
                        research.research_meta.update(metadata)
                    else:
                        research.research_meta = metadata

                self.session.commit()
                logger.info(
                    f"Saved report for research {research_id} to database"
                )
                return True

        except Exception:
            logger.exception("Error saving report to database")
            self.session.rollback()
            return False

    def get_report(
        self, research_id: str, username: Optional[str] = None
    ) -> Optional[str]:
        """Get report from database."""
        try:
            if username:
                # Use cached service if username is provided
                cached_service = CachedResearchService(self.session, username)
                return cached_service.get_report(research_id)
            else:
                # Direct database read without caching
                research = (
                    self.session.query(ResearchHistory)
                    .filter_by(id=research_id)
                    .first()
                )

                if not research or not research.report_content:
                    return None

                return research.report_content

        except Exception:
            logger.exception("Error getting report from database")
            return None

    def get_report_with_metadata(
        self, research_id: str, username: Optional[str] = None
    ) -> Optional[Dict[str, Any]]:
        """Get report with metadata from database."""
        try:
            research = (
                self.session.query(ResearchHistory)
                .filter_by(id=research_id)
                .first()
            )

            if not research or not research.report_content:
                return None

            return {
                "content": research.report_content,
                "metadata": research.research_meta or {},
                "query": research.query,
                "mode": research.mode,
                "created_at": research.created_at,
                "completed_at": research.completed_at,
                "duration_seconds": research.duration_seconds,
            }

        except Exception:
            logger.exception("Error getting report with metadata")
            return None

    def delete_report(
        self, research_id: str, username: Optional[str] = None
    ) -> bool:
        """Delete report from database."""
        try:
            research = (
                self.session.query(ResearchHistory)
                .filter_by(id=research_id)
                .first()
            )

            if not research:
                return False

            research.report_content = None
            self.session.commit()

            if username:
                # Invalidate cache if username is provided
                cached_service = CachedResearchService(self.session, username)
                cached_service.invalidate_report(research_id)

            return True

        except Exception:
            logger.exception("Error deleting report")
            self.session.rollback()
            return False

    def report_exists(
        self, research_id: str, username: Optional[str] = None
    ) -> bool:
        """Check if report exists in database."""
        try:
            research = (
                self.session.query(ResearchHistory)
                .filter_by(id=research_id)
                .first()
            )

            return research is not None and research.report_content is not None

        except Exception:
            logger.exception("Error checking if report exists")
            return False
