"""
Text formatters for LLM/human readable output.
"""

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from .ticket import Attachment, Ticket, TicketDetail, TicketList


def _fmt_size(size: int) -> str:
    """Format bytes to human readable."""
    for unit in ["B", "KB", "MB", "GB"]:
        if size < 1024:
            return f"{size:.1f}{unit}" if unit != "B" else f"{size}{unit}"
        size /= 1024
    return f"{size:.1f}TB"


def _fmt_dt(dt) -> str:
    if not dt:
        return "-"
    return dt.strftime("%Y-%m-%d %H:%M")


def format_ticket(t: "Ticket") -> str:
    lines = [
        f"[{t.key}] {t.summary}",
        f"  Project: {t.project} | Type: {t.issue_type} | Priority: {t.priority or '-'}",
        f"  Status: {t.status} ({t.status_category or '-'})",
        f"  Assignee: {t.assignee or '-'} | Reporter: {t.reporter or '-'}",
        f"  Labels: {', '.join(t.labels) if t.labels else '-'}",
        f"  Created: {_fmt_dt(t.created)} | Updated: {_fmt_dt(t.updated)}",
        f"  URL: {t.url}",
    ]
    if t.description:
        lines.append(f"  Description: {t.description}")
    return "\n".join(lines)


def format_ticket_detail(t: "TicketDetail") -> str:
    lines = [
        f"# {t.key}: {t.summary}",
        "",
        f"Project: {t.project}",
        f"Type: {t.issue_type}",
        f"Status: {t.status} ({t.status_category or '-'})",
        f"Priority: {t.priority or '-'}",
        f"Assignee: {t.assignee or '-'}",
        f"Reporter: {t.reporter or '-'}",
        f"Labels: {', '.join(t.labels) if t.labels else '-'}",
        f"Created: {_fmt_dt(t.created)}",
        f"Updated: {_fmt_dt(t.updated)}",
        f"Parent: {t.parent_key or '-'}",
        f"Subtasks: {', '.join(t.subtasks) if t.subtasks else '-'}",
        f"Linked issues: {', '.join(t.linked_issues) if t.linked_issues else '-'}",
        f"URL: {t.url}",
        "",
        "## Description",
        t.description or "(no description)",
        "",
    ]

    lines.append(f"## Comments ({len(t.comments)})")
    if t.comments:
        for c in t.comments:
            lines.append(f"### {c.get('author', 'Unknown')} ({c.get('created', '')[:16] if c.get('created') else '-'})")
            lines.append(c.get("body", ""))
            lines.append("")
    else:
        lines.append("(no comments)")

    lines.append("")
    lines.append(f"## Attachments ({len(t.attachments)})")
    if t.attachments:
        for a in t.attachments:
            has_content = "[downloaded]" if a.content_base64 else ""
            lines.append(f"- {a.filename} ({_fmt_size(a.size)}, {a.mimetype}) {has_content}")
    else:
        lines.append("(no attachments)")

    return "\n".join(lines)


def format_ticket_with_children(parent: "TicketDetail", children: list) -> str:
    """Format a ticket with its children (subtasks/stories)."""
    lines = [
        f"# {parent.key}: {parent.summary}",
        "",
        f"Project: {parent.project}",
        f"Type: {parent.issue_type}",
        f"Status: {parent.status} ({parent.status_category or '-'})",
        f"Priority: {parent.priority or '-'}",
        f"Assignee: {parent.assignee or '-'}",
        f"Reporter: {parent.reporter or '-'}",
        f"Labels: {', '.join(parent.labels) if parent.labels else '-'}",
        f"Created: {_fmt_dt(parent.created)}",
        f"Updated: {_fmt_dt(parent.updated)}",
        f"URL: {parent.url}",
        "",
        "## Description",
        parent.description or "(no description)",
        "",
    ]

    # Add children section
    if children:
        child_type = "Sub-tasks" if parent.issue_type in ("Story", "Task") else "Stories"
        lines.append(f"## {child_type} ({len(children)})")
        lines.append("=" * 60)
        lines.append("")

        for child in children:
            lines.append(f"[{child.key}] {child.summary}")
            lines.append(f"  Type: {child.issue_type} | Status: {child.status} | Priority: {child.priority or '-'}")
            lines.append(f"  Assignee: {child.assignee or '-'}")
            lines.append(f"  URL: {child.url}")
            lines.append("")
            lines.append("-" * 60)
            lines.append("")

    lines.append(f"## Comments ({len(parent.comments)})")
    if parent.comments:
        for c in parent.comments:
            lines.append(f"### {c.get('author', 'Unknown')} ({c.get('created', '')[:16] if c.get('created') else '-'})")
            lines.append(c.get("body", ""))
            lines.append("")
    else:
        lines.append("(no comments)")

    lines.append("")
    lines.append(f"## Attachments ({len(parent.attachments)})")
    if parent.attachments:
        for a in parent.attachments:
            has_content = "[downloaded]" if a.content_base64 else ""
            lines.append(f"- {a.filename} ({_fmt_size(a.size)}, {a.mimetype}) {has_content}")
    else:
        lines.append("(no attachments)")

    return "\n".join(lines)


def format_ticket_list(tl: "TicketList") -> str:
    # Sort for text output: stories with subtasks, then bugs
    stories = []
    bugs = []
    subtasks = []

    for t in tl.tickets:
        if t.parent_key:
            subtasks.append(t)
        elif t.issue_type in ("Story", "Epic", "Task"):
            stories.append(t)
        elif t.issue_type == "Bug":
            bugs.append(t)
        else:
            stories.append(t)  # fallback

    # Build sorted list: parent stories, then their subtasks, then bugs
    sorted_tickets = []
    for story in sorted(stories, key=lambda t: t.key):
        sorted_tickets.append(story)
        # Add subtasks for this story
        story_subtasks = [st for st in subtasks if st.parent_key == story.key]
        sorted_tickets.extend(sorted(story_subtasks, key=lambda t: t.key))

    # Add bugs at the end
    sorted_tickets.extend(sorted(bugs, key=lambda t: t.key))

    lines = [
        f"Total: {tl.total} | Page: {tl.page} | Page size: {tl.page_size}",
        f"Showing: {len(tl.tickets)} tickets",
        "=" * 60,
        "",
    ]
    for i, t in enumerate(sorted_tickets):
        lines.append(format_ticket(t))
        if i < len(sorted_tickets) - 1:
            lines.append("")
            lines.append("-" * 60)
        lines.append("")
    return "\n".join(lines)
