"""
Research routes using SQLAlchemy ORM instead of raw SQL.
This is a converted version showing how to replace raw SQL with ORM queries.
"""

import json
from datetime import datetime, UTC
from pathlib import Path

from flask import (
    Blueprint,
    jsonify,
    request,
)
from loguru import logger

from ...config.paths import get_research_outputs_directory
from ...constants import ResearchStatus
from ...database.models import ResearchHistory
from ...database.session_context import get_user_db_session
from ...security import filter_research_metadata, strip_settings_snapshot
from ..auth.decorators import login_required
from ..models.database import calculate_duration
from .globals import active_research, termination_flags

# Create a Blueprint for the research application
research_bp = Blueprint("research", __name__)

# Output directory for research results
OUTPUT_DIR = get_research_outputs_directory()


# Example conversions from the original file:


def check_research_status_orm(research_id):
    """
    Check research status using ORM instead of raw SQL.

    Original SQL:
    SELECT status FROM research_history WHERE id = ?
    """
    with get_user_db_session() as db_session:
        research = (
            db_session.query(ResearchHistory).filter_by(id=research_id).first()
        )
        return research.status if research else None


def update_research_status_orm(research_id, new_status):
    """
    Update research status using ORM.

    Original SQL:
    UPDATE research_history SET status = ? WHERE id = ?
    """
    with get_user_db_session() as db_session:
        research = (
            db_session.query(ResearchHistory).filter_by(id=research_id).first()
        )
        if research:
            research.status = new_status
            db_session.commit()
            return True
        return False


def update_progress_log_orm(research_id, progress_log):
    """
    Update progress log using ORM.

    Original SQL:
    UPDATE research_history SET progress_log = ? WHERE id = ?
    """
    with get_user_db_session() as db_session:
        research = (
            db_session.query(ResearchHistory).filter_by(id=research_id).first()
        )
        if research:
            research.progress_log = progress_log
            db_session.commit()
            return True
        return False


@research_bp.route("/api/start_research", methods=["POST"])
@login_required
def start_research():
    """Start research with ORM operations."""
    data = request.json
    query = data.get("query")
    mode = data.get("mode", "quick")

    # ... validation code ...

    # Check if there's any active research that's actually still running
    if active_research:
        # Verify each active research is still valid
        stale_research_ids = []
        with get_user_db_session() as db_session:
            for research_id, research_data in list(active_research.items()):
                # Check database status using ORM
                research = (
                    db_session.query(ResearchHistory)
                    .filter_by(id=research_id)
                    .first()
                )

                # If the research doesn't exist in DB or is not in_progress, it's stale
                if (
                    not research
                    or research.status != ResearchStatus.IN_PROGRESS
                    or (
                        not research_data.get("thread")
                        or not research_data.get("thread").is_alive()
                    )
                ):
                    stale_research_ids.append(research_id)

        # Clean up any stale research processes
        for stale_id in stale_research_ids:
            logger.info(f"Cleaning up stale research process: {stale_id}")
            if stale_id in active_research:
                del active_research[stale_id]
            if stale_id in termination_flags:
                del termination_flags[stale_id]

    # Create a record in the database with ORM
    created_at = datetime.now(UTC).isoformat()

    # Save research settings in the metadata field
    research_settings = {
        "model_provider": data.get("model_provider", "OLLAMA"),
        "model": data.get("model"),
        # ... other settings ...
    }

    with get_user_db_session() as db_session:
        research = ResearchHistory(
            query=query,
            mode=mode,
            status=ResearchStatus.IN_PROGRESS,
            created_at=created_at,
            progress_log=[{"time": created_at, "progress": 0}],
            research_meta=research_settings,
        )
        db_session.add(research)
        db_session.commit()
        research_id = research.id

    # Start the research process
    # ... rest of the function ...

    return jsonify({"status": "success", "research_id": research_id})


@research_bp.route("/api/terminate/<string:research_id>", methods=["POST"])
@login_required
def terminate_research(research_id):
    """Terminate research using ORM."""
    try:
        with get_user_db_session() as db_session:
            # Check if the research exists and is in progress
            research = (
                db_session.query(ResearchHistory)
                .filter_by(id=research_id)
                .first()
            )

        if not research:
            return jsonify(
                {"status": "error", "message": "Research not found"}
            ), 404

        # If it's not in progress, return an error
        if research.status != ResearchStatus.IN_PROGRESS:
            return (
                jsonify(
                    {
                        "status": "error",
                        "message": "Research is not in progress",
                    }
                ),
                400,
            )

        # Check if it's in the active_research dict
        if research_id not in active_research:
            # Update the status in the database
            research.status = ResearchStatus.SUSPENDED
            db_session.commit()
            return jsonify(
                {"status": "success", "message": "Research terminated"}
            )

        # Set the termination flag
        termination_flags[research_id] = True

        # Log the termination request
        timestamp = datetime.now(UTC).isoformat()
        termination_message = "Research termination requested by user"
        current_progress = active_research[research_id]["progress"]

        # Create log entry
        log_entry = {
            "time": timestamp,
            "message": termination_message,
            "progress": current_progress,
            "metadata": {"phase": "termination"},
        }

        # Add to in-memory log
        active_research[research_id]["log"].append(log_entry)

        # Update the log in the database
        if research.progress_log:
            try:
                current_log = research.progress_log
                if isinstance(current_log, str):
                    current_log = json.loads(current_log)
            except Exception:
                current_log = []
        else:
            current_log = []

        current_log.append(log_entry)
        research.progress_log = current_log
        research.status = ResearchStatus.SUSPENDED
        db_session.commit()

        logger.log("MILESTONE", f"Research ended: {termination_message}")

        return jsonify({"status": "success", "message": "Research terminated"})

    finally:
        db_session.close()


@research_bp.route("/api/delete/<string:research_id>", methods=["DELETE"])
@login_required
def delete_research(research_id):
    """Delete research using ORM."""
    db_session = get_user_db_session()

    try:
        # Get the research record
        research = (
            db_session.query(ResearchHistory).filter_by(id=research_id).first()
        )

        if not research:
            return jsonify(
                {"status": "error", "message": "Research not found"}
            ), 404

        # Get report path before deletion
        report_path = research.report_path

        # Delete from database
        db_session.delete(research)
        db_session.commit()

        # Delete report file if exists
        if report_path and Path(report_path).exists():
            try:
                Path(report_path).unlink()
                logger.info(f"Deleted report file: {report_path}")
            except Exception:
                logger.exception("Failed to delete report file")

        return jsonify(
            {"status": "success", "message": "Research deleted successfully"}
        )

    except Exception:
        db_session.rollback()
        logger.exception("Error deleting research")
        return jsonify(
            {
                "status": "error",
                "message": "An internal error occurred while deleting the research.",
            }
        ), 500
    finally:
        db_session.close()


@research_bp.route("/api/clear_history", methods=["POST"])
@login_required
def clear_history():
    """Clear history using ORM."""
    db_session = get_user_db_session()

    try:
        # Get all research records
        all_research = db_session.query(ResearchHistory).all()

        # Delete report files
        deleted_files = 0
        for research in all_research:
            if research.report_path and Path(research.report_path).exists():
                try:
                    Path(research.report_path).unlink()
                    deleted_files += 1
                except Exception:
                    logger.exception(
                        f"Failed to delete file {research.report_path}"
                    )

        # Delete all records
        deleted_count = db_session.query(ResearchHistory).delete()
        db_session.commit()

        logger.info(
            f"Cleared history: {deleted_count} records, {deleted_files} files"
        )

        return jsonify(
            {
                "status": "success",
                "message": f"Deleted {deleted_count} research records and {deleted_files} report files",
            }
        )

    except Exception:
        db_session.rollback()
        logger.exception("Error clearing history")
        return jsonify(
            {
                "status": "error",
                "message": "An internal error occurred while clearing the history.",
            }
        ), 500
    finally:
        db_session.close()


@research_bp.route("/api/history", methods=["GET"])
@login_required
def api_get_history():
    """Get history using ORM with pagination."""
    page = max(1, request.args.get("page", 1, type=int))
    per_page = request.args.get("per_page", 50, type=int)
    per_page = max(1, min(per_page, 500))

    db_session = get_user_db_session()

    try:
        # Query with pagination
        query = db_session.query(ResearchHistory).order_by(
            ResearchHistory.created_at.desc()
        )

        # Get total count
        total = query.count()

        # Get paginated results
        research_items = (
            query.offset((page - 1) * per_page).limit(per_page).all()
        )

        # Convert to dictionaries
        history_data = []
        for item in research_items:
            data = {
                "id": item.id,
                "query": item.query,
                "mode": item.mode,
                "status": item.status,
                "created_at": item.created_at,
                "completed_at": item.completed_at,
                "duration_seconds": item.duration_seconds,
                "metadata": filter_research_metadata(item.research_meta),
                "progress": item.progress,
                "title": item.title,
            }

            # Calculate duration if not set
            if not data["duration_seconds"] and data["created_at"]:
                data["duration_seconds"] = calculate_duration(
                    data["created_at"], data["completed_at"]
                )

            history_data.append(data)

        return jsonify(
            {
                "history": history_data,
                "total": total,
                "page": page,
                "per_page": per_page,
                "total_pages": (total + per_page - 1) // per_page,
            }
        )

    except Exception:
        logger.exception("Error fetching history")
        return jsonify(
            {
                "status": "error",
                "message": "An internal error occurred while fetching the history.",
            }
        ), 500
    finally:
        db_session.close()


@research_bp.route("/api/research/<string:research_id>")
@login_required
def api_get_research(research_id):
    """Get research details using ORM."""
    try:
        with get_user_db_session() as db_session:
            research = (
                db_session.query(ResearchHistory)
                .filter_by(id=research_id)
                .first()
            )

            if not research:
                return jsonify(
                    {"status": "error", "message": "Research not found"}
                ), 404

            # Convert to dictionary
            data = {
                "id": research.id,
                "query": research.query,
                "mode": research.mode,
                "status": research.status,
                "created_at": research.created_at,
                "completed_at": research.completed_at,
                "duration_seconds": research.duration_seconds,
                "metadata": strip_settings_snapshot(research.research_meta),
                "progress": research.progress,
                "title": research.title,
            }

            # Add logs if available
            if research_id in active_research:
                data["logs"] = active_research[research_id].get("log", [])

            return jsonify(data)

    except Exception:
        logger.exception("Error fetching research")
        return jsonify(
            {
                "status": "error",
                "message": "An internal error occurred while fetching the research.",
            }
        ), 500


# Add more converted routes as needed...
