import os
import sys
import traceback as tb

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../")))

from flask import Flask, request, jsonify, g
from flask_cors import CORS
from graphql import graphql_sync
from schema import schema
from models.session_models import (
    SessionOperations,
    SESSION_COOKIE_NAME,
    SESSION_TTL_HOURS,
)
from ff_crud.crud import DBClient
from ff_crud import __config as connection_config

app = Flask(__name__)
# CORS(
#     app,
#     supports_credentials=True,
#     origins=["http://localhost:3000", "https://fireflysolar.tech"],
# )  # This will allow all domains by default


def get_db():
    if not hasattr(g, "db_client"):
        g.db_client = DBClient(connection_config.firefly_dev)
        g.db_client._ensure_connection()
    return g.db_client


@app.before_request
def load_current_user():
    """
    Load the current user + session from the ff_session cookie (if present)
    and attach them to flask.g so resolvers can access them.
    """
    g.current_user = None
    g.current_session = None

    get_db()  # Ensure DB client is ready

    # Debug so we know this is firing
    print(f"[SESSION] before_request fired for path={request.path}")
    print("[SESSION] Cookies on request:", dict(request.cookies))

    session_id = request.cookies.get(SESSION_COOKIE_NAME)
    if not session_id:
        print("[SESSION] No ff_session cookie found")
        return  # no session cookie → unauthenticated

    try:
        db_client = get_db()
        sessions = SessionOperations(db_client)
        session, user = sessions.get_session_with_user(session_id)

        print("[SESSION] DB lookup returned:", session, user)

        if session and user:
            # session is a dict (TypedDict), so use [] not .
            print(
                f"[SESSION] Loaded session for user_id={user['id']} "
                f"session_id={session['session_id'][:12]}..."
            )

            g.current_session = session

            # SessionUser in your models has: id, name, email, role
            # We'll normalize to what the frontend expects: role_name + optional role_id

            g.current_user = {
                "id": user["id"],
                "email": user["email"],
                "name": user["name"],
                "roles": user["roles"],
                "dept_id": user["dept_id"],
            }

            print("[SESSION] g.current_user set to:", g.current_user)
        else:
            print("[SESSION] No valid session found for this session_id")
    except Exception as e:
        print("[SESSION] Error in load_current_user:", e)
        print(tb.format_exc())
        g.current_user = None
        g.current_session = None


print("[INFO] GraphQL server is starting...")


@app.teardown_appcontext
def close_db(exception=None):
    db = getattr(g, "db_client", None)
    if db is not None:
        try:
            db.close()  # or db._close_connection()
        except Exception:
            pass


@app.route("/", methods=["GET", "POST", "OPTIONS"])
def graphql_server():
    if request.method == "OPTIONS":
        # Handle CORS preflight
        response = app.make_default_options_response()
        headers = response.headers

        headers["Access-Control-Allow-Origin"] = request.headers.get("Origin", "*")
        headers["Access-Control-Allow-Credentials"] = "true"
        headers["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS"
        headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"
        return response

    if request.method == "GET":
        # Simple HTML for GraphiQL interface
        return (
            """
        <!DOCTYPE html>
        <html>
          <head>
            <title>GraphiQL</title>
            <link href="https://cdnjs.cloudflare.com/ajax/libs/graphiql/1.4.2/graphiql.min.css" rel="stylesheet" />
          </head>
          <body style="margin: 0;">
            <div id="graphiql" style="height: 100vh;"></div>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
            <script src="https://cdnjs.cloudflare.com/ajax/libs/graphiql/1.4.2/graphiql.min.js"></script>
            <script>
              const graphQLFetcher = graphQLParams =>
                fetch('/graphql', {
                  method: 'post',
                  headers: { 'Content-Type': 'application/json' },
                  body: JSON.stringify(graphQLParams),
                })
                  .then(response => response.json())
                  .catch(() => response.text());
                ReactDOM.render(
                  React.createElement(GraphiQL, { fetcher: graphQLFetcher }),
                  document.getElementById('graphiql'),
                );
            </script>
          </body>
        </html>
        """,
            200,
        )

    # POST (GraphQL query)
    data = request.get_json()
    result = graphql_sync(
        schema,
        data.get("query"),
        variable_values=data.get("variables"),
        context_value=request,
    )

    payload = {}
    if result.errors:
        payload["errors"] = [str(e) for e in result.errors]
    if result.data:
        payload["data"] = result.data

    resp = jsonify(payload)

    # ----- SET SESSION COOKIE IF LOGIN CREATED ONE -----
    session_id = getattr(g, "new_session_id", None)
    if session_id:
        print(f"[SESSION] Setting cookie ff_session={session_id[:12]}... on response")
        is_prod = request.host.endswith("fireflysolar.tech")

        resp.set_cookie(
            key=SESSION_COOKIE_NAME,
            value=session_id,
            httponly=True,
            secure=is_prod,  # ✅ False on localhost
            samesite="None" if is_prod else "Lax",  # ✅
            max_age=SESSION_TTL_HOURS * 3600,
            path="/",
        )

    return resp, 200


@app.route("/webhook/ringcentral", methods=["POST"])
def ringcentral_webhook():
    print("[DEBUG] Headers:", dict(request.headers))
    print("[DEBUG] Body:", request.get_data())

    validation_token = request.headers.get("Validation-Token")
    if validation_token:
        # respond with token
        response = jsonify({"status": "validation"})
        response.headers["Validation-Token"] = validation_token
        print(
            "[INFO] Responded to RingCentral validation with token:", validation_token
        )
        return response, 200

    # Normal webhook processing
    data = request.get_json()
    print("[INFO] Received RingCentral webhook:", data)
    return jsonify({"status": "ok"}), 200
