"""Command-line interface for sed.sh."""

import click
import json
import sys
from pathlib import Path
from sed_sh import SedSH
from sed_sh.exceptions import SedSHError


@click.group()
@click.option(
    "--api-key",
    envvar="SEDSH_API_KEY",
    help="API key (or set SEDSH_API_KEY environment variable)",
)
@click.pass_context
def cli(ctx, api_key):
    """sed.sh CLI - URL shortener, malware scanner, disposable inbox, mock APIs, and PDF reports.

    Documentation: https://docs.sed.sh
    """
    ctx.ensure_object(dict)
    ctx.obj["api_key"] = api_key


# ===== LINKS COMMANDS =====


@cli.group()
def links():
    """URL shortening service."""
    pass


@links.command("create")
@click.argument("target_url")
@click.option("--password", help="Optional password protection")
@click.pass_context
def links_create(ctx, target_url, password):
    """Create a shortened URL."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.links.create(target_url, password=password)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@links.command("list")
@click.pass_context
def links_list(ctx):
    """List all shortened URLs."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.links.list()
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@links.command("delete")
@click.argument("code")
@click.pass_context
def links_delete(ctx, code):
    """Delete a shortened URL by code."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.links.delete(code)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


# ===== MALWARE COMMANDS =====


@cli.group()
def malware():
    """Malware scanning service."""
    pass


@malware.command("scan")
@click.argument("file_path", type=click.Path(exists=True))
@click.pass_context
def malware_scan(ctx, file_path):
    """Scan a file for malware."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.malware.scan_file(file_path)
            click.echo(json.dumps(result, indent=2))
            click.echo(
                "\nScan initiated. You'll receive an email when the scan completes.",
                err=True,
            )
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


# ===== INBOX COMMANDS =====


@cli.group()
def inbox():
    """Disposable email inbox service."""
    pass


@inbox.command("create")
@click.pass_context
def inbox_create(ctx):
    """Create a new disposable inbox."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.inbox.create()
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@inbox.command("list")
@click.pass_context
def inbox_list(ctx):
    """List all inboxes."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.inbox.list()
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@inbox.command("messages")
@click.argument("inbox_code")
@click.pass_context
def inbox_messages(ctx, inbox_code):
    """Get all messages for an inbox."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.inbox.get_messages(inbox_code)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@inbox.command("message")
@click.argument("inbox_code")
@click.argument("message_id")
@click.pass_context
def inbox_message(ctx, inbox_code, message_id):
    """Get a specific message."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.inbox.get_message(inbox_code, message_id)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@inbox.command("delete")
@click.argument("inbox_code")
@click.pass_context
def inbox_delete(ctx, inbox_code):
    """Delete an inbox."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.inbox.delete(inbox_code)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


# ===== ROUTES COMMANDS =====


@cli.group()
def routes():
    """Mock API / Routes service."""
    pass


@routes.command("create")
@click.option("--name", required=True, help="Endpoint name")
@click.option("--method", required=True, help="HTTP method (GET, POST, etc.)")
@click.option("--path", required=True, help="API path (must start with /)")
@click.option("--forward-mode", is_flag=True, help="Enable forward mode")
@click.option("--forward-url", help="URL to forward requests to (for forward mode)")
@click.option("--status", type=int, help="Response status code (for mock mode)")
@click.option("--delay", type=int, help="Response delay in ms (for mock mode)")
@click.option("--body", help="Response body (for mock mode)")
@click.option("--headers", help="Response headers as JSON (for mock mode)")
@click.pass_context
def routes_create(ctx, name, method, path, forward_mode, forward_url, status, delay, body, headers):
    """Create a mock API endpoint."""
    try:
        kwargs = {
            "name": name,
            "method": method,
            "path": path,
            "forward_mode": forward_mode,
        }

        if forward_url:
            kwargs["forward_url"] = forward_url
        if status:
            kwargs["response_status"] = status
        if delay:
            kwargs["response_delay"] = delay
        if body:
            kwargs["response_body"] = body
        if headers:
            kwargs["response_headers"] = json.loads(headers)

        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.routes.create_endpoint(**kwargs)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@routes.command("list")
@click.pass_context
def routes_list(ctx):
    """List all endpoints."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.routes.list_endpoints()
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@routes.command("delete")
@click.argument("endpoint_id")
@click.pass_context
def routes_delete(ctx, endpoint_id):
    """Delete an endpoint."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.routes.delete_endpoint(endpoint_id)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@routes.command("requests")
@click.pass_context
def routes_requests(ctx):
    """List all received requests."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.routes.get_requests()
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@routes.command("request")
@click.argument("request_id")
@click.pass_context
def routes_request(ctx, request_id):
    """Get details of a specific request."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.routes.get_request(request_id)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


# ===== REPORTS COMMANDS =====


@cli.group()
def reports():
    """PDF reports service."""
    pass


@reports.command("create-template")
@click.option("--name", required=True, help="Template name")
@click.option("--html", required=True, type=click.Path(exists=True), help="Path to HTML file")
@click.option("--expiry-hours", type=int, default=24, help="Expiry in hours (max 24)")
@click.pass_context
def reports_create_template(ctx, name, html, expiry_hours):
    """Create a report template from an HTML file."""
    try:
        html_content = Path(html).read_text()
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.reports.create_template(name, html_content, expiry_hours)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@reports.command("list-templates")
@click.pass_context
def reports_list_templates(ctx):
    """List all report templates."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.reports.list_templates()
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@reports.command("delete-template")
@click.argument("template_id")
@click.pass_context
def reports_delete_template(ctx, template_id):
    """Delete a template."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.reports.delete_template(template_id)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@reports.command("generate")
@click.argument("template_id")
@click.option("--data", required=True, type=click.Path(exists=True), help="Path to JSON data file")
@click.pass_context
def reports_generate(ctx, template_id, data):
    """Generate a PDF from a template."""
    try:
        json_data = json.loads(Path(data).read_text())
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.reports.generate_pdf(template_id, json_data)
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


@reports.command("list-generations")
@click.pass_context
def reports_list_generations(ctx):
    """List recent PDF generations."""
    try:
        with SedSH(api_key=ctx.obj["api_key"]) as client:
            result = client.reports.list_generations()
            click.echo(json.dumps(result, indent=2))
    except SedSHError as e:
        click.echo(f"Error: {e.message}", err=True)
        sys.exit(1)


if __name__ == "__main__":
    cli(obj={})
