"""CLI entry point for caffeinate-me."""

import argparse
import sys
from datetime import datetime
from typing import Optional

from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.text import Text

from . import __version__
from .art import get_random_cup
from .coffee_types import COFFEE_TYPES, get_all_types, get_coffee_info, get_recommendation
from .core import caffeinate_me, strip_emoji
from .tracker import ACHIEVEMENTS, export_data, get_stats, log_coffee
from .timer import BREW_TIMES, get_brew_type_choices, list_brew_times, run_timer

console = Console()


# ---------------------------------------------------------------------------
# Theme helpers
# ---------------------------------------------------------------------------


def _theme_color() -> str:
    """Pick a colour theme based on time of day."""
    hour = datetime.now().hour
    if 5 <= hour < 10:
        return "yellow"
    elif 10 <= hour < 15:
        return "bright_blue"
    elif 15 <= hour < 20:
        return "dark_orange"
    return "medium_purple"


# ---------------------------------------------------------------------------
# Display helpers
# ---------------------------------------------------------------------------


def _show_quote(args: argparse.Namespace) -> None:
    """Display a coffee quote with ASCII art and a recommendation."""
    mood: Optional[str] = getattr(args, "mood", None)
    no_emoji: bool = getattr(args, "no_emoji", False)
    intensity: Optional[str] = getattr(args, "intensity", None)
    coffee_type: Optional[str] = getattr(args, "type", None)
    do_log: bool = getattr(args, "log", False)

    theme = _theme_color()

    message = caffeinate_me(mood=mood, no_emoji=no_emoji)

    rec = get_coffee_info(coffee_type) if coffee_type else get_recommendation(intensity=intensity)

    cup = get_random_cup()

    content = Text()
    content.append(cup, style=theme)
    content.append(f'\n\n  "{message}"\n', style=f"bold {theme}")

    if rec:
        rec_line = (
            f"\n  Recommended: {rec['emoji']} {rec['name']}"
            f"  •  {rec['caffeine_mg']}mg caffeine"
            f"  •  {rec['intensity'].capitalize()} intensity"
        )
        content.append(rec_line, style="dim")

    console.print()
    console.print(Panel(content, title="[bold]☕ Caffeinate Me[/bold]", border_style=theme))

    if do_log:
        ct = coffee_type or (
            rec["name"].lower().replace(" ", "-") if rec else None
        )
        newly_unlocked = log_coffee(coffee_type=ct, mood=mood)
        stats = get_stats()
        console.print(f"\n  [green]✓ Coffee #{stats['today']} logged today![/green]")
        for key in newly_unlocked:
            ach = ACHIEVEMENTS.get(key, {})
            console.print(
                f"  [bold yellow]{ach.get('icon', '🏆')}  Achievement Unlocked: "
                f"{ach.get('name', key)}![/bold yellow]"
            )

    console.print()


def _show_stats() -> None:
    """Display consumption statistics and achievements."""
    theme = _theme_color()
    stats = get_stats()

    console.print()

    # Stats table
    table = Table(
        title="☕ Your Coffee Stats",
        border_style=theme,
        show_header=False,
        show_lines=True,
    )
    table.add_column("Metric", style="cyan", no_wrap=True)
    table.add_column("Value", style="bold")

    table.add_row("Today", f"{stats['today']} cup(s)")
    table.add_row("This Week", f"{stats['week']} cup(s)")
    table.add_row("All Time", f"{stats['total']} cup(s)")
    table.add_row("Daily Average", f"{stats['avg_per_day']}")

    if stats["favorite_type"]:
        fav_info = COFFEE_TYPES.get(stats["favorite_type"], {})
        fav_label = fav_info.get("name", stats["favorite_type"])
        table.add_row("Favourite", f"{fav_label} ☕")

    console.print(table)

    # Achievements table
    unlocked = stats["achievements"]
    all_ach = stats["all_achievements"]

    ach_table = Table(
        title=f"🏆 Achievements  ({len(unlocked)}/{len(all_ach)})",
        border_style=theme,
        show_header=False,
        show_lines=True,
    )
    ach_table.add_column("Icon", width=3, justify="center")
    ach_table.add_column("Name", style="cyan")
    ach_table.add_column("Description")

    for key, ach in all_ach.items():
        if key in unlocked:
            ach_table.add_row(ach["icon"], f"[bold]{ach['name']}[/bold]", ach["description"])
        else:
            ach_table.add_row(
                "·",
                f"[dim]{ach['name']}[/dim]",
                f"[dim]{ach['description']}[/dim]",
            )

    console.print(ach_table)
    console.print()


def _show_coffee_type_info(coffee_type: str) -> None:
    """Display detailed info for a single coffee type."""
    theme = _theme_color()
    info = get_coffee_info(coffee_type)

    if not info:
        console.print(f"[red]Unknown coffee type: {coffee_type!r}[/red]")
        console.print(f"Available types: {', '.join(get_all_types())}")
        return

    content = Text()
    content.append(f"  {info['emoji']}  {info['name']}\n\n", style=f"bold {theme}")
    content.append(f"  {info['description']}\n\n", style="italic")
    content.append("  Caffeine:  ", style="dim")
    content.append(f"{info['caffeine_mg']}mg\n", style="bold")
    content.append("  Brew Time: ", style="dim")
    content.append(f"{info['brew_time']}\n", style="bold")
    content.append("  Intensity: ", style="dim")
    content.append(f"{info['intensity'].capitalize()}\n", style="bold")
    content.append("  Best Time: ", style="dim")
    content.append(f"{info['best_time'].capitalize()}\n\n", style="bold")
    content.append(f"  💡 {info['notes']}", style="dim italic")

    console.print(Panel(content, title=f"☕ {info['name']}", border_style=theme))


# ---------------------------------------------------------------------------
# Argument parser
# ---------------------------------------------------------------------------


def _build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="caffeinate-me",
        description="☕  A whimsical caffeine companion for coffee-loving developers",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=(
            "examples:\n"
            "  caffeinate-me                       Show a random coffee quote\n"
            "  caffeinate-me --mood energetic       Quote filtered by mood\n"
            "  caffeinate-me --intensity espresso   Espresso-strength recommendation\n"
            "  caffeinate-me --type latte           Show latte details + a quote\n"
            "  caffeinate-me --stats                View your coffee stats\n"
            "  caffeinate-me --log                  Log a coffee + show quote\n"
            "  caffeinate-me --no-emoji             Plain text output\n"
            "  caffeinate-me timer french-press     Start a brewing timer\n"
            "  caffeinate-me timer --list           Show all brew times\n"
            "  caffeinate-me --export csv           Export your data as CSV\n"
        ),
    )

    parser.add_argument(
        "--version", action="version", version=f"caffeinate-me {__version__}"
    )
    parser.add_argument(
        "--mood",
        choices=["energetic", "sleepy", "stressed", "zen"],
        metavar="MOOD",
        help="Filter quotes by mood: energetic, sleepy, stressed, zen",
    )
    parser.add_argument(
        "--intensity",
        choices=["mild", "strong", "espresso"],
        metavar="LEVEL",
        help="Coffee intensity for recommendation: mild, strong, espresso",
    )
    parser.add_argument(
        "--type",
        choices=get_all_types(),
        metavar="TYPE",
        help=f"Coffee type: {', '.join(get_all_types())}",
    )
    parser.add_argument(
        "--no-emoji",
        action="store_true",
        help="Output without emoji characters",
    )
    parser.add_argument(
        "--stats",
        action="store_true",
        help="Show coffee consumption statistics",
    )
    parser.add_argument(
        "--log",
        action="store_true",
        help="Log this coffee to your tracker",
    )
    parser.add_argument(
        "--export",
        choices=["json", "csv"],
        metavar="FORMAT",
        help="Export tracker data: json or csv",
    )

    # ---- timer sub-command ----
    subparsers = parser.add_subparsers(dest="command")
    timer_p = subparsers.add_parser("timer", help="Start a brewing timer")
    timer_p.add_argument(
        "brew_type",
        nargs="?",
        default="french-press",
        choices=get_brew_type_choices(),
        metavar="TYPE",
        help=f"Type to brew: {', '.join(get_brew_type_choices())}",
    )
    timer_p.add_argument(
        "--list",
        action="store_true",
        help="List all brew types and times",
    )

    return parser


# ---------------------------------------------------------------------------
# Entry point
# ---------------------------------------------------------------------------


def main(argv=None) -> None:
    """Parse arguments and dispatch to the correct handler."""
    parser = _build_parser()
    args = parser.parse_args(argv)

    # Sub-commands
    if args.command == "timer":
        if getattr(args, "list", False):
            list_brew_times()
        else:
            run_timer(args.brew_type)
        return

    # Export
    if getattr(args, "export", None):
        print(export_data(args.export))
        return

    # Stats-only mode
    if getattr(args, "stats", False):
        _show_stats()
        return

    # Type info + quote (when --type supplied without --stats)
    if getattr(args, "type", None):
        _show_coffee_type_info(args.type)

    # Default: show a quote (always)
    _show_quote(args)


if __name__ == "__main__":
    main()
