from celery_app import app
from config import settings
from tasks.preprocess import preprocess_images
from tasks.group_rooms import group_rooms
from tasks.detect_connections import detect_connections
from tasks.hotspot_prediction import hotspot_prediction
from tasks.validation import run_validation
from sqlalchemy import create_engine, text
from sqlalchemy.orm import Session


def _update_job_status(house_id: str, status: str, progress: float, message: str):
    """Update the AI job status in the database."""
    engine = create_engine(settings.database_url)
    try:
        with Session(engine) as session:
            session.execute(
                text(
                    "UPDATE ai_jobs SET status = :status, progress = :progress, "
                    "message = :message, updated_at = NOW() "
                    "WHERE house_id = :house_id"
                ),
                {
                    "house_id": house_id,
                    "status": status,
                    "progress": progress,
                    "message": message,
                },
            )
            session.commit()
    except Exception:
        pass  # Best effort status update


@app.task(bind=True)
def run_full_analysis(self, house_id: str):
    """Run complete AI analysis pipeline in order.

    Pipeline: preprocess -> group_rooms -> detect_connections -> hotspot_prediction -> validation
    """
    total_steps = 5
    results = {}

    try:
        # Step 1: Preprocess
        _update_job_status(house_id, "running", 0.0, "Preprocessing images...")
        preprocess_result = preprocess_images(house_id)
        results["preprocess"] = preprocess_result
        if not preprocess_result.get("success", False):
            _update_job_status(
                house_id, "failed", 0.2,
                f"Preprocessing failed: {preprocess_result.get('errors', [])}",
            )
            return {
                "success": False,
                "step": "preprocess",
                "results": results,
            }

        # Step 2: Group rooms
        _update_job_status(house_id, "running", 0.25, "Grouping rooms...")
        group_result = group_rooms(house_id)
        results["group_rooms"] = group_result
        if not group_result.get("success", False):
            _update_job_status(
                house_id, "failed", 0.4,
                f"Room grouping failed: {group_result.get('error', '')}",
            )
            return {
                "success": False,
                "step": "group_rooms",
                "results": results,
            }

        # Step 3: Detect connections
        _update_job_status(house_id, "running", 0.5, "Detecting connections...")
        detect_result = detect_connections(house_id)
        results["detect_connections"] = detect_result
        if not detect_result.get("success", False):
            _update_job_status(
                house_id, "failed", 0.65,
                f"Connection detection failed: {detect_result.get('error', '')}",
            )
            return {
                "success": False,
                "step": "detect_connections",
                "results": results,
            }

        # Step 4: Hotspot prediction
        _update_job_status(house_id, "running", 0.7, "Predicting hotspots...")
        hotspot_result = hotspot_prediction(house_id)
        results["hotspot_prediction"] = hotspot_result
        if not hotspot_result.get("success", False):
            _update_job_status(
                house_id, "failed", 0.85,
                f"Hotspot prediction failed: {hotspot_result.get('error', '')}",
            )
            return {
                "success": False,
                "step": "hotspot_prediction",
                "results": results,
            }

        # Step 5: Validation
        _update_job_status(house_id, "running", 0.9, "Running validation...")
        validation_result = run_validation(house_id)
        results["validation"] = validation_result
        if not validation_result.get("success", False):
            _update_job_status(
                house_id, "failed", 0.95,
                f"Validation failed: {validation_result.get('error', '')}",
            )
            return {
                "success": False,
                "step": "validation",
                "results": results,
            }

        # Complete!
        _update_job_status(house_id, "completed", 1.0, "Analysis complete")
        return {
            "success": True,
            "step": "complete",
            "results": results,
        }

    except Exception as e:
        _update_job_status(
            house_id, "failed", 0.0, f"Pipeline error: {str(e)}"
        )
        return {
            "success": False,
            "step": "pipeline_error",
            "results": results,
            "error": str(e),
        }
