from __future__ import annotations

import logging
from typing import Any

from sqlalchemy import text
from sqlalchemy.orm import Session

from app.repositories.schema_helper import has_table
from app.services import campaign_core
from app.services.outbound_call_service import initiate_outbound_call
from app.utils.cluster_table_names import campaigns_table

logger = logging.getLogger(__name__)


def run_campaign(
    session_default: Session,
    session_cluster: Session,
    business_id: int,
    campaign_id: int,
    status: str | None,
    waiting_time: Any,
    start_time: str | None,
    end_time: str | None,
    retry_only: bool,
    priority_only: bool,
) -> dict[str, Any]:
    """
    Laravel CampaignService::runCampaign — loads campaign row if needed, then initiates outbound calls.
    (Source not provided; behavior aligned with ProcessCampaignJob + initiateOutboundCall.)
    """
    table_name = campaigns_table(business_id)
    if not has_table(session_cluster, table_name):
        return {
            "success": False,
            "error": "Campaign table not found",
            "campaign_deleted": True,
        }

    campaign = session_cluster.execute(
        text(f"SELECT * FROM `{table_name}` WHERE campaign_id = :cid LIMIT 1"),
        {"cid": campaign_id},
    ).mappings().first()

    if not campaign:
        return {
            "success": False,
            "error": "Campaign not found",
            "campaign_deleted": True,
        }

    status = status or campaign.get("status") or "active"
    waiting_time = waiting_time if waiting_time is not None else campaign.get("waiting_time")
    start_time = start_time or campaign.get("start_time")
    end_time = end_time or campaign.get("end_time")

    logger.info(
        "CampaignService.run_campaign cid=%s bid=%s status=%s retry_only=%s priority_only=%s",
        campaign_id,
        business_id,
        status,
        retry_only,
        priority_only,
    )

    result = initiate_outbound_call(
        session_default,
        session_cluster,
        campaign_id,
        business_id,
        retry_only=retry_only,
        priority_only=priority_only,
    )

    if isinstance(result, dict) and result.get("success") is False:
        if "Campaign not found" in str(result.get("error", "")):
            result = {**result, "campaign_deleted": True}
    return result
