"""Scheduled messages commands — CRUD for scheduled/recurring messages."""

from __future__ import annotations

import json

import typer

from turumba_cli.client import TurumbaClient
from turumba_cli.config import get_value
from turumba_cli.errors import TurumbaAPIError, TurumbaAuthError
from turumba_cli.output import error, render, render_meta, success

app = typer.Typer(name="scheduled-messages", help="Manage scheduled and recurring messages.")

API_PATH = "/v1/scheduled-messages"

LIST_COLUMNS = {
    "ID": "id",
    "Name": "name",
    "Status": "status",
    "Send Type": "send_type",
    "Recurring": "is_recurring",
    "Scheduled At": "scheduled_at",
    "Trigger Count": "trigger_count",
    "Created At": "created_at",
}


def _handle_error(e: Exception) -> None:
    if isinstance(e, TurumbaAuthError | TurumbaAPIError):
        error(str(e))
    else:
        error(f"Unexpected error: {e}")
    raise typer.Exit(1)


@app.command("list")
def list_scheduled_messages(
    filter_: list[str] | None = typer.Option(None, "--filter", "-f", help="Filter: field:op:value"),
    sort: list[str] | None = typer.Option(None, "--sort", "-s", help="Sort: field:asc|desc"),
    limit: int = typer.Option(100, "--limit", "-l", help="Max results"),
    skip: int = typer.Option(0, "--skip", help="Offset"),
    output: str = typer.Option("table", "--output", "-o", help="Output format: table, json, csv"),
    gateway_url: str = typer.Option(None, "--gateway-url", "-g", help="Gateway URL override"),
) -> None:
    """List scheduled messages."""
    client = TurumbaClient(gateway_url=gateway_url)
    try:
        data, meta = client.list(API_PATH, filter_=filter_, sort=sort, limit=limit, skip=skip)
    except Exception as e:
        _handle_error(e)

    render(data, output_format=output, columns=LIST_COLUMNS, title="Scheduled Messages")
    render_meta(meta, output_format=output)


@app.command("get")
def get_scheduled_message(
    scheduled_message_id: str = typer.Argument(help="Scheduled message ID"),
    output: str = typer.Option("table", "--output", "-o", help="Output format: table, json"),
    gateway_url: str = typer.Option(None, "--gateway-url", "-g", help="Gateway URL override"),
) -> None:
    """Get details of a specific scheduled message."""
    client = TurumbaClient(gateway_url=gateway_url)
    try:
        data = client.get(API_PATH, scheduled_message_id)
    except Exception as e:
        _handle_error(e)

    render(data, output_format=output, is_list=False, title="Scheduled Message Details")


@app.command("create")
def create_scheduled_message(
    send_type: str = typer.Option(..., "--send-type", help="Send type: single or group"),
    scheduled_at: str = typer.Option(..., "--scheduled-at", help="Schedule time (ISO 8601)"),
    account_id: str = typer.Option(
        None, "--account-id", "-a", help="Account ID (defaults to config default_account_id)"
    ),
    name: str = typer.Option(None, "--name", "-n", help="Message name"),
    channel_id: str = typer.Option(None, "--channel-id", "-c", help="Channel ID"),
    template_id: str = typer.Option(None, "--template-id", "-t", help="Template ID"),
    message_body: str = typer.Option(None, "--body", "-b", help="Message body (if no template)"),
    delivery_address: str = typer.Option(
        None, "--delivery-address", "-d", help="Recipient address (for single send)"
    ),
    contact_id: str = typer.Option(None, "--contact-id", help="Contact ID (for single send)"),
    group_ids: list[str] | None = typer.Option(
        None, "--group-id", help="Group ID(s) (for group send)"
    ),
    exclude_person_ids: list[str] | None = typer.Option(
        None, "--exclude-person-id", help="Person ID(s) to exclude"
    ),
    timezone: str = typer.Option(None, "--timezone", help="Timezone (e.g. Africa/Addis_Ababa)"),
    is_recurring: bool = typer.Option(False, "--recurring", help="Enable recurring schedule"),
    recurrence_rule: str = typer.Option(
        None, "--recurrence-rule", help="Recurrence rule (e.g. RRULE:FREQ=DAILY)"
    ),
    recurrence_end_at: str = typer.Option(
        None, "--recurrence-end-at", help="Recurrence end time (ISO 8601)"
    ),
    custom_values: str = typer.Option(
        None, "--custom-values", help="Custom template values as JSON"
    ),
    metadata: str = typer.Option(None, "--metadata", help="Metadata as JSON string"),
    output: str = typer.Option("table", "--output", "-o", help="Output format: table, json"),
    gateway_url: str = typer.Option(None, "--gateway-url", "-g", help="Gateway URL override"),
) -> None:
    """Create a new scheduled message."""
    if not template_id and not message_body:
        error("Provide either --template-id or --body.")
        raise typer.Exit(1)
    if send_type == "single" and not delivery_address:
        error("--delivery-address is required for single send type.")
        raise typer.Exit(1)
    if send_type == "group" and not group_ids:
        error("--group-id is required for group send type.")
        raise typer.Exit(1)
    if is_recurring and not recurrence_rule:
        error("--recurrence-rule is required when --recurring is set.")
        raise typer.Exit(1)

    resolved_account_id = account_id or get_value("default_account_id")

    client = TurumbaClient(gateway_url=gateway_url)

    fields: dict = {
        "account_id": resolved_account_id,
        "send_type": send_type,
        "scheduled_at": scheduled_at,
        "name": name,
        "channel_id": channel_id,
        "template_id": template_id,
        "message_body": message_body,
        "delivery_address": delivery_address,
        "contact_id": contact_id,
        "group_ids": group_ids,
        "exclude_person_ids": exclude_person_ids,
        "timezone": timezone,
        "recurrence_rule": recurrence_rule,
        "recurrence_end_at": recurrence_end_at,
    }
    data = {k: v for k, v in fields.items() if v}
    if is_recurring:
        data["is_recurring"] = True
    if custom_values:
        data["custom_values"] = json.loads(custom_values)
    if metadata:
        data["metadata"] = json.loads(metadata)

    try:
        result = client.create(API_PATH, data)
    except Exception as e:
        _handle_error(e)

    success(f"Scheduled message created: {result.get('id', '')}")
    render(result, output_format=output, is_list=False, title="Created Scheduled Message")


@app.command("update")
def update_scheduled_message(
    scheduled_message_id: str = typer.Argument(help="Scheduled message ID"),
    name: str = typer.Option(None, "--name", "-n", help="Message name"),
    channel_id: str = typer.Option(None, "--channel-id", "-c", help="Channel ID"),
    template_id: str = typer.Option(None, "--template-id", "-t", help="Template ID"),
    message_body: str = typer.Option(None, "--body", "-b", help="Message body"),
    scheduled_at: str = typer.Option(None, "--scheduled-at", help="Schedule time (ISO 8601)"),
    timezone: str = typer.Option(None, "--timezone", help="Timezone"),
    recurrence_rule: str = typer.Option(None, "--recurrence-rule", help="Recurrence rule"),
    recurrence_end_at: str = typer.Option(
        None, "--recurrence-end-at", help="Recurrence end time (ISO 8601)"
    ),
    custom_values: str = typer.Option(
        None, "--custom-values", help="Custom template values as JSON"
    ),
    metadata: str = typer.Option(None, "--metadata", help="Metadata as JSON string"),
    output: str = typer.Option("table", "--output", "-o", help="Output format: table, json"),
    gateway_url: str = typer.Option(None, "--gateway-url", "-g", help="Gateway URL override"),
) -> None:
    """Update an existing scheduled message."""
    client = TurumbaClient(gateway_url=gateway_url)

    data: dict = {}
    if name is not None:
        data["name"] = name
    if channel_id is not None:
        data["channel_id"] = channel_id
    if template_id is not None:
        data["template_id"] = template_id
    if message_body is not None:
        data["message_body"] = message_body
    if scheduled_at is not None:
        data["scheduled_at"] = scheduled_at
    if timezone is not None:
        data["timezone"] = timezone
    if recurrence_rule is not None:
        data["recurrence_rule"] = recurrence_rule
    if recurrence_end_at is not None:
        data["recurrence_end_at"] = recurrence_end_at
    if custom_values is not None:
        data["custom_values"] = json.loads(custom_values)
    if metadata is not None:
        data["metadata"] = json.loads(metadata)

    if not data:
        error("No fields to update. Provide at least one option.")
        raise typer.Exit(1)

    try:
        result = client.update(API_PATH, scheduled_message_id, data)
    except Exception as e:
        _handle_error(e)

    success(f"Scheduled message updated: {scheduled_message_id}")
    render(result, output_format=output, is_list=False, title="Updated Scheduled Message")


@app.command("delete")
def delete_scheduled_message(
    scheduled_message_id: str = typer.Argument(help="Scheduled message ID"),
    force: bool = typer.Option(False, "--force", "-y", help="Skip confirmation"),
    gateway_url: str = typer.Option(None, "--gateway-url", "-g", help="Gateway URL override"),
) -> None:
    """Delete a scheduled message."""
    if not force:
        typer.confirm(f"Delete scheduled message {scheduled_message_id}?", abort=True)

    client = TurumbaClient(gateway_url=gateway_url)
    try:
        client.delete(API_PATH, scheduled_message_id)
    except Exception as e:
        _handle_error(e)

    success(f"Scheduled message deleted: {scheduled_message_id}")
