"""CLI interface for the Perplexity research agent."""

import asyncio
import click
import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional
from dataclasses import asdict

from ..config import config
from ..services.protocols import ResearchQuery, ResearchResult
from ..services.research.service import OpenRouterResearchService
from ..services.research.config import ResearchConfig


@click.group()
def research():
    """Perplexity Research Agent CLI using sonar-reasoning-pro via OpenRouter."""
    pass


@research.command()
@click.option('--query', '-q', required=True, help='Research question to investigate')
@click.option('--context', '-c', help='Additional context for the research')
@click.option('--max-tokens', '-m', default=4000, help='Maximum tokens for response')
@click.option('--temperature', '-t', default=0.1, help='Temperature for response generation')
@click.option('--output', '-o', help='Output file path (JSON or MD)')
@click.option('--format', '-f', 'output_format', default='text', 
              type=click.Choice(['text', 'json', 'markdown']), 
              help='Output format')
def query(query: str, context: Optional[str], max_tokens: int, temperature: float, 
          output: Optional[str], output_format: str):
    """Conduct research using Perplexity sonar-reasoning-pro."""
    
    # Validate API key
    if not config.OPENROUTER_API_KEY:
        click.echo("❌ OPENROUTER_API_KEY not found in environment", err=True)
        return 1
    
    try:
        # Initialize research service
        research_config = ResearchConfig.from_env(config.OPENROUTER_API_KEY)
        service = OpenRouterResearchService(research_config)
        
        # Create research query
        research_query = ResearchQuery(
            query=query,
            context=context,
            max_tokens=max_tokens,
            temperature=temperature,
            model="perplexity/sonar-reasoning-pro"
        )
        
        click.echo("🧠 Conducting research with Perplexity sonar-reasoning-pro...")
        
        # Execute research
        result = asyncio.run(service.research(research_query))
        
        # Display results based on format
        if output_format == 'json':
            display_json_result(result, output)
        elif output_format == 'markdown':
            display_markdown_result(result, output)
        else:
            display_text_result(result, output)
        
        return 0
        
    except Exception as e:
        click.echo(f"❌ Research failed: {e}", err=True)
        return 1


@research.command()
def models():
    """List available models through OpenRouter."""
    
    if not config.OPENROUTER_API_KEY:
        click.echo("❌ OPENROUTER_API_KEY not found in environment", err=True)
        return 1
    
    try:
        research_config = ResearchConfig.from_env(config.OPENROUTER_API_KEY)
        service = OpenRouterResearchService(research_config)
        
        models = service.get_available_models()
        
        click.echo("📋 Available Models:")
        for model in models:
            if "perplexity" in model:
                click.echo(f"  🧠 {model}")
            else:
                click.echo(f"  🤖 {model}")
        
        return 0
        
    except Exception as e:
        click.echo(f"❌ Failed to retrieve models: {e}", err=True)
        return 1


@research.command()
@click.option('--file', '-f', required=True, help='File containing research queries (one per line)')
@click.option('--output-dir', '-o', default='./research_results', help='Output directory for results')
@click.option('--format', 'output_format', default='json', 
              type=click.Choice(['json', 'markdown']), 
              help='Output format for batch results')
def batch(file: str, output_dir: str, output_format: str):
    """Conduct batch research on multiple queries."""
    
    if not config.OPENROUTER_API_KEY:
        click.echo("❌ OPENROUTER_API_KEY not found in environment", err=True)
        return 1
    
    # Validate input file
    input_path = Path(file)
    if not input_path.exists():
        click.echo(f"❌ Input file not found: {file}", err=True)
        return 1
    
    # Create output directory
    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)
    
    try:
        # Initialize research service
        research_config = ResearchConfig.from_env(config.OPENROUTER_API_KEY)
        service = OpenRouterResearchService(research_config)
        
        # Read queries
        with open(input_path, 'r') as f:
            queries = [line.strip() for line in f if line.strip()]
        
        click.echo(f"📚 Processing {len(queries)} research queries...")
        
        results = []
        for i, query_text in enumerate(queries, 1):
            click.echo(f"  [{i}/{len(queries)}] Researching: {query_text[:50]}...")
            
            try:
                research_query = ResearchQuery(
                    query=query_text,
                    max_tokens=4000,
                    temperature=0.1,
                    model="perplexity/sonar-reasoning-pro"
                )
                
                result = asyncio.run(service.research(research_query))
                results.append(result)
                
                # Save individual result
                timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
                filename = f"research_{i:03d}_{timestamp}.{output_format}"
                filepath = output_path / filename
                
                if output_format == 'json':
                    save_json_result(result, filepath)
                else:
                    save_markdown_result(result, filepath)
                
            except Exception as e:
                click.echo(f"    ❌ Failed: {e}", err=True)
                continue
        
        # Save combined results
        combined_filename = f"batch_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}.{output_format}"
        combined_filepath = output_path / combined_filename
        
        if output_format == 'json':
            save_batch_json_results(results, combined_filepath)
        else:
            save_batch_markdown_results(results, combined_filepath)
        
        click.echo(f"✅ Batch research completed. Results saved to: {output_path}")
        return 0
        
    except Exception as e:
        click.echo(f"❌ Batch research failed: {e}", err=True)
        return 1


def display_text_result(result: ResearchResult, output: Optional[str]):
    """Display research result in text format."""
    content = f"""🧠 Research Results
{'='*50}

Query: {result.query}

Answer:
{result.answer}

Sources:
{chr(10).join(f"- {source}" for source in result.sources) if result.sources else "- Sources integrated in analysis"}

Metrics:
- Processing Time: {result.processing_time:.2f} seconds
- Confidence Score: {result.confidence_score:.1%}
- Model Used: {result.model_used}
- Tokens Used: {result.token_usage.get('total_tokens', 'N/A')}
- Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
    
    if output:
        with open(output, 'w') as f:
            f.write(content)
        click.echo(f"✅ Results saved to: {output}")
    else:
        click.echo(content)


def display_json_result(result: ResearchResult, output: Optional[str]):
    """Display research result in JSON format."""
    json_data = asdict(result)
    json_data['timestamp'] = datetime.now(timezone.utc).isoformat()
    json_content = json.dumps(json_data, indent=2)
    
    if output:
        with open(output, 'w') as f:
            f.write(json_content)
        click.echo(f"✅ Results saved to: {output}")
    else:
        click.echo(json_content)


def display_markdown_result(result: ResearchResult, output: Optional[str]):
    """Display research result in markdown format."""
    markdown_content = f"""# Research Report: {result.query}

## Executive Summary
{result.answer[:300]}...

## Detailed Analysis
{result.answer}

## Sources
{chr(10).join(f"- {source}" for source in result.sources) if result.sources else "- Sources integrated in analysis"}

---
**Research Metadata:**
- Model: {result.model_used}
- Processing Time: {result.processing_time:.2f} seconds
- Confidence Score: {result.confidence_score:.1%}
- Tokens Used: {result.token_usage.get('total_tokens', 'N/A')}
- Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
    
    if output:
        with open(output, 'w') as f:
            f.write(markdown_content)
        click.echo(f"✅ Results saved to: {output}")
    else:
        click.echo(markdown_content)


def save_json_result(result: ResearchResult, filepath: Path):
    """Save single result as JSON."""
    json_data = asdict(result)
    json_data['timestamp'] = datetime.now(timezone.utc).isoformat()
    
    with open(filepath, 'w') as f:
        json.dump(json_data, f, indent=2)


def save_markdown_result(result: ResearchResult, filepath: Path):
    """Save single result as markdown."""
    content = f"""# Research Report: {result.query}

## Answer
{result.answer}

## Sources
{chr(10).join(f"- {source}" for source in result.sources) if result.sources else "- Sources integrated in analysis"}

---
**Metadata:**
- Model: {result.model_used}
- Processing Time: {result.processing_time:.2f}s
- Confidence: {result.confidence_score:.1%}
- Tokens: {result.token_usage.get('total_tokens', 'N/A')}
- Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
"""
    
    with open(filepath, 'w') as f:
        f.write(content)


def save_batch_json_results(results: list[ResearchResult], filepath: Path):
    """Save batch results as JSON."""
    batch_data = {
        'timestamp': datetime.now(timezone.utc).isoformat(),
        'total_queries': len(results),
        'results': [asdict(result) for result in results]
    }
    
    with open(filepath, 'w') as f:
        json.dump(batch_data, f, indent=2)


def save_batch_markdown_results(results: list[ResearchResult], filepath: Path):
    """Save batch results as markdown."""
    content = f"""# Batch Research Results

Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
Total Queries: {len(results)}

"""
    
    for i, result in enumerate(results, 1):
        content += f"""## Research #{i}: {result.query}

### Answer
{result.answer}

### Sources
{chr(10).join(f"- {source}" for source in result.sources) if result.sources else "- Sources integrated in analysis"}

### Metadata
- Model: {result.model_used}
- Processing Time: {result.processing_time:.2f}s
- Confidence: {result.confidence_score:.1%}
- Tokens: {result.token_usage.get('total_tokens', 'N/A')}

---
"""
    
    with open(filepath, 'w') as f:
        f.write(content)


if __name__ == '__main__':
    research()
