"""Onboarding workflow — runs on user creation.

A code-engine workflow that creates a welcome notification and an
approval step for admin confirmation of new users.
"""

from __future__ import annotations

import uuid
from typing import Any

from sqlalchemy.ext.asyncio import AsyncSession

from app.services.workflow_service import create_instance

# Onboarding workflow definition (code-engine — hardcoded steps)
ONBOARDING_WORKFLOW_STEPS = [
    {
        "name": "Send welcome notification",
        "type": "notification",
        "config": {
            "notification_type": "welcome",
            "title": "Welcome to LeoCRM!",
            "body": "Your account has been created. An admin will approve your access shortly.",
        },
        "description": "Send a welcome notification to the new user",
    },
    {
        "name": "Admin approval",
        "type": "approval",
        "config": {
            "required_role": "admin",
            "description": "Admin must approve the new user account",
        },
        "description": "Admin reviews and approves the new user",
    },
    {
        "name": "Send confirmation",
        "type": "notification",
        "config": {
            "notification_type": "onboarding_complete",
            "title": "Account approved",
            "body": "Your account has been approved. You can now use LeoCRM.",
        },
        "description": "Notify user that their account is approved",
    },
]


def get_onboarding_workflow_definition() -> dict[str, Any]:
    """Return the onboarding workflow definition for DB seeding."""
    return {
        "name": "User Onboarding",
        "description": "Automated onboarding workflow triggered on user creation",
        "trigger_event": "user.created",
        "steps": ONBOARDING_WORKFLOW_STEPS,
        "is_active": True,
    }


async def ensure_onboarding_workflow_exists(
    db: AsyncSession,
    tenant_id: uuid.UUID,
    user_id: uuid.UUID,
) -> uuid.UUID | None:
    """Ensure the onboarding workflow exists in the DB for this tenant.

    If it doesn't exist yet, create it. Returns the workflow ID.
    """
    from sqlalchemy import select

    from app.models.workflow import Workflow

    result = await db.execute(
        select(Workflow).where(
            Workflow.tenant_id == tenant_id,
            Workflow.trigger_event == "user.created",
            Workflow.name == "User Onboarding",
        )
    )
    existing = result.scalar_one_or_none()
    if existing:
        return existing.id

    from app.services.workflow_service import create_workflow

    wf_dict = await create_workflow(
        db,
        tenant_id,
        user_id,
        get_onboarding_workflow_definition(),
    )
    return uuid.UUID(wf_dict["id"]) if wf_dict else None


async def trigger_onboarding(
    db: AsyncSession,
    tenant_id: uuid.UUID,
    admin_user_id: uuid.UUID,
    new_user_id: uuid.UUID,
) -> dict[str, Any] | None:
    """Trigger the onboarding workflow for a newly created user.

    1. Ensure the onboarding workflow exists in DB
    2. Create a workflow instance with new_user_id in context
    """
    wf_id = await ensure_onboarding_workflow_exists(db, tenant_id, admin_user_id)
    if wf_id is None:
        return None

    instance = await create_instance(
        db,
        tenant_id,
        admin_user_id,
        str(wf_id),
        context={"new_user_id": str(new_user_id), "user_id": str(new_user_id)},
    )
    return instance
