import json
import sqlite3  # For database access
import logging

# Function to retrieve the latest model information from the database
def get_latest_model(db_path, region, start_year, end_year):
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Query the latest model run based on region and years
    cursor.execute("""
        SELECT * FROM model_runs 
        WHERE region = ? AND start_year = ? AND end_year = ? 
        ORDER BY timestamp DESC LIMIT 1
    """, (region, start_year, end_year))
    
    result = cursor.fetchone()
    conn.close()

    if result:
        logging.info(f"Latest model found: {result}")
        (
            model_id, model_type, data_path, region, start_year, end_year, train_years_str,
            test_years_str, timestamp, accuracy, f1_score, precision, recall, feature_importance_str,
            class_mapping_str, model_file_path
        ) = result
        
        # Convert JSON-like strings to Python objects (list and dict)
        train_years = json.loads(train_years_str)
        test_years = json.loads(test_years_str)
        class_mapping = json.loads(class_mapping_str)
        feature_importance = json.loads(feature_importance_str) if feature_importance_str else None
        
        # Return all relevant data as a dictionary
        return {
            "start_year": start_year,
            "end_year": end_year,
            "region": region,
            "test_years": test_years,
            "model_timestamp": timestamp,
            "model_file_path": model_file_path,
            "class_mapping": class_mapping,
            "accuracy": accuracy,
            "f1_score": f1_score,
            "precision": precision,
            "recall": recall,
        }

    else:
        logging.info("No model found for the specified region and years.")
        return None



def log_model_run(db_path, model_type, data_path, region, start_year, end_year, train_years, test_years, timestamp, accuracy, f1, precision, recall, feature_importance, class_mapping, model_file_path):
    # Convert lists and dictionaries to JSON strings for easy storage
    train_years_str = json.dumps(train_years)
    test_years_str = json.dumps(test_years)
    class_mapping_str = json.dumps(class_mapping)
    
    # Convert the feature_importance ndarray to a list
    feature_importance_str = json.dumps(feature_importance.tolist()) if feature_importance is not None else None

    # Connect to the SQLite database
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    # Ensure the table exists (create it if not)
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS model_runs (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            model_type TEXT,
            data_path TEXT,
            region TEXT,
            start_year INTEGER,
            end_year INTEGER,
            train_years TEXT,
            test_years TEXT,
            timestamp TEXT,
            accuracy REAL,
            f1_score REAL,
            precision REAL,
            recall REAL,
            feature_importance TEXT,
            class_mapping TEXT,
            model_file_path TEXT
        )
    """)
    
    # Insert the new model run
    cursor.execute("""
        INSERT INTO model_runs (model_type, data_path, region, start_year, end_year, train_years, test_years, timestamp, accuracy, f1_score, precision, recall, feature_importance, class_mapping, model_file_path)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    """, (model_type, data_path, region, start_year, end_year, train_years_str, test_years_str, timestamp, accuracy, f1, precision, recall, feature_importance_str, class_mapping_str, model_file_path))
    
    conn.commit()
    conn.close()

    logging.info("Model details logged to SQLite database successfully.")
 
 
 
 # Set Paths and Parameters from Arguments or Database
def read_db(read_db, db_path, region, start_year, end_year):
    if read_db:
        logging.info("Fetching model details from the database.")
        model_info = get_latest_model(db_path, region, start_year, end_year)
        if model_info:
            model_timestamp = model_info["model_timestamp"]
            test_years = model_info["test_years"]
            accuracy = model_info.get("accuracy")
            f1_score = model_info.get("f1_score")
            precision = model_info.get("precision")
            recall = model_info.get("recall")
            class_mapping = model_info.get("class_mapping")
            
            # Return all necessary values here
            return {
                "model_timestamp": model_timestamp,
                "test_years": test_years,
                "accuracy": accuracy,
                "f1_score": f1_score,
                "precision": precision,
                "recall": recall,
                "class_mapping": class_mapping
            }
        else:
            raise ValueError("No model found in the database for the given region and years.")
    else:
        logging.info("Skipping database lookup as `read_db` is set to False.")
        return None

