import sys
import argparse
import logging
from pathlib import Path
from datetime import datetime

from rich.console import Console
from rich.progress import Progress, SpinnerColumn, TextColumn
import questionary

from . import (
    MessageService, 
    Exporter, 
    require_database_access, 
    PermissionError,
    ExportLoader,
    RawStatisticsAnalyzer,
    NLPStatisticsAnalyzer,
    LLMStatisticsAnalyzer,
    TerminalDisplay,
)

logger = logging.getLogger(__name__)


def parse_args():
    parser = argparse.ArgumentParser(
        prog="imexport",
        description="Export and analyze iMessage conversations from macOS",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    
    subparsers = parser.add_subparsers(dest="command", help="Command to run")
    
    export_parser = subparsers.add_parser(
        "export",
        help="Export iMessage conversations to JSON",
    )
    
    export_parser.add_argument(
        "-y", "--year",
        type=int,
        default=datetime.now().year,
        help="Year to export (default: current year)",
    )
    
    export_parser.add_argument(
        "-o", "--output",
        type=str,
        help="Output file path (default: exports/imessage_export_YEAR.jsonl)",
    )
    
    export_parser.add_argument(
        "-d", "--database",
        type=str,
        help="Path to chat.db (default: ~/Library/Messages/chat.db)",
    )
    
    export_parser.add_argument(
        "--format",
        type=str,
        choices=["jsonl", "json"],
        default="jsonl",
        help="Export format (default: jsonl)",
    )
    
    export_parser.add_argument(
        "--indent",
        type=int,
        default=2,
        help="JSON indentation spaces for json format (default: 2, use 0 for compact)",
    )
    
    export_parser.add_argument(
        "--skip-permission-check",
        action="store_true",
        help="Skip permission check (use with caution)",
    )
    
    export_parser.add_argument(
        "--debug",
        action="store_true",
        help="Enable debug logging",
    )
    
    export_parser.add_argument(
        "--replace-cache",
        action="store_true",
        help="Replace existing cached export file if it exists",
    )
    
    analyze_parser = subparsers.add_parser(
        "analyze",
        help="Analyze exported iMessage data",
    )
    
    analyze_parser.add_argument(
        "input",
        type=str,
        nargs="?",
        help="Path to exported JSON/JSONL file",
    )
    
    analyze_parser.add_argument(
        "--analyzers",
        type=str,
        default="raw",
        help="Comma-separated list of analyzers to run (raw,nlp,llm) (default: raw)",
    )
    
    analyze_parser.add_argument(
        "--output",
        type=str,
        help="Output file path for statistics JSON (optional)",
    )
    
    analyze_parser.add_argument(
        "--no-share",
        action="store_false",
        dest="share",
        help="Don't upload statistics (show full terminal output instead)",
    )
    
    analyze_parser.add_argument(
        "--share",
        action="store_true",
        dest="share",
        default=True,
        help="Upload statistics to web and get shareable link (default)",
    )
    
    analyze_parser.add_argument(
        "--server-url",
        type=str,
        default="https://imessage-wrapped.fly.dev",
        help="Web server URL for sharing (default: https://imessage-wrapped.fly.dev)",
    )
    
    analyze_parser.add_argument(
        "--debug",
        action="store_true",
        help="Enable debug logging",
    )
    
    args = parser.parse_args()
    
    if args.command is None:
        args.command = "export"
        args.year = datetime.now().year
        args.output = None
        args.database = None
        args.format = "jsonl"
        args.indent = 2
        args.skip_permission_check = False
        args.debug = False
        args.replace_cache = False
    
    return args


def export_command(args):
    console = Console()
    
    if not args.skip_permission_check:
        try:
            require_database_access(args.database)
        except PermissionError:
            sys.exit(1)
    
    if args.output:
        output_path = args.output
    else:
        ext = "jsonl" if args.format == "jsonl" else "json"
        output_path = f"exports/imessage_export_{args.year}.{ext}"
    
    output_file = Path(output_path)
    
    if output_file.exists() and not args.replace_cache:
        console.print(f"\n[yellow]ℹ[/] Export file already exists: [cyan]{output_path}[/]")
        console.print(f"[dim]Use --replace-cache to regenerate[/]")
        return
    
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console,
    ) as progress:
        task = progress.add_task(f"Exporting messages from {args.year}...", total=None)
        
        service = MessageService(db_path=args.database)
        data = service.export_year(args.year)
        
        progress.update(task, description=f"Writing {data.total_messages} messages to file...")
        
        from .exporter import JSONSerializer, JSONLSerializer
        if args.format == "json":
            serializer = JSONSerializer(indent=args.indent if args.indent > 0 else None)
        else:
            serializer = JSONLSerializer()
        exporter = Exporter(serializer=serializer)
        exporter.export_to_file(data, output_path)
    
    console.print(f"\n[green]✓[/] Exported {data.total_messages} messages to [cyan]{output_path}[/]")
    console.print(f"[dim]Conversations: {len(data.conversations)}[/]")


def analyze_command(args):
    console = Console()
    
    if not args.input:
        exports_dir = Path("exports")
        export_files = []
        
        if exports_dir.exists():
            export_files = sorted(
                [f for f in exports_dir.iterdir() if f.suffix in ['.json', '.jsonl']],
                key=lambda x: x.stat().st_mtime,
                reverse=True
            )
        
        if not export_files:
            console.print(f"[yellow]ℹ[/] No export found. Exporting messages first...\n")
            
            export_args = argparse.Namespace(
                year=datetime.now().year,
                output=None,
                database=None,
                format="jsonl",
                indent=2,
                skip_permission_check=False,
                debug=args.debug,
                replace_cache=False,
            )
            export_command(export_args)
            
            if not exports_dir.exists():
                console.print(f"[red]✗[/] Export failed.")
                sys.exit(1)
            
            export_files = sorted(
                [f for f in exports_dir.iterdir() if f.suffix in ['.json', '.jsonl']],
                key=lambda x: x.stat().st_mtime,
                reverse=True
            )
            
        if not export_files:
            console.print(f"[red]✗[/] Export failed.")
            sys.exit(1)
        
        if args.share or len(export_files) == 1:
            input_path = export_files[0]
        else:
            choices = []
            for file in export_files:
                size_mb = file.stat().st_size / (1024 * 1024)
                choices.append(questionary.Choice(
                    title=f"{file.name} ({size_mb:.1f} MB)",
                    value=file
                ))
            
            selected = questionary.select(
                "Select export file to analyze:",
                choices=choices
            ).ask()
            
            if selected is None:
                sys.exit(0)
            
            input_path = selected
    else:
        input_path = Path(args.input)
        if not input_path.exists():
            console.print(f"[red]✗[/] Input file not found: {args.input}")
            sys.exit(1)
    
    analyzer_names = [name.strip() for name in args.analyzers.split(",")]
    
    with Progress(
        SpinnerColumn(),
        TextColumn("[progress.description]{task.description}"),
        console=console,
    ) as progress:
        task = progress.add_task("Loading export data...", total=None)
        
        try:
            data = ExportLoader.load(input_path)
        except Exception as e:
            console.print(f"[red]✗[/] Failed to load export data: {e}")
            sys.exit(1)
        
        progress.update(task, description=f"Analyzing {data.total_messages:,} messages...")
        
        analyzers = []
        if "raw" in analyzer_names:
            analyzers.append(RawStatisticsAnalyzer())
        if "nlp" in analyzer_names:
            analyzers.append(NLPStatisticsAnalyzer())
        if "llm" in analyzer_names:
            analyzers.append(LLMStatisticsAnalyzer())
        
        statistics = {}
        for analyzer in analyzers:
            progress.update(task, description=f"Running {analyzer.name} analyzer...")
            statistics[analyzer.name] = analyzer.analyze(data)
    
    if args.output:
        import json
        output_path = Path(args.output)
        output_path.parent.mkdir(parents=True, exist_ok=True)
        with open(output_path, 'w', encoding='utf-8') as f:
            json.dump(statistics, f, indent=2, ensure_ascii=False)
        console.print(f"\n[green]✓[/] Statistics saved to [cyan]{args.output}[/]")
    
    display = TerminalDisplay()
    display.render(statistics, brief=args.share)
    
    if args.share:
        from .uploader import StatsUploader
        uploader = StatsUploader(base_url=args.server_url)
        
        year = data.year if hasattr(data, 'year') else datetime.now().year
        share_url = uploader.upload(year, statistics)
        
        if not share_url:
            console.print("\n[yellow]Tip: Make sure the web server is running:[/]")
            console.print("[dim]  cd web && npm install && npm run dev[/]")


def main():
    args = parse_args()
    
    if args.debug:
        logging.basicConfig(
            level=logging.DEBUG,
            format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
        )
        logger.debug("Debug logging enabled")
    
    if args.command == "export":
        export_command(args)
    elif args.command == "analyze":
        analyze_command(args)
    else:
        console = Console()
        console.print("[red]Unknown command. Use 'export' or 'analyze'.[/]")
        sys.exit(1)


if __name__ == "__main__":
    main()

