import click
import os
import subprocess
from pathlib import Path
from rich.console import Console

console = Console()


@click.group()
def cli():
    """FeatherOS CLI - Build full-stack apps with minimal code"""
    pass


@cli.command()
@click.argument('project_name', default='my-app')
def init(project_name):
    """Initialize a new FeatherOS project"""
    console.print(f"[cyan]Creating new FeatherOS project: {project_name}[/cyan]")
    
    project_path = Path(project_name)
    project_path.mkdir(exist_ok=True)
    
    app_content = '''import feather as ft

app = ft.App(title="My FeatherOS App")

@app.page("/")
def home():
    ft.title("Welcome to FeatherOS")
    
    with ft.form() as form:
        name = ft.input("Name", placeholder="Enter your name", required=True)
        email = ft.input("Email", type="email", placeholder="your@email.com")
        submit = ft.button("Submit")
    
    if form.submitted:
        ft.db.save("users", {
            "name": name.value,
            "email": email.value
        })
        ft.success(f"Welcome {name.value}!")
        ft.rerun()
    
    users = ft.db.query("users", order_by="created_at DESC", limit=10)
    
    if users:
        ft.title("Recent Users", level=2)
        ft.table(users, headers=["id", "name", "email", "created_at"])

if __name__ == "__main__":
    app.run()
'''
    
    app_file = project_path / 'app.py'
    with open(app_file, 'w') as f:
        f.write(app_content)
    
    console.print(f"[green]✓ Project created successfully![/green]")
    console.print(f"\n[yellow]Next steps:[/yellow]")
    console.print(f"  cd {project_name}")
    console.print(f"  feather serve")


@cli.command()
@click.option('--host', default='0.0.0.0', help='Host to bind to')
@click.option('--port', default=5000, help='Port to bind to')
@click.option('--reload/--no-reload', default=True, help='Enable hot-reload')
def serve(host, port, reload):
    """Run the FeatherOS development server"""
    console.print(f"[cyan]Starting FeatherOS server on {host}:{port}[/cyan]")
    
    if not os.path.exists('app.py'):
        console.print("[red]Error: app.py not found in current directory[/red]")
        console.print("[yellow]Run 'feather init' to create a new project[/yellow]")
        return
    
    os.environ['FLASK_ENV'] = 'development'
    os.environ['FLASK_HOST'] = host
    os.environ['FLASK_PORT'] = str(port)
    
    if reload:
        from .dev_server import run_dev_server
        try:
            run_dev_server('app.py')
        except KeyboardInterrupt:
            console.print("\n[yellow]Server stopped[/yellow]")
    else:
        try:
            subprocess.run(['python', 'app.py'], check=True)
        except KeyboardInterrupt:
            console.print("\n[yellow]Server stopped[/yellow]")
        except subprocess.CalledProcessError:
            console.print("[red]Error running app.py[/red]")


@cli.group()
def plugin():
    """Manage FeatherOS plugins"""
    pass


@plugin.command()
@click.argument('plugin_name')
@click.option('--server', default=None, help='Custom plugin server URL')
def install(plugin_name, server):
    """Install a plugin from the FeatherOS server"""
    from .plugins.installer import PluginInstaller
    
    installer = PluginInstaller(server_url=server)
    installer.install(plugin_name)


@plugin.command()
def list():
    """List all installed plugins"""
    from .plugins.installer import PluginInstaller
    
    installer = PluginInstaller()
    installer.list_installed()


@cli.command()
@click.argument('component_type', type=click.Choice(['page', 'model', 'api', 'component']))
@click.argument('name')
def generate(component_type, name):
    """Generate a new component, page, model, or API endpoint"""
    console.print(f"[cyan]Generating {component_type}: {name}[/cyan]")
    
    if component_type == 'page':
        _generate_page(name)
    elif component_type == 'model':
        _generate_model(name)
    elif component_type == 'api':
        _generate_api(name)
    elif component_type == 'component':
        _generate_component(name)
    
    console.print(f"[green]✓ {component_type.capitalize()} '{name}' created successfully![/green]")


def _generate_page(name):
    """Generate a new page template"""
    pages_dir = Path('pages')
    pages_dir.mkdir(exist_ok=True)
    
    page_content = f'''import feather as ft

@ft.app.page("/{name.lower()}")
def {name.lower()}_page():
    """{ name} page"""
    ft.title("{name}")
    ft.text("Welcome to {name} page!")
    
    # Add your components here
'''
    
    page_file = pages_dir / f'{name.lower()}.py'
    with open(page_file, 'w') as f:
        f.write(page_content)


def _generate_model(name):
    """Generate a new database model"""
    models_dir = Path('models')
    models_dir.mkdir(exist_ok=True)
    
    model_content = f'''from feather.database.models import Model
from typing import Optional

class {name}(Model):
    """{ name} model"""
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.name: Optional[str] = kwargs.get('name')
        # Add more fields here
    
    @classmethod
    def create(cls, **kwargs):
        """Create a new {name}"""
        from feather import db
        record_id = db.save('{name.lower()}s', kwargs)
        return cls(id=record_id, **kwargs)
    
    @classmethod
    def find_by_id(cls, record_id: int):
        """Find {name} by ID"""
        from feather import db
        results = db.query('{name.lower()}s', where={{'id': record_id}})
        return cls(**results[0].__dict__) if results else None
'''
    
    model_file = models_dir / f'{name.lower()}.py'
    with open(model_file, 'w') as f:
        f.write(model_content)


def _generate_api(name):
    """Generate a new API endpoint"""
    api_dir = Path('api')
    api_dir.mkdir(exist_ok=True)
    
    api_content = f'''from feather.api import route, get, post, put, delete
from pydantic import BaseModel
from typing import List, Optional

class {name}Request(BaseModel):
    """Request model for {name}"""
    name: str
    # Add more fields here

class {name}Response(BaseModel):
    """Response model for {name}"""
    id: int
    name: str
    created_at: str

@get('/api/{name.lower()}s')
def list_{name.lower()}s() -> List[{name}Response]:
    """List all {name}s"""
    from feather import db
    items = db.query('{name.lower()}s')
    return [{{
        'id': item.id,
        'name': item.name,
        'created_at': str(item.created_at)
    }} for item in items]

@post('/api/{name.lower()}s')
def create_{name.lower()}(data: {name}Request) -> {name}Response:
    """Create a new {name}"""
    from feather import db
    record_id = db.save('{name.lower()}s', data.dict())
    return {{
        'id': record_id,
        **data.dict(),
        'created_at': str(datetime.utcnow())
    }}

@put('/api/{name.lower()}s/{{id}}')
def update_{name.lower()}(id: int, data: {name}Request):
    """Update a {name}"""
    from feather import db
    db.update('{name.lower()}s', id, data.dict())
    return {{'message': '{name} updated successfully'}}

@delete('/api/{name.lower()}s/{{id}}')
def delete_{name.lower()}(id: int):
    """Delete a {name}"""
    from feather import db
    db.delete('{name.lower()}s', id)
    return {{'message': '{name} deleted successfully'}}
'''
    
    api_file = api_dir / f'{name.lower()}.py'
    with open(api_file, 'w') as f:
        f.write(api_content)


def _generate_component(name):
    """Generate a new custom component"""
    components_dir = Path('components')
    components_dir.mkdir(exist_ok=True)
    
    component_content = f'''import feather as ft

class {name}:
    """Custom {name} component"""
    
    def __init__(self, **kwargs):
        self.props = kwargs
    
    def render(self):
        """Render the component"""
        with ft.card():
            ft.title(self.props.get('title', '{name}'))
            ft.text(self.props.get('content', 'Component content here'))
            
            # Add your component logic here
        
        return self

# Usage: 
# {name.lower()} = {name}(title="My Title", content="My content")
# {name.lower()}.render()
'''
    
    component_file = components_dir / f'{name.lower()}.py'
    with open(component_file, 'w') as f:
        f.write(component_content)


@cli.command()
def test():
    """Run the test suite"""
    console.print("[cyan]Running FeatherOS test suite...[/cyan]")
    
    try:
        import pytest
        exit_code = pytest.main(['tests/', '-v'])
        if exit_code == 0:
            console.print("[green]✓ All tests passed![/green]")
        else:
            console.print("[red]✗ Some tests failed[/red]")
    except ImportError:
        console.print("[yellow]pytest not installed, using unittest instead[/yellow]")
        subprocess.run(['python', '-m', 'unittest', 'discover', '-s', 'tests', '-v'])


@cli.command()
@click.argument('template', type=click.Choice(['blog', 'dashboard', 'ecommerce', 'api']))
@click.argument('project_name')
def new(template, project_name):
    """Create a new project from a template"""
    console.print(f"[cyan]Creating {template} project: {project_name}[/cyan]")
    
    project_path = Path(project_name)
    project_path.mkdir(exist_ok=True)
    
    templates = {
        'blog': _create_blog_template,
        'dashboard': _create_dashboard_template,
        'ecommerce': _create_ecommerce_template,
        'api': _create_api_template
    }
    
    templates[template](project_path)
    console.print(f"[green]✓ {template.capitalize()} project created![/green]")
    console.print(f"\n[yellow]Next steps:[/yellow]")
    console.print(f"  cd {project_name}")
    console.print(f"  pip install -r requirements.txt")
    console.print(f"  feather serve")


def _create_blog_template(path):
    """Create a blog template"""
    (path / 'app.py').write_text('''import feather as ft

app = ft.App(title="My Blog")

@app.page("/")
def home():
    ft.title("Welcome to My Blog")
    posts = ft.db.query("posts", order_by="created_at DESC")
    for post in posts:
        with ft.card():
            ft.title(post.title, level=2)
            ft.text(post.content)

if __name__ == "__main__":
    app.run()
''')


def _create_dashboard_template(path):
    """Create a dashboard template"""
    (path / 'app.py').write_text('''import feather as ft

app = ft.App(title="Dashboard")

@app.page("/")
def dashboard():
    ft.title("Analytics Dashboard")
    cols = ft.columns([1, 1, 1])
    with cols[0]:
        ft.metric("Users", 1234, "+12%")
    with cols[1]:
        ft.metric("Revenue", "$45K", "+8%")
    with cols[2]:
        ft.metric("Orders", 567, "+23%")

if __name__ == "__main__":
    app.run()
''')


def _create_ecommerce_template(path):
    """Create an ecommerce template"""
    (path / 'app.py').write_text('''import feather as ft

app = ft.App(title="My Store")

@app.page("/")
def shop():
    ft.title("Welcome to Our Store")
    products = ft.db.query("products")
    for product in products:
        with ft.card():
            ft.title(product.name)
            ft.text(f"${product.price}")
            ft.button("Add to Cart")

if __name__ == "__main__":
    app.run()
''')


def _create_api_template(path):
    """Create an API-only template"""
    (path / 'app.py').write_text('''import feather as ft
from feather.api import route, get, post

app = ft.App(title="API Server")

@get('/api/items')
def list_items():
    items = ft.db.query("items")
    return {'items': [item.__dict__ for item in items]}

@post('/api/items')
def create_item(data):
    record_id = ft.db.save("items", data)
    return {'id': record_id, 'message': 'Item created'}

if __name__ == "__main__":
    app.run(api_only=True)
''')


if __name__ == '__main__':
    cli()
