"""Module providing unified interface for project information."""

from dataclasses import dataclass
from typing import List, Optional

from rich.console import Console
from rich.markdown import Markdown
from rich.panel import Panel

__all__ = [
    "ProjectInfo",
    "ProjectInfoError",
    "get_project_info",
    "format_project_info",
    "display_project_status",
]

from ra_aid.file_listing import FileListerError, get_file_listing
from ra_aid.project_state import ProjectStateError, is_new_project


@dataclass
class ProjectInfo:
    """Data class containing project information.

    Attributes:
        is_new: Whether the project is new/empty
        files: List of tracked files in the project
        total_files: Total number of tracked files (before any limit)
    """

    is_new: bool
    files: List[str]
    total_files: int


class ProjectInfoError(Exception):
    """Base exception for project info related errors."""

    pass


def get_project_info(directory: str, file_limit: Optional[int] = None) -> ProjectInfo:
    """
    Get unified project information including new status and file listing.

    Args:
        directory: Path to the project directory
        file_limit: Optional maximum number of files to return in listing

    Returns:
        ProjectInfo: Object containing project information

    Raises:
        ProjectInfoError: If there are any errors accessing project information
        ProjectStateError: If there are errors checking project state
        FileListerError: If there are errors listing files
    """
    try:
        # Check if project is new
        new_status = is_new_project(directory)

        # Get file listing
        files, total = get_file_listing(directory, limit=file_limit)

        return ProjectInfo(is_new=new_status, files=files, total_files=total)

    except (ProjectStateError, FileListerError):
        # Re-raise known errors
        raise
    except Exception as e:
        # Wrap unexpected errors
        raise ProjectInfoError(f"Error getting project info: {e}")


def format_project_info(info: ProjectInfo) -> str:
    """Format project information into a displayable string.

    Args:
        info: ProjectInfo object to format

    Returns:
        Formatted string containing project status and file listing
    """
    # Create project status line
    status = "New/Empty Project" if info.is_new else "Existing Project"

    # Handle empty project case
    if info.total_files == 0:
        return f"Project Status: {status}\nTotal Files: 0\nFiles: None"

    # Format file count with truncation notice if needed
    file_count = (
        f"{len(info.files)} of {info.total_files}"
        if len(info.files) < info.total_files
        else str(info.total_files)
    )
    file_count_line = f"Total Files: {file_count}"

    # Format file listing
    files_section = "Files:\n" + "\n".join(f"- {f}" for f in info.files)

    # Add truncation notice if list was truncated
    if len(info.files) < info.total_files:
        files_section += (
            f"\n[Note: Showing {len(info.files)} of {info.total_files} total files]"
        )

    return f"Project Status: {status}\n{file_count_line}\n{files_section}"


def display_project_status(info: ProjectInfo) -> None:
    """Display project status in a visual panel.

    Args:
        info: ProjectInfo object containing project state
    """
    # Create project status text
    status = "**New/empty project**" if info.is_new else "**Existing project**"

    # Format file count (with truncation notice if needed)
    file_count = (
        f"{len(info.files)} of {info.total_files}"
        if len(info.files) < info.total_files
        else str(info.total_files)
    )

    # Build status text with markdown
    status_text = f"""
{status} with **{file_count} file(s)**
"""

    # Create and display panel
    console = Console()
    console.print(Panel(Markdown(status_text.strip()), title="📊 Project Status"))
