import requests
import os
import random
import json
import uuid
from .auth import get_token

API_BASE_URL = "https://aigendb-backend-production.up.railway.app"

def get_ml_server():
    return load_config().get("services", {}).get("ml_server")

def get_access_token():
    return load_config().get("services", {}).get("access_token")

def get_db_server():
    server = load_config().get("services", {}).get("db_server", "")
    return server.rstrip("/") if server else ""

def get_provisioner_key():
    return load_config().get("services", {}).get("provisioner_api_key", "")

def get_headers():
    token = get_token()
    return {
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json"
    }

from .config import get_config, load_config

def get_project_id():
    env_config = load_config()
    return env_config.get("firebase", {}).get("projectId", "aigendb")


def fetch_user_credits():
    try:
        response = requests.get(f"{API_BASE_URL}/api/user/credits", headers=get_headers(), timeout=10)
        if response.status_code == 200:
            return response.json()
            
        if response.status_code in (401, 403):
            from .config import clear_config
            clear_config()
            print("\n[yellow]Your session has expired or is invalid. Please log in again.[/yellow]")
            import sys
            sys.exit(1)
            
        raise Exception(f"API Error: {response.status_code} - {response.text}")
    except Exception as e:
        print(f"\n[red]Error fetching credits: {str(e)}[/red]")
        return {"credits": 0, "subscription_type": "Free"}

def generate_schema(schema_payload):
    try:
        headers = {"Content-Type": "application/json"}
        if get_access_token():
            headers["Authorization"] = f"Bearer {get_access_token()}"
        ml_server_base = get_ml_server().rstrip("/") if get_ml_server() else "http://localhost:8000"
        response = requests.post(f"{ml_server_base}/generate", json=schema_payload, headers=headers, timeout=30)
        if response.status_code == 200:
            return response.json()
        print(f"[red]Error from ML Server: {response.text}[/red]")
        raise Exception("API Error")
    except Exception as e:
        print(f"[red]Failed to connect to ML Server: {e}[/red]")
        return {"project": schema_payload.get("project_name", "unknown"), "sql_queries": []}

def check_schema_status(project_id):
    try:
        response = requests.get(f"{API_BASE_URL}/api/schema/status/{project_id}", headers=get_headers(), timeout=5)
        if response.status_code == 200:
            return response.json()
        raise Exception("API Error")
    except:
        if random.random() > 0.5:
             return {
                 "status": "completed",
                 "generated_sql": "CREATE TABLE users (id serial PRIMARY KEY, name VARCHAR(255));\nCREATE TABLE gigs (id serial PRIMARY KEY, cost int);"
             }
        return {"status": "processing"}

def create_database(project_name, schema_sql):
    """Call the DB provisioner server to create a database for the user."""
    try:
        config = get_config()
        user_id = config.get("user_id", "unknown") if config else "unknown"
        # Fetch project_id from Firestore
        projects = fetch_user_projects()
        project = next((p for p in projects if p.get("project_name") == project_name), {})
        project_id = project.get("project_id", project_name)

        url = f"{get_db_server()}/create-database"
        headers = {
            "Authorization": f"Bearer {get_provisioner_key()}",
            "Content-Type": "application/json"
        }
        payload = {
            "user_id": user_id,
            "project_id": project_id,
            "schema_sql": schema_sql
        }
        response = requests.post(url, json=payload, headers=headers, timeout=60)
        if response.status_code == 200:
            return response.json()
        raise Exception(f"DB Server error: {response.status_code} - {response.text}")
    except Exception as e:
        print(f"[red]Failed to provision database: {e}[/red]")
        return None


def save_db_credentials(project_name, database_name, connection_url, password):
    """Persist DB credentials to the project document via the backend."""
    try:
        payload = {
            "database_name": database_name,
            "connection_url": connection_url,
            "db_password": password
        }
        response = requests.patch(
            f"{API_BASE_URL}/api/projects/{project_name}/credentials", 
            json=payload, 
            headers=get_headers(), 
            timeout=10
        )
        return response.status_code == 200
    except Exception:
        return False

def fetch_user_projects():
    try:
        response = requests.get(f"{API_BASE_URL}/api/projects", headers=get_headers(), timeout=10)
        if response.status_code == 200:
            return response.json().get("projects", [])
        return []
    except Exception as e:
        return []

def save_user_project(project_name, user_input, query0):
    try:
        project_id = str(uuid.uuid4())
        payload = {
            "project_id": project_id,
            "project_name": project_name,
            "user_input": json.dumps(user_input),
            "query0": query0
        }
        response = requests.post(f"{API_BASE_URL}/api/projects/{project_name}", json=payload, headers=get_headers(), timeout=10)
        return response.status_code == 200
    except Exception as e:
        return False

def delete_database(database_name):
    """Tell the provisioner to drop the RDS database for a project."""
    try:
        url = f"{get_db_server()}/delete-database"
        headers = {
            "Authorization": f"Bearer {get_provisioner_key()}",
            "Content-Type": "application/json"
        }
        response = requests.delete(url, json={"database_name": database_name}, headers=headers, timeout=30)
        return response.status_code == 200
    except Exception as e:
        print(f"[red]Failed to delete database: {e}[/red]")
        return False



def delete_user_project(project_name):
    try:
        response = requests.delete(f"{API_BASE_URL}/api/projects/{project_name}", headers=get_headers(), timeout=10)
        return response.status_code == 200
    except:
        return False

def append_project_query(project_name, new_query):
    try:
        projects = fetch_user_projects()
        target_project = next((p for p in projects if p.get("project_name") == project_name), None)
        
        next_idx = 1
        if target_project and "queries" in target_project:
            queries = target_project["queries"]
            if queries:
                highest_idx = max([int(k.replace("query", "")) for k in queries.keys() if k.replace("query", "").isdigit()] + [-1])
                next_idx = highest_idx + 1
                
        query_key = f"query{next_idx}"
        payload = { query_key: new_query }
        
        response = requests.post(f"{API_BASE_URL}/api/projects/{project_name}/queries", json=payload, headers=get_headers(), timeout=10)
        return response.status_code == 200
    except Exception as e:
        return False

def deduct_user_credit(project_name):
    try:
        response = requests.post(f"{API_BASE_URL}/api/projects/{project_name}/deduct-credit", json={}, headers=get_headers(), timeout=10)
        return response.status_code == 200
    except Exception as e:
        print(f"[red]Failed to log credit usage: {str(e)}[/red]")
        return False
