"""File-based report storage implementation."""

from pathlib import Path
from typing import Dict, Any, Optional
from loguru import logger

from .base import ReportStorage
from ..config.paths import get_research_outputs_directory


class FileReportStorage(ReportStorage):
    """Store reports as files on disk."""

    def __init__(self, base_dir: Optional[Path] = None):
        """Initialize file storage.

        Args:
            base_dir: Base directory for storing reports.
                     If None, uses default research outputs directory.
        """
        self.base_dir = base_dir or get_research_outputs_directory()
        self.base_dir.mkdir(parents=True, exist_ok=True)

    def _get_report_path(self, research_id: str) -> Path:
        """Get the file path for a report."""
        return self.base_dir / f"{research_id}.md"

    def _get_metadata_path(self, research_id: str) -> Path:
        """Get the file path for report metadata."""
        return self.base_dir / f"{research_id}_metadata.json"

    def save_report(
        self,
        research_id: str,
        content: str,
        metadata: Optional[Dict[str, Any]] = None,
        username: Optional[str] = None,
    ) -> bool:
        """Save report to file."""
        try:
            from ..security.file_write_verifier import (
                write_file_verified,
                write_json_verified,
            )

            report_path = self._get_report_path(research_id)

            # Save content
            write_file_verified(
                report_path,
                content,
                "storage.allow_file_backup",
                context="file storage backup",
            )

            # Save metadata if provided
            if metadata:
                metadata_path = self._get_metadata_path(research_id)
                write_json_verified(
                    metadata_path,
                    metadata,
                    "storage.allow_file_backup",
                    context="file storage metadata",
                )

            logger.info(
                f"Saved report for research {research_id} to {report_path}"
            )
            return True

        except Exception:
            logger.exception("Error saving report to file")
            return False

    def get_report(
        self, research_id: str, username: Optional[str] = None
    ) -> Optional[str]:
        """Get report from file."""
        try:
            report_path = self._get_report_path(research_id)

            if not report_path.exists():
                return None

            with open(report_path, "r", encoding="utf-8") as f:
                return f.read()

        except Exception:
            logger.exception("Error reading report from file")
            return None

    def get_report_with_metadata(
        self, research_id: str, username: Optional[str] = None
    ) -> Optional[Dict[str, Any]]:
        """Get report with metadata from files."""
        try:
            content = self.get_report(research_id)
            if not content:
                return None

            result = {"content": content, "metadata": {}}

            # Try to load metadata
            metadata_path = self._get_metadata_path(research_id)
            if metadata_path.exists():
                import json

                with open(metadata_path, "r", encoding="utf-8") as f:
                    result["metadata"] = json.load(f)

            return result

        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 files."""
        try:
            report_path = self._get_report_path(research_id)
            metadata_path = self._get_metadata_path(research_id)

            deleted = False

            if report_path.exists():
                report_path.unlink()
                deleted = True

            if metadata_path.exists():
                metadata_path.unlink()

            return deleted

        except Exception:
            logger.exception("Error deleting report files")
            return False

    def report_exists(
        self, research_id: str, username: Optional[str] = None
    ) -> bool:
        """Check if report file exists."""
        return self._get_report_path(research_id).exists()
