import os
import json
import time
import pandas as pd
from sqlalchemy import create_engine, text
from dotenv import load_dotenv

from llm_client import analyze_internal_comments_batch 

from llm_client import (
    analyze_internal_comments_batch,
    get_internal_prompt_version
)


load_dotenv()

DB_URI = os.getenv("MYSQL_URI")
engine = create_engine(DB_URI, pool_pre_ping=True)

BATCH_SIZE = 20

# MODEL_VERSION = "llama3_internal_v1"


def safe_float(val, default=0.5):
    try:
        return float(val)
    except:
        return default


# ---------------------------
# FETCH UNPROCESSED INTERNAL COMMENTS
# ---------------------------

def fetch_unprocessed_internal_comments(limit=None):

    query = """
    SELECT *
    FROM article_user_comment
    WHERE external_comment_id IS NULL
    AND llm_sentiment IS NULL
    AND deleted_on IS NULL
    ORDER BY created_on ASC
    """

    params = {}
    if limit is not None:
        query += "\n    LIMIT :limit"
        params["limit"] = int(limit)

    with engine.connect() as conn:
        df = pd.read_sql(text(query), conn, params=params)

    return df


# ---------------------------
# INSERT RESULTS
# ---------------------------

def insert_processed(rows):

    if not rows:
        return

    query = text("""
        UPDATE article_user_comment SET
            llm_confidence     = :llm_confidence,
            llm_sentiment      = :llm_sentiment,
            llm_emotion        = :llm_emotion,
            llm_impact_score   = :llm_impact_score,
            llm_toxicity_score = :llm_toxicity_score,
            llm_language_code  = :llm_language_code,
            llm_prompt_version = :llm_prompt_version,
            llm_raw_output     = :llm_raw_output,
            model_version      = :model_version
        WHERE id = :auc_id
    """)

    with engine.begin() as conn:
        conn.execute(query, rows)


# ---------------------------
# PROCESS INTERNAL COMMENTS
# ---------------------------

def process_internal_comments(limit=None):

    total_processed = 0
    failed_batches = 0

    df = fetch_unprocessed_internal_comments(limit=limit)

    if df.empty:
        print("No internal comments to process")
        return 0

    results = []

    for i in range(0, len(df), BATCH_SIZE):

        batch_df = df.iloc[i:i+BATCH_SIZE]

        comments = batch_df["msg"].tolist()

        llm_outputs, used_model = analyze_internal_comments_batch(comments)

        if not llm_outputs:
            print(f"[LLM FAIL] internal batch starting at {i}")
            failed_batches += 1
            continue

        for item in llm_outputs:

            try:
                idx = item.get("index")

                if idx is None:
                    continue

                try:
                    idx = int(idx) - 1
                except:
                    continue

                if idx < 0 or idx >= len(batch_df):
                    continue

                row = batch_df.iloc[idx]


                results.append({
                    "auc_id": row["id"],
                    "llm_confidence": safe_float(item.get("confidence", 0.5)),
                    "llm_sentiment": item.get("sentiment", "Neutral"),
                    "llm_emotion": item.get("emotion", "neutral"),
                    "llm_impact_score": round(safe_float(item.get("impact_score", 0.5)) * 2 - 1, 3),
                    "llm_toxicity_score": safe_float(item.get("toxicity", 0.0)),
                    "llm_language_code": item.get("language_code", "en"),
                    "llm_prompt_version": get_internal_prompt_version(),
                    "llm_raw_output": json.dumps(item),
                    "model_version": used_model
                })

            except Exception as e:
                print(f"[MAPPING ERROR] {e}")
                continue

        total_processed += 1

    insert_processed(results)

    print("\n====================")
    print("INTERNAL PROCESSING SUMMARY")
    print("====================")
    print("Fetched:", len(df))
    print(f"To insert: {len(results)}")
    print(f"Total LLM outputs processed: {total_processed}")
    print(f"Failed batches: {failed_batches}")
    print(f"Total DB rows inserted: {len(results)}")

    return len({result["auc_id"] for result in results})


# ---------------------------
# MAIN
# ---------------------------

if __name__ == "__main__":

    while True:
        processed = process_internal_comments()
        print(f"[DEBUG] processed batch size: {processed}")

        if processed is None or processed == 0:
            print("✅ ALL INTERNAL COMMENTS PROCESSED")
            break


        time.sleep(1)
