import os
import json
import subprocess
import requests
import pandas as pd
import logging
from logging.handlers import RotatingFileHandler

# --- CONFIGURAZIONE E LOGGING ---

def load_config(config_path):
    with open(config_path, encoding="utf-8") as f:
        return json.load(f)

def setup_logging(log_dir, log_file, debug=False):
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(log_dir, log_file)
    logging.basicConfig(
        level=logging.DEBUG if debug else logging.INFO,
        format="%(asctime)s [%(levelname)s] %(message)s",
        handlers=[
            RotatingFileHandler(log_path, maxBytes=5*1024*1024, backupCount=3, encoding="utf-8"),
            logging.StreamHandler()
        ]
    )

# --- ESTRAZIONE DATI DAI FILE MDB ---

def extract_data_from_mdb(mdb_path, tables):
    extracted_data = {}
    for table in tables:
        try:
            # Use mdb-export to extract data
            result = subprocess.run(["mdb-export", mdb_path, table], capture_output=True, text=True)
            if result.returncode == 0:
                # Convert CSV output to DataFrame
                df = pd.read_csv(pd.compat.StringIO(result.stdout))
                extracted_data[table] = df
            else:
                logging.error(f"Failed to extract table {table} from {mdb_path}: {result.stderr}")
        except Exception as e:
            logging.error(f"Error extracting table {table}: {e}")
    return extracted_data

# --- INVIO DATI ALL'API ---

def send_to_api(endpoint, token, payload):
    headers = {
        'Authorization': f'Bearer {token}',
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    }
    try:
        response = requests.post(endpoint, headers=headers, json=payload)
        response.raise_for_status()  # Raise an error for bad responses
        logging.info(f"Data sent to {endpoint}: {response.json()}")
    except requests.exceptions.RequestException as e:
        logging.error(f"Error sending data to API: {e}")

# --- PROCESSAMENTO E INVIO DEI DATI ---

def process_and_send_data(extracted_data, mappings, token):
    for mapping in mappings:
        table = mapping['table']
        endpoint = mapping['endpoint']
        payload_fields = mapping['payload_fields']
        
        if table in extracted_data:
            df = extracted_data[table]
            for _, row in df.iterrows():
                payload = {new_key: row[old_key] for old_key, new_key in payload_fields.items() if old_key in row}
                send_to_api(endpoint, token, payload)

# --- MAIN ---

if __name__ == "__main__":
    base_dir = os.path.dirname(os.path.abspath(__file__))
    config_path = os.path.join(base_dir, "agent_config.json")
    
    # Load configuration
    cfg = load_config(config_path)
    setup_logging(cfg["LogDirectory"], cfg.get("LogFile", "agent.log"), cfg.get("Debug", False))
    
    # Define the MDB files and tables to extract
    input_directory = cfg["InputDirectory"]
    mdb_files = [f for f in os.listdir(input_directory) if f.endswith('.mdb')]
    tables_to_extract = ["stabili", "fornitori", "condomin"]  # Specify the tables you want to extract

    # Process each MDB file
    for mdb_file in mdb_files:
        mdb_path = os.path.join(input_directory, mdb_file)
        logging.info(f"Processing MDB file: {mdb_path}")
        
        extracted_data = extract_data_from_mdb(mdb_path, tables_to_extract)
        process_and_send_data(extracted_data, cfg["SyncMappings"], cfg["AdminToken"])

    logging.info("Data extraction and sending completed.")