"""
Generate command - Code generation from templates.
"""
from pathlib import Path
from typing import Optional

import typer
from rich import print
from rich.console import Console
from rich.table import Table

app = typer.Typer(help="Generate code from templates")
console = Console()


@app.command()
def migration(
    name: str = typer.Argument(..., help="Migration name"),
    models: Optional[str] = typer.Option(
        None, "--models", "-m",
        help="Comma-separated list of models to include"
    )
):
    """Generate a database migration script."""
    console.print(f"[bold green]Generating migration:[/bold green] {name}")
    
    timestamp = Path.cwd().name  # Simplified - would use actual timestamp
    filename = f"migrate_{timestamp}_{name.lower().replace(' ', '_')}.py"
    
    migration_code = f'''"""
Migration: {name}
Generated by Essencia CLI
"""
from essencia.database import Database, AsyncDatabase
from essencia.models import MongoModel


async def up(db: AsyncDatabase):
    """Apply migration."""
    # TODO: Implement migration logic
    pass


async def down(db: AsyncDatabase):
    """Rollback migration."""
    # TODO: Implement rollback logic
    pass


def up_sync(db: Database):
    """Apply migration (sync)."""
    # TODO: Implement migration logic
    pass


def down_sync(db: Database):
    """Rollback migration (sync)."""
    # TODO: Implement rollback logic
    pass
'''
    
    # Create migrations directory if it doesn't exist
    migrations_dir = Path.cwd() / "migrations"
    migrations_dir.mkdir(exist_ok=True)
    
    # Write migration file
    migration_path = migrations_dir / filename
    migration_path.write_text(migration_code)
    
    console.print(f"✅ Generated migration: {migration_path}")


@app.command()
def api(
    name: str = typer.Argument(..., help="API resource name"),
    model: Optional[str] = typer.Option(
        None, "--model", "-m",
        help="Associated model name"
    ),
    operations: Optional[str] = typer.Option(
        "crud", "--operations", "-o",
        help="Operations to generate (crud, ro, custom)"
    )
):
    """Generate API endpoints."""
    console.print(f"[bold green]Generating API for:[/bold green] {name}")
    
    if not model:
        model = name
    
    # Generate FastAPI router
    if operations == "crud":
        ops_code = '''
@router.get("/", response_model=List[{model}])
async def list_{name_lower}(
    skip: int = 0,
    limit: int = 100,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """List all {name_lower}."""
    return await {model}.find_many({{}}, skip=skip, limit=limit)


@router.get("/{{{name_lower}_id}}", response_model={model})
async def get_{name_lower}(
    {name_lower}_id: str,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """Get a specific {name_lower}."""
    {name_lower} = await {model}.find_by_id({name_lower}_id)
    if not {name_lower}:
        raise HTTPException(status_code=404, detail="{model} not found")
    return {name_lower}


@router.post("/", response_model={model})
async def create_{name_lower}(
    {name_lower}: {model},
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """Create a new {name_lower}."""
    return await {name_lower}.save()


@router.put("/{{{name_lower}_id}}", response_model={model})
async def update_{name_lower}(
    {name_lower}_id: str,
    {name_lower}_update: {model},
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """Update a {name_lower}."""
    {name_lower} = await {model}.find_by_id({name_lower}_id)
    if not {name_lower}:
        raise HTTPException(status_code=404, detail="{model} not found")
    
    for field, value in {name_lower}_update.dict(exclude_unset=True).items():
        setattr({name_lower}, field, value)
    
    return await {name_lower}.save()


@router.delete("/{{{name_lower}_id}}")
async def delete_{name_lower}(
    {name_lower}_id: str,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """Delete a {name_lower}."""
    {name_lower} = await {model}.find_by_id({name_lower}_id)
    if not {name_lower}:
        raise HTTPException(status_code=404, detail="{model} not found")
    
    await {name_lower}.delete()
    return {{"message": "{model} deleted successfully"}}'''
    elif operations == "ro":
        ops_code = '''
@router.get("/", response_model=List[{model}])
async def list_{name_lower}(
    skip: int = 0,
    limit: int = 100,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """List all {name_lower}."""
    return await {model}.find_many({{}}, skip=skip, limit=limit)


@router.get("/{{{name_lower}_id}}", response_model={model})
async def get_{name_lower}(
    {name_lower}_id: str,
    db: AsyncIOMotorDatabase = Depends(get_db)
):
    """Get a specific {name_lower}."""
    {name_lower} = await {model}.find_by_id({name_lower}_id)
    if not {name_lower}:
        raise HTTPException(status_code=404, detail="{model} not found")
    return {name_lower}'''
    else:
        ops_code = '''
# TODO: Implement custom operations'''
    
    api_code = f'''"""
API endpoints for {name}.
"""
from typing import List
from fastapi import APIRouter, Depends, HTTPException
from motor.motor_asyncio import AsyncIOMotorDatabase

from essencia.models import {model}
from ..dependencies import get_db

router = APIRouter(prefix="/{name.lower()}", tags=["{name}"])

{ops_code.format(model=model, name_lower=name.lower())}
'''
    
    # Write API file
    api_path = Path.cwd() / f"{name.lower()}_api.py"
    api_path.write_text(api_code)
    
    console.print(f"✅ Generated API endpoints: {api_path}")


@app.command()
def report(
    report_type: str = typer.Argument(
        ...,
        help="Report type (patient-summary, medication-list, assessment-history)"
    ),
    format: str = typer.Option(
        "pdf", "--format", "-f",
        help="Output format (pdf, html, excel)"
    )
):
    """Generate report templates."""
    console.print(f"[bold green]Generating {report_type} report template[/bold green]")
    
    if report_type == "patient-summary":
        template = '''"""
Patient Summary Report Generator.
"""
from datetime import datetime
from typing import Dict, Any
from essencia.models import Patient, VitalSignsSet, Medication
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph
from reportlab.lib.styles import getSampleStyleSheet


class PatientSummaryReport:
    """Generate patient summary reports."""
    
    def __init__(self, patient: Patient):
        self.patient = patient
        self.styles = getSampleStyleSheet()
    
    async def generate_pdf(self, filename: str):
        """Generate PDF report."""
        doc = SimpleDocTemplate(filename, pagesize=A4)
        story = []
        
        # Title
        story.append(Paragraph(f"Patient Summary: {self.patient.name}", self.styles["Title"]))
        
        # Basic Information
        story.append(Paragraph("Basic Information", self.styles["Heading2"]))
        data = [
            ["Name:", self.patient.name],
            ["CPF:", self.patient.cpf],
            ["Birth Date:", self.patient.birth_date.strftime("%d/%m/%Y")],
            ["Blood Type:", self.patient.blood_type or "Unknown"],
        ]
        
        t = Table(data)
        t.setStyle(TableStyle([
            ("BACKGROUND", (0, 0), (-1, 0), "#CCCCCC"),
            ("TEXTCOLOR", (0, 0), (-1, 0), "#000000"),
            ("ALIGN", (0, 0), (-1, -1), "LEFT"),
            ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
            ("FONTSIZE", (0, 0), (-1, 0), 12),
            ("BOTTOMPADDING", (0, 0), (-1, 0), 12),
            ("BACKGROUND", (0, 1), (-1, -1), "#EEEEEE"),
            ("GRID", (0, 0), (-1, -1), 1, "#000000")
        ]))
        story.append(t)
        
        # TODO: Add vital signs, medications, assessments
        
        doc.build(story)
        return filename
'''
    elif report_type == "medication-list":
        template = '''"""
Medication List Report Generator.
"""
from datetime import datetime
from typing import List
from essencia.models import Patient, Medication


class MedicationListReport:
    """Generate medication list reports."""
    
    def __init__(self, patient: Patient, medications: List[Medication]):
        self.patient = patient
        self.medications = medications
    
    def generate_html(self) -> str:
        """Generate HTML report."""
        active_meds = [m for m in self.medications if m.is_active()]
        
        html = f"""
        <html>
        <head>
            <title>Medication List - {self.patient.name}</title>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                table {{ border-collapse: collapse; width: 100%; }}
                th, td {{ border: 1px solid #ddd; padding: 8px; text-align: left; }}
                th {{ background-color: #4CAF50; color: white; }}
                tr:nth-child(even) {{ background-color: #f2f2f2; }}
            </style>
        </head>
        <body>
            <h1>Medication List</h1>
            <p><strong>Patient:</strong> {self.patient.name}</p>
            <p><strong>Date:</strong> {datetime.now().strftime("%d/%m/%Y")}</p>
            
            <h2>Active Medications ({len(active_meds)})</h2>
            <table>
                <tr>
                    <th>Medication</th>
                    <th>Dosage</th>
                    <th>Frequency</th>
                    <th>Start Date</th>
                    <th>Instructions</th>
                </tr>
        """
        
        for med in active_meds:
            html += f"""
                <tr>
                    <td>{med.name} {med.strength}</td>
                    <td>{med.dosage_amount} {med.dosage_unit}</td>
                    <td>{med.frequency_value}x {med.frequency_unit.value}</td>
                    <td>{med.start_date.strftime("%d/%m/%Y")}</td>
                    <td>{med.special_instructions or "-"}</td>
                </tr>
            """
        
        html += """
            </table>
        </body>
        </html>
        """
        
        return html
'''
    else:
        template = '''"""
Custom Report Generator.
"""
# TODO: Implement custom report logic
'''
    
    # Write report file
    report_path = Path.cwd() / f"{report_type.replace('-', '_')}_report.py"
    report_path.write_text(template)
    
    console.print(f"✅ Generated report template: {report_path}")


@app.command()
def list_templates():
    """List available templates."""
    table = Table(title="Available Templates")
    table.add_column("Category", style="cyan")
    table.add_column("Template", style="green")
    table.add_column("Description")
    
    templates = [
        ("create", "model", "MongoDB model with encryption support"),
        ("create", "service", "Service with repository pattern"),
        ("create", "ui", "Flet UI component"),
        ("create", "assessment", "Mental health assessment"),
        ("generate", "migration", "Database migration script"),
        ("generate", "api", "FastAPI endpoints"),
        ("generate", "report", "Report generator"),
    ]
    
    for category, template, description in templates:
        table.add_row(category, template, description)
    
    console.print(table)