import os
import re
import uuid
import logging
import json
import sys
from openai import OpenAI
print("📍 being here 1", flush=True)
from dotenv import load_dotenv
from flask import Flask, request, jsonify
from openai import OpenAI
from db import SessionLocal, init_db
# import models
from utils.prompt_manager import build_messages_payload
from models import Session as ChatSession, User, Case
from models import Message
from flask import render_template
from models import Topic
from sqlalchemy.sql import func

client = OpenAI()  # Uses env var OPENAI_API_KEY automatically

load_dotenv()

print(f"🔑 OPENAI_API_KEY ends with: ...{os.getenv('OPENAI_API_KEY')[-4:]}")
print(f"🗄 DB user: {os.getenv('DB_USER')}")

openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

app = Flask(__name__)

init_db()  # ← now creates *all* tables from models.py

# @app.route("/")
# def hello():
#    return "✅ Dynbot backend is running."

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/init-session", methods=["POST"])
def init_session():
    db = SessionLocal()
    data = request.get_json()

    tenant_id = data.get("tenant_id", 1)
    user_id = data.get("user_id", 1)
    session_token = data.get("session_token", str(uuid.uuid4()))

    # Ensure user exists
    user = db.query(User).filter_by(id=user_id).first()
    if not user:
        user = User(id=user_id, tenant_id=tenant_id, username="Default User", email="default@example.com")
        db.add(user)
        db.commit()

    # Always create a new session
    new_session = ChatSession(
        tenant_id=tenant_id,
        user_id=user_id,
        session_token=session_token,
    )
    db.add(new_session)
    db.commit()
    db.refresh(new_session)

    # Create a case before closing the session
    case = Case(
        tenant_id=tenant_id,
        user_id=user_id,
        session_id=new_session.id
    )
    db.add(case)
    db.commit()
    db.refresh(case)

    # ✅ Access attributes before db.close()
    response = {
        "session_id": new_session.id,
        "session_token": session_token,
        "case_id": case.id
    }

    db.close()
    return jsonify(response)


@app.route("/cases", methods=["POST"])
def create_case():
    db = SessionLocal()
    tenant_id = request.json.get("tenant_id", 1)  # default tenant
    new = models.Case(tenant_id=tenant_id, title=request.json.get("title",""))
    db.add(new); db.commit(); db.refresh(new)
    db.close()
    return jsonify({"case_id": new.id}), 201

@app.route("/cases/<int:case_id>/history", methods=["GET"])
def get_history(case_id):
    db = SessionLocal()
    msgs = db.query(models.Message).filter_by(case_id=case_id).order_by(models.Message.timestamp).all()
    fups = db.query(models.FollowupQuestion).join(models.Message).filter(models.Message.case_id==case_id).all()
    db.close()
    return jsonify({
        "messages": [{"role":m.role,"content":m.content,"timestamp":m.timestamp.isoformat()} for m in msgs],
        "followups": [{"message_id":f.message_id,"question_text":f.question_text} for f in fups]
    })


@app.route("/cases/<int:case_id>/messages", methods=["POST"])
def handle_message(case_id):
    db = SessionLocal()
    try:
        data = request.get_json()
        user_input = data.get("content")
        tenant_id = data.get("tenant_id")

        # Store user message
        db.add(Message(case_id=case_id, role="user", content=user_input))
        db.commit()

        # Determine iteration (number of user messages so far)
        user_messages = db.query(Message).filter_by(case_id=case_id, role="user").order_by(Message.timestamp).all()
        turn = len(user_messages) - 1  # zero-based index: 0, 1, 2

        # Select prompt by turn
        if turn == 0:
            prompt = f"""
You are a project management coach. The user will give you a topic, such as a risk or delay symptom.
Please list the most common root causes for this issue as a bullet list, sorted by importance.
Start each point with a short title (2–4 words), followed by a brief explanation.
Return a maximum of 6 points. Do not suggest any follow-up questions.
"""
        elif turn == 1:
            prompt = f"""
You are a project management coach. The user will give you a specific issue.
Provide up to 6 effective strategies or interventions to prevent or mitigate this issue in future projects.
Structure your response as a bullet list, ordered by priority.
Include both practical tips and strategic actions.
Conclude your answer with: 'About which of the options do you like to know more?'
"""
        else:
            prompt = f"""
You are a project management expert. The user has explored an issue and its mitigation options.
Summarize the overall discussion in 4–6 bullet points including the original problem, the root cause chosen,
and the selected mitigation strategy. Highlight one actionable insight.
Present the output as a coaching-style summary for review.
"""

        messages = [
            {"role": "system", "content": prompt},
            {"role": "user", "content": user_input}
        ]

        print("📥 User input:", user_input)
        print("🧮 Turn:", turn)
        print("💬 Sending to OpenAI:", messages)

        openai_response = client.chat.completions.create(
            model="gpt-4",
            messages=messages,
            temperature=0.7,
        )
        reply = openai_response.choices[0].message.content.strip()

        # reply = openai_response.choices[0].message.content.strip()

        try:
            reply = openai_response.choices[0].message.content.strip()
        except Exception as e:
            print("❌ Failed to extract reply from OpenAI response:", openai_response)
            raise


        # Extract bullet titles for button choices (max 3)
        bullet_titles = re.findall(r"^\d+\.\s\*\*(.*?)\*\*", reply, re.MULTILINE)
        choices = bullet_titles[:3]

        # Determine summary flag
        is_summary = turn >= 2

        # Store assistant reply
        db.add(Message(case_id=case_id, role="assistant", content=reply))
        db.commit()

        return jsonify({
            "reply": reply,
            "choices": choices if not is_summary else [],
            "followups": [],  # followups unused in current design
            "is_summary": is_summary
        })

    except Exception as e:
        import traceback
        traceback.print_exc()  # 👈 this will print the full error to the journal
        print("❌ Error in /messages:", str(e))
        return jsonify({"error": "Internal server error"}), 500

    finally:
        db.close()


def generate_summary_for_case(db, case_id):
    messages = db.query(Message).filter_by(case_id=case_id).order_by(Message.timestamp).all()
    user_inputs = [m.content for m in messages if m.role == "user"]
    assistant_replies = [m.content for m in messages if m.role == "assistant"]

    joined = "\n\n".join(
        f"User: {u}\nAssistant: {a}"
        for u, a in zip(user_inputs, assistant_replies)
    )

    prompt = [
        {"role": "system", "content": "You are an assistant that generates executive summaries of project analysis conversations."},
        {"role": "user", "content": f"Summarize the following dialog into a concise executive summary:\n\n{joined}"}
    ]

    resp = openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=prompt
    )

    return resp.choices[0].message.content

@app.route("/tenants", methods=["POST"])
def create_tenant():
    db = SessionLocal()
    name = request.json["name"]
    t = models.Tenant(name=name)
    db.add(t); db.commit(); db.refresh(t)
    db.close()
    return jsonify({"tenant_id": t.id}), 201


@app.route("/topics/random", methods=["GET"])
def get_random_topics():
    db = SessionLocal()
    tenant_id = 1  # or dynamic if implemented
    raw_topics = db.query(Topic)\
        .filter_by(tenant_id=tenant_id)\
        .order_by(func.random())\
        .limit(3)\
        .all()

    # Replace {topic} in question field
    results = []
    for t in raw_topics:
        filled_question = t.question.replace("{topic}", t.topic)
        results.append({
            "topic": t.topic,
            "question": filled_question
        })

    db.close()
    return jsonify(results)    


if __name__ == '__main__':
    app.run(
        host='0.0.0.0',
        port=5002,
        ssl_context=(
            '/var/www/html/decompression/certs/fullchain.pem',
            '/var/www/html/decompression/certs/privkey.pem'
        ),
        debug=True
    )

