"""Reminders skill — thin wrapper on the Fliiq job scheduler."""

from datetime import datetime, timezone

from fliiq.runtime.config import resolve_fliiq_dir
from fliiq.runtime.scheduler.job_crud import create_job_from_params, delete_job_by_name
from fliiq.runtime.scheduler.loader import load_jobs
from fliiq.runtime.ulid import generate_id

_REMINDER_PREFIX = "reminder-"


def _project_root():
    """Resolve the project root (parent of .fliiq/)."""
    return resolve_fliiq_dir().parent


def _jobs_dir():
    return resolve_fliiq_dir() / "jobs"


def _parse_datetime(text: str) -> str:
    """Parse natural language or ISO datetime string. Returns ISO format."""
    # Try ISO first
    try:
        dt = datetime.fromisoformat(text)
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=timezone.utc)
        return dt.isoformat()
    except ValueError:
        pass

    # Try natural language via dateparser
    try:
        import dateparser

        dt = dateparser.parse(text, settings={"RETURN_AS_TIMEZONE_AWARE": True})
        if dt:
            return dt.isoformat()
    except ImportError:
        pass

    raise ValueError(
        f"Could not parse datetime: '{text}'. "
        "Use ISO format (2026-03-01T09:00:00) or natural language ('tomorrow 9am')."
    )


async def handler(params: dict) -> dict:
    action = params["action"]

    if action == "set":
        return _set(params)
    if action == "list":
        return _list(params)
    if action == "cancel":
        return _cancel(params)

    raise ValueError(f"Unknown action: {action}")


def _set(params: dict) -> dict:
    message = params.get("message")
    if not message:
        raise ValueError("message is required for set action")

    channel = params.get("channel", "telegram")
    recurring = params.get("recurring")

    # Generate unique name
    short_id = generate_id("r").split("_")[1][:10]
    name = f"{_REMINDER_PREFIX}{short_id}"

    # Build trigger
    if recurring:
        trigger_type = "cron"
        schedule = recurring
    else:
        fire_at = params.get("fire_at")
        if not fire_at:
            raise ValueError("fire_at is required for one-time reminders (or provide 'recurring' for recurring)")
        trigger_type = "at"
        schedule = _parse_datetime(fire_at)

    # Build job prompt
    skill_name = f"send_{channel}"
    prompt = (
        f"Send this reminder via {channel}: {message}. "
        f"Use the {skill_name} skill to deliver the message. Do not ask for confirmation, just send it."
    )

    result = create_job_from_params(
        {
            "name": name,
            "prompt": prompt,
            "trigger_type": trigger_type,
            "schedule": schedule,
            "skills": [skill_name],
            "delivery_type": channel,
            "delivery_to": "default",
        },
        _project_root(),
    )

    return {"success": True, "message": result, "reminder_name": name, "schedule": schedule}


def _list(params: dict) -> dict:
    jobs_dir = _jobs_dir()
    jobs = load_jobs(jobs_dir)
    reminders = [j for j in jobs if j.name.startswith(_REMINDER_PREFIX)]

    return {
        "success": True,
        "count": len(reminders),
        "reminders": [
            {
                "name": j.name,
                "prompt": j.prompt,
                "trigger": f"{j.trigger.type} {j.trigger.schedule}",
                "enabled": j.enabled,
                "last_status": j.state.last_status,
                "last_run": str(j.state.last_run_at) if j.state.last_run_at else None,
            }
            for j in reminders
        ],
    }


def _cancel(params: dict) -> dict:
    name = params.get("reminder_name")
    if not name:
        raise ValueError("reminder_name is required for cancel action")

    result = delete_job_by_name(name, _project_root())
    return {"success": True, "message": result}
