"""Conversation exporter for markdown and JSON formats."""

import json
from datetime import datetime
from pathlib import Path

from cleave.tui.services.session_store import Conversation, ConversationMessage


class ConversationExporter:
    """Exports conversations to various formats.

    Supports:
    - Markdown: Human-readable format with code blocks preserved
    - JSON: Machine-readable format for import/analysis

    Usage:
        exporter = ConversationExporter()
        exporter.to_markdown(conversation, Path("export.md"))
        exporter.to_json(conversation, Path("export.json"))
    """

    def to_markdown(self, conversation: Conversation, output_path: Path | None = None) -> str:
        """Export conversation to markdown.

        Args:
            conversation: Conversation to export.
            output_path: Optional path to write file.

        Returns:
            Markdown string.
        """
        lines = []

        # Header
        lines.append(f"# {conversation.title or 'Conversation'}")
        lines.append("")
        lines.append(f"**Created:** {self._format_timestamp(conversation.created_at)}")
        lines.append(f"**Updated:** {self._format_timestamp(conversation.updated_at)}")
        lines.append("")

        # Metadata if present
        if conversation.metadata:
            lines.append("## Metadata")
            lines.append("")
            for key, value in conversation.metadata.items():
                lines.append(f"- **{key}:** {value}")
            lines.append("")

        # Messages
        lines.append("## Conversation")
        lines.append("")

        for msg in conversation.messages:
            lines.extend(self._format_message_markdown(msg))
            lines.append("")

        # Footer
        lines.append("---")
        lines.append(f"*Exported from Cleave TUI on {datetime.now().strftime('%Y-%m-%d %H:%M')}*")

        content = "\n".join(lines)

        if output_path:
            output_path.parent.mkdir(parents=True, exist_ok=True)
            output_path.write_text(content, encoding="utf-8")

        return content

    def _format_message_markdown(self, msg: ConversationMessage) -> list[str]:
        """Format a single message as markdown.

        Args:
            msg: Message to format.

        Returns:
            List of markdown lines.
        """
        lines = []

        # Role header
        role_labels = {
            "user": "**You:**",
            "assistant": "**Claude:**",
            "system": "*System:*",
            "tool": "**Tool:**",
        }
        label = role_labels.get(msg.role, f"**{msg.role.title()}:**")
        lines.append(label)
        lines.append("")

        # Content - preserve code blocks
        lines.append(msg.content)

        # Metadata if present (for tool messages)
        if msg.metadata and msg.role == "tool":
            tool_name = msg.metadata.get("tool", "unknown")
            lines.append("")
            lines.append(f"> Tool: `{tool_name}`")

        return lines

    def _format_timestamp(self, timestamp: str) -> str:
        """Format ISO timestamp for display."""
        if not timestamp:
            return "Unknown"
        try:
            dt = datetime.fromisoformat(timestamp)
            return dt.strftime("%Y-%m-%d %H:%M:%S")
        except ValueError:
            return timestamp

    def to_json(self, conversation: Conversation, output_path: Path | None = None) -> str:
        """Export conversation to JSON.

        Args:
            conversation: Conversation to export.
            output_path: Optional path to write file.

        Returns:
            JSON string.
        """
        data = conversation.to_dict()

        # Add export metadata
        data["_export"] = {
            "format": "cleave-conversation-v1",
            "exported_at": datetime.now().isoformat(),
            "source": "cleave-tui",
        }

        content = json.dumps(data, indent=2, ensure_ascii=False)

        if output_path:
            output_path.parent.mkdir(parents=True, exist_ok=True)
            output_path.write_text(content, encoding="utf-8")

        return content

    def from_json(self, json_path: Path) -> Conversation | None:
        """Import conversation from JSON.

        Args:
            json_path: Path to JSON file.

        Returns:
            Imported Conversation, or None if invalid.
        """
        try:
            with json_path.open("r", encoding="utf-8") as f:
                data = json.load(f)

            # Remove export metadata if present
            data.pop("_export", None)

            return Conversation.from_dict(data)
        except Exception:
            return None

    def to_text(self, conversation: Conversation, output_path: Path | None = None) -> str:
        """Export conversation to plain text.

        Args:
            conversation: Conversation to export.
            output_path: Optional path to write file.

        Returns:
            Plain text string.
        """
        lines = []

        lines.append(f"{conversation.title or 'Conversation'}")
        lines.append("=" * 60)
        lines.append("")

        for msg in conversation.messages:
            role_labels = {
                "user": "You",
                "assistant": "Claude",
                "system": "System",
                "tool": "Tool",
            }
            label = role_labels.get(msg.role, msg.role.title())
            lines.append(f"[{label}]")
            lines.append(msg.content)
            lines.append("")
            lines.append("-" * 40)
            lines.append("")

        content = "\n".join(lines)

        if output_path:
            output_path.parent.mkdir(parents=True, exist_ok=True)
            output_path.write_text(content, encoding="utf-8")

        return content
