# @File: backend/routers/whatsapp_automation.py
# @Desc: Client-side REST endpoints for WhatsApp campaigns and workflow
#        automation. Mounted under /api/v1/client/whatsapp so the
#        existing auto-registration picks it up. All endpoints require an
#        authenticated user and an active WhatsApp subscription — the
#        services raise 404 otherwise so we don't need per-route guards.
from __future__ import annotations

import logging
from typing import List

from core.database import get_db
from dependencies.auth import get_current_user
from fastapi import APIRouter, Depends, Query, Response, status
from schemas.auth import UserResponse
from schemas.whatsapp_automation import (
    CampaignCreate,
    CampaignOut,
    CampaignRecipientOut,
    CampaignUpdate,
    WorkflowCreate,
    WorkflowOut,
    WorkflowRunOut,
    WorkflowTestRequest,
    WorkflowUpdate,
)
from services.whatsapp import campaigns as campaigns_service
from services.whatsapp import workflows as workflows_service
from sqlalchemy.ext.asyncio import AsyncSession

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/api/v1/client/whatsapp",
    tags=["WhatsApp Client - Automation"],
)


# ---------------------------------------------------------------------------
# Campaigns
# ---------------------------------------------------------------------------


@router.get("/campaigns/stats", summary="Aggregate campaign counters")
async def get_campaign_stats(
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await campaigns_service.campaign_stats(db, user.id)


@router.get("/campaigns", response_model=List[CampaignOut], summary="List campaigns")
async def list_campaigns(
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> list[dict]:
    return await campaigns_service.list_campaigns(db, user.id)


@router.post(
    "/campaigns",
    response_model=CampaignOut,
    status_code=status.HTTP_201_CREATED,
    summary="Create a campaign draft (or schedule it)",
)
async def create_campaign(
    payload: CampaignCreate,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await campaigns_service.create_campaign(db, user.id, payload.model_dump())


@router.get(
    "/campaigns/{campaign_id}",
    response_model=CampaignOut,
    summary="Get campaign details",
)
async def get_campaign(
    campaign_id: int,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await campaigns_service.get_campaign(db, user.id, campaign_id)


@router.get(
    "/campaigns/{campaign_id}/recipients",
    response_model=List[CampaignRecipientOut],
    summary="List recipients for a campaign",
)
async def list_campaign_recipients(
    campaign_id: int,
    limit: int = Query(500, ge=1, le=1000),
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> list[dict]:
    return await campaigns_service.list_recipients(db, user.id, campaign_id, limit=limit)


@router.patch(
    "/campaigns/{campaign_id}",
    response_model=CampaignOut,
    summary="Update a campaign draft",
)
async def update_campaign(
    campaign_id: int,
    payload: CampaignUpdate,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await campaigns_service.update_campaign(
        db, user.id, campaign_id, payload.model_dump(exclude_unset=True)
    )


@router.delete(
    "/campaigns/{campaign_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete a campaign",
)
async def delete_campaign(
    campaign_id: int,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> Response:
    await campaigns_service.delete_campaign(db, user.id, campaign_id)
    return Response(status_code=status.HTTP_204_NO_CONTENT)


@router.post(
    "/campaigns/{campaign_id}/{action}",
    response_model=CampaignOut,
    summary="Start / pause / resume / cancel a campaign",
)
async def transition_campaign(
    campaign_id: int,
    action: str,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await campaigns_service.transition_campaign(db, user.id, campaign_id, action)


# ---------------------------------------------------------------------------
# Workflows
# ---------------------------------------------------------------------------


@router.get("/workflows", response_model=List[WorkflowOut], summary="List workflows")
async def list_workflows(
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> list[dict]:
    return await workflows_service.list_workflows(db, user.id)


@router.post(
    "/workflows",
    response_model=WorkflowOut,
    status_code=status.HTTP_201_CREATED,
    summary="Create a workflow",
)
async def create_workflow(
    payload: WorkflowCreate,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await workflows_service.create_workflow(db, user.id, payload.model_dump())


@router.get(
    "/workflows/{workflow_id}",
    response_model=WorkflowOut,
    summary="Get workflow details",
)
async def get_workflow(
    workflow_id: int,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await workflows_service.get_workflow(db, user.id, workflow_id)


@router.patch(
    "/workflows/{workflow_id}",
    response_model=WorkflowOut,
    summary="Update a workflow",
)
async def update_workflow(
    workflow_id: int,
    payload: WorkflowUpdate,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await workflows_service.update_workflow(
        db, user.id, workflow_id, payload.model_dump(exclude_unset=True)
    )


@router.delete(
    "/workflows/{workflow_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Delete a workflow",
)
async def delete_workflow(
    workflow_id: int,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> Response:
    await workflows_service.delete_workflow(db, user.id, workflow_id)
    return Response(status_code=status.HTTP_204_NO_CONTENT)


@router.get(
    "/workflows/{workflow_id}/runs",
    response_model=List[WorkflowRunOut],
    summary="Recent runs for a workflow",
)
async def list_workflow_runs(
    workflow_id: int,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> list[dict]:
    return await workflows_service.list_runs(db, user.id, workflow_id)


@router.post(
    "/workflows/{workflow_id}/test",
    summary="Dry-run a workflow against a sample message",
)
async def test_workflow(
    workflow_id: int,
    payload: WorkflowTestRequest,
    db: AsyncSession = Depends(get_db),
    user: UserResponse = Depends(get_current_user),
) -> dict:
    return await workflows_service.test_workflow(
        db, user.id, workflow_id, payload.model_dump()
    )