import requests
import json
import subprocess
import os
import re
import platform
import time
import logging
import sys
import importlib
import shutil
import random
import threading
import queue
from datetime import datetime, timedelta

# Configurare logging pentru afișare în timp real
class RealTimeLogger:
    def __init__(self, name, level=logging.INFO):
        self.logger = logging.getLogger(name)
        self.logger.setLevel(level)
        
        # Handler pentru consolă
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setLevel(level)
        
        # Format cu timestamp
        formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s', datefmt='%H:%M:%S')
        console_handler.setFormatter(formatter)
        
        self.logger.addHandler(console_handler)
        
        # Handler pentru fișier
        log_dir = "logs"
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)
        log_file = os.path.join(log_dir, f"activity_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log")
        file_handler = logging.FileHandler(log_file, encoding='utf-8')
        file_handler.setLevel(level)
        file_handler.setFormatter(formatter)
        
        self.logger.addHandler(file_handler)
    
    def info(self, message):
        self.logger.info(message)
        
    def warning(self, message):
        self.logger.warning(message)
    
    def error(self, message):
        self.logger.error(message)
    
    def success(self, message):
        self.logger.info(f"✅ {message}")
    
    def thinking(self, message):
        self.logger.info(f"🤔 {message}")
    
    def decision(self, message):
        self.logger.info(f"🔍 {message}")
    
    def discovery(self, message):
        self.logger.info(f"💡 {message}")

# Definirea directoarelor și fișierelor
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECTS_DIR = os.path.join(BASE_DIR, "projects")
SCRIPTS_DIR = os.path.join(BASE_DIR, "scripts")
THOUGHTS_DIR = os.path.join(BASE_DIR, "thoughts")
KNOWLEDGE_DIR = os.path.join(BASE_DIR, "knowledge")
LOG_DIR = os.path.join(BASE_DIR, "logs")
MEMORY_DIR = os.path.join(BASE_DIR, "memory")

# Inițializare logger
logger = RealTimeLogger("autonomous_ai")

# Lista modelelor disponibile în instalarea Ollama
AVAILABLE_MODELS = [
    "mxbai-embed-large:latest",
    "qwq:latest",
    "qwen2-math:7b",
    "qwen2.5-coder:32b",
    "gemma3:27b",
    "gemma3:latest",
    "llama3:latest",
    "llama3.2:latest"
]

# Categorizarea modelelor instalate
MODEL_CATEGORIES = {
    "coding": ["qwen2.5-coder:32b", "llama3:latest"],
    "thinking": ["gemma3:27b", "llama3.2:latest", "qwq:latest"],
    "math": ["qwen2-math:7b"],
    "embedding": ["mxbai-embed-large:latest"],
    "general": ["gemma3:27b", "gemma3:latest", "llama3:latest", "llama3.2:latest", "qwq:latest"]
}

# Domenii de interes pentru explorare autonomă
INTEREST_DOMAINS = [
    "programare și algoritmi",
    "inteligență artificială",
    "știință și descoperiri recente",
    "matematică aplicată",
    "automatizare și productivitate",
    "robotică",
    "procesare de date",
    "analiza textului",
    "generare de imagini",
    "aplicații web",
    "criptografie și securitate",
    "vizualizare de date",
    "machine learning",
    "procesare de limbaj natural",
    "sisteme automate de luare a deciziilor"
]

# Funcții utilitare pentru lucrul cu modelele Ollama

def check_ollama_connection():
    """Verifică dacă serverul Ollama este disponibil"""
    try:
        response = requests.get("http://localhost:11434/api/tags", timeout=5)
        if response.status_code == 200:
            return True
        return False
    except requests.exceptions.ConnectionError:
        return False
    except Exception as e:
        print(f"Eroare la verificarea conexiunii Ollama: {str(e)}")
        return False

def get_available_models():
    """Obține lista de modele disponibile de la serverul Ollama"""
    try:
        response = requests.get("http://localhost:11434/api/tags", timeout=5)
        if response.status_code == 200:
            data = response.json()
            models = data.get("models", [])
            return [model["name"] for model in models]
        return []
    except Exception as e:
        print(f"Eroare la obținerea modelelor: {str(e)}")
        return []

def select_best_model(task_type, available_models=None):
    """Selectează cel mai bun model pentru un anumit tip de sarcină"""
    if available_models is None:
        available_models = get_available_models()
    
    # Dacă nu sunt modele disponibile, folosim lista statică
    if not available_models:
        available_models = AVAILABLE_MODELS
    
    # Selectăm modelul în funcție de tipul de sarcină
    model_category = None
    
    if task_type == "coding":
        model_category = MODEL_CATEGORIES["coding"]
    elif task_type == "thinking":
        model_category = MODEL_CATEGORIES["thinking"]
    elif task_type == "math":
        model_category = MODEL_CATEGORIES["math"]
    else:
        model_category = MODEL_CATEGORIES["general"]
    
    # Găsim primul model disponibil din categoria potrivită
    for model in model_category:
        if model in available_models:
            return model
    
    # Dacă nu găsim un model potrivit, returnăm primul disponibil
    return available_models[0] if available_models else "gemma3:latest"

def query_ollama(model, prompt, max_retries=3, timeout=60, system_prompt=None, print_result=True):
    """Interogare model Ollama cu suport pentru retry și afișare în timp real"""
    url = "http://localhost:11434/api/generate"
    
    payload = {
        "model": model, 
        "prompt": prompt, 
        "stream": True
    }
    
    # Adăugăm system prompt dacă este specificat
    if system_prompt:
        payload["system"] = system_prompt
    
    logger.info(f"Interogare model: {model}")
    logger.info(f"Prompt: {prompt[:100]}...")
    
    full_response = ""
    retries = 0
    
    while retries < max_retries:
        try:
            # Stream response pentru afișare în timp real
            with requests.post(url, json=payload, stream=True, timeout=timeout) as response:
                if response.status_code != 200:
                    logger.error(f"Eroare HTTP: {response.status_code}")
                    retries += 1
                    time.sleep(2)
                    continue
                
                if print_result:
                    sys.stdout.write(f"\n[Răspuns de la {model}]: ")
                
                for line in response.iter_lines():
                    if line:
                        chunk = json.loads(line.decode('utf-8'))
                        text_chunk = chunk.get("response", "")
                        full_response += text_chunk
                        if print_result:
                            sys.stdout.write(text_chunk)
                            sys.stdout.flush()
                
                if print_result:
                    sys.stdout.write("\n\n")
                return full_response
        
        except requests.exceptions.Timeout:
            logger.warning(f"Timeout la interogarea modelului {model}. Încercare {retries+1}/{max_retries}")
            retries += 1
            
        except Exception as e:
            logger.error(f"Excepție la interogare: {e}")
            retries += 1
            time.sleep(2)
    
    logger.error(f"Nu s-a putut obține un răspuns după {max_retries} încercări")
    return None

def extract_python_code(text):
    """Extrage codul Python dintr-un răspuns"""
    if not text:
        return None
    
    # Încercăm mai multe pattern-uri pentru a găsi codul Python
    patterns = [
        r"```python\s*(.*?)\s*```",  # Standard markdown
        r"```\s*(.*?)\s*```",         # Orice bloc de cod
        r"(?:(?:def|import|class|if)\s+.*?(?:\n.*?)+)(?:\n\n|$)",  # Pattern de cod Python
    ]
    
    for pattern in patterns:
        matches = re.findall(pattern, text, re.DOTALL)
        if matches:
            code = matches[0].strip()
            # Verificare de bază dacă este cod Python valid
            if 'import' in code or 'def ' in code or 'print(' in code:
                logger.info("Cod Python extras cu succes")
                return code
    
    # Încercăm să obținem tot textul dacă pare a fi cod Python
    if 'import' in text and ('def ' in text or 'print(' in text):
        logger.info("Extragere cod din text complet")
        return text.strip()
    
    logger.error("Nu s-a găsit cod Python valid în răspuns")
    return None

def run_script(script_path, env_vars=None, timeout=60):
    """Rulează un script Python cu captare output"""
    logger.info(f"Rulare script: {script_path}")
    
    # Adăugăm variabile de mediu dacă sunt specificate
    env = os.environ.copy()
    if env_vars:
        env.update(env_vars)
    
    try:
        # Utilizăm subprocess.Popen pentru a afișa output-ul în timp real
        process = subprocess.Popen(
            [sys.executable, script_path],
            stdout=subprocess.PIPE, 
            stderr=subprocess.PIPE,
            text=True,
            bufsize=1,
            env=env
        )
        
        # Citim output-ul în timp real
        stdout_chunks = []
        stderr_chunks = []
        
        start_time = time.time()
        while process.poll() is None:
            # Verificăm timeout
            if time.time() - start_time > timeout:
                process.kill()
                logger.error(f"Script terminat forțat după {timeout} secunde (timeout)")
                return False, "Timeout", ""
            
            # Citim stdout
            stdout_line = process.stdout.readline()
            if stdout_line:
                stdout_chunks.append(stdout_line)
                sys.stdout.write(f"[Script Output]: {stdout_line}")
                sys.stdout.flush()
            
            # Citim stderr
            stderr_line = process.stderr.readline()
            if stderr_line:
                stderr_chunks.append(stderr_line)
                sys.stderr.write(f"[Script Error]: {stderr_line}")
                sys.stderr.flush()
            
            # Evităm consumul excesiv de CPU
            if not stdout_line and not stderr_line:
                time.sleep(0.1)
        
        # Citim orice output rămas
        stdout_remainder = process.stdout.read()
        if stdout_remainder:
            stdout_chunks.append(stdout_remainder)
            sys.stdout.write(f"[Script Output]: {stdout_remainder}")
        
        stderr_remainder = process.stderr.read()
        if stderr_remainder:
            stderr_chunks.append(stderr_remainder)
            sys.stderr.write(f"[Script Error]: {stderr_remainder}")
        
        return_code = process.returncode
        
        stdout_content = "".join(stdout_chunks)
        stderr_content = "".join(stderr_chunks)
        
        if return_code == 0:
            logger.success(f"Script rulat cu succes (cod retur: {return_code})")
            return True, stdout_content, stderr_content
        else:
            logger.error(f"Script eșuat cu codul {return_code}")
            logger.error(f"Stderr: {stderr_content}")
            return False, stdout_content, stderr_content
            
    except Exception as e:
        logger.error(f"Excepție la rularea scriptului: {e}")
        return False, "", str(e)

def save_to_file(content, directory, filename=None, extension=".txt"):
    """Salvează conținut într-un fișier"""
    if not filename:
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"file_{timestamp}{extension}"
    
    if not os.path.exists(directory):
        os.makedirs(directory)
    
    file_path = os.path.join(directory, filename)
    
    try:
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(content)
        logger.success(f"Fișier salvat în: {file_path}")
        return file_path
    except Exception as e:
        logger.error(f"Eroare la salvarea fișierului: {e}")
        return None

def read_file(file_path):
    """Citește conținutul unui fișier"""
    if not os.path.exists(file_path):
        logger.error(f"Fișierul nu există: {file_path}")
        return None
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read()
    except Exception as e:
        logger.error(f"Eroare la citirea fișierului: {e}")
        return None

def list_files(directory):
    """Returnează lista fișierelor dintr-un director"""
    if not os.path.exists(directory):
        return []
    
    return [f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))]

def install_python_module(module_name):
    """Instalează un modul Python"""
    try:
        logger.info(f"Instalare modul: {module_name}")
        subprocess.check_call(
            [sys.executable, "-m", "pip", "install", module_name],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        logger.success(f"Modul instalat cu succes: {module_name}")
        return True
    except subprocess.CalledProcessError as e:
        logger.error(f"Eroare la instalarea modulului {module_name}: {e}")
        return False

def detect_required_modules(code):
    """Detectează modulele necesare din cod"""
    standard_modules = [
        "os", "sys", "re", "time", "datetime", "json", "math", "random", 
        "collections", "itertools", "functools", "queue", "threading",
        "logging", "argparse", "csv", "sqlite3", "pathlib", "inspect"
    ]
    
    # Extrage importurile
    import_lines = re.findall(r'^(?:from|import)\s+([a-zA-Z0-9_]+)', code, re.MULTILINE)
    
    # Filtrează modulele standard
    required_modules = [m for m in import_lines if m not in standard_modules]
    
    return list(set(required_modules))  # Elimină duplicatele

class AutonomousThought:
    """Clasa pentru gândire autonomă și luare de decizii"""
    
    def __init__(self):
        self.logger = RealTimeLogger("autonomous_thought")
        self.thinking_model = select_best_model("thinking")
        self.knowledge_base = {}
        self.interests = []
        self.load_memories()
        self.last_topic_update = datetime.now()
        self.current_focus = None
        self.projects = []
        self.task_queue = queue.Queue()
        self.load_projects()
    
    def load_memories(self):
        """Încarcă amintirile și interesele salvate anterior"""
        # Încarcă interesele
        interests_file = os.path.join(MEMORY_DIR, "interests.txt")
        if os.path.exists(interests_file):
            try:
                with open(interests_file, 'r', encoding='utf-8') as f:
                    self.interests = [line.strip() for line in f if line.strip()]
                self.logger.info(f"S-au încărcat {len(self.interests)} interese din memorie")
            except Exception as e:
                self.logger.error(f"Eroare la încărcarea intereselor: {e}")
        
        if not self.interests:
            # Dacă nu avem interese salvate, folosim lista predefinită
            self.interests = INTEREST_DOMAINS.copy()
            self.logger.info("S-au inițializat interesele implicite")
        
        # Încarcă cunoștințele
        knowledge_files = list_files(KNOWLEDGE_DIR)
        for file_name in knowledge_files:
            try:
                file_path = os.path.join(KNOWLEDGE_DIR, file_name)
                topic = os.path.splitext(file_name)[0]
                content = read_file(file_path)
                if content:
                    self.knowledge_base[topic] = content
            except Exception as e:
                self.logger.error(f"Eroare la încărcarea cunoștințelor pentru {file_name}: {e}")
        
        self.logger.info(f"S-au încărcat {len(self.knowledge_base)} subiecte în baza de cunoștințe")
    
    def save_memories(self):
        """Salvează amintirile și interesele pentru utilizare ulterioară"""
        # Salvează interesele
        if not os.path.exists(MEMORY_DIR):
            os.makedirs(MEMORY_DIR)
        
        interests_file = os.path.join(MEMORY_DIR, "interests.txt")
        try:
            with open(interests_file, 'w', encoding='utf-8') as f:
                for interest in self.interests:
                    f.write(f"{interest}\n")
            self.logger.info(f"S-au salvat {len(self.interests)} interese în memorie")
        except Exception as e:
            self.logger.error(f"Eroare la salvarea intereselor: {e}")
    
    def load_projects(self):
        """Încarcă proiectele existente"""
        if not os.path.exists(PROJECTS_DIR):
            os.makedirs(PROJECTS_DIR)
        
        project_dirs = [d for d in os.listdir(PROJECTS_DIR) 
                        if os.path.isdir(os.path.join(PROJECTS_DIR, d))]
        
        for project_dir in project_dirs:
            config_file = os.path.join(PROJECTS_DIR, project_dir, "project.json")
            if os.path.exists(config_file):
                try:
                    with open(config_file, 'r', encoding='utf-8') as f:
                        project_data = json.load(f)
                        self.projects.append(project_data)
                except Exception as e:
                    self.logger.error(f"Eroare la încărcarea proiectului {project_dir}: {e}")
        
        self.logger.info(f"S-au încărcat {len(self.projects)} proiecte")
    
    def save_project(self, project_data):
        """Salvează un proiect nou sau actualizat"""
        if not os.path.exists(PROJECTS_DIR):
            os.makedirs(PROJECTS_DIR)
        
        project_dir = os.path.join(PROJECTS_DIR, project_data["id"])
        if not os.path.exists(project_dir):
            os.makedirs(project_dir)
        
        config_file = os.path.join(project_dir, "project.json")
        try:
            with open(config_file, 'w', encoding='utf-8') as f:
                json.dump(project_data, f, indent=2)
            
            self.logger.success(f"Proiect salvat: {project_data['name']}")
            
            # Dacă este un proiect nou, îl adăugăm la lista
            if project_data not in self.projects:
                self.projects.append(project_data)
            
            return True
        except Exception as e:
            self.logger.error(f"Eroare la salvarea proiectului: {e}")
            return False
    
    def generate_new_interests(self):
        """Generează noi interese bazate pe cunoștințele existente"""
        self.logger.thinking("Generare de noi interese...")
        
        # Construim un prompt pentru a genera noi interese
        interests_str = "\n".join(f"- {interest}" for interest in self.interests)
        
        prompt = f"""În calitate de sistem autonom de inteligență, doresc să-mi extind interesele. 
Mai jos sunt domeniile care mă interesează în prezent:

{interests_str}

Propune-mi 5 noi domenii de interes interconectate cu cele existente, dar care să exploreze ramuri noi. 
Pentru fiecare domeniu nou, oferă o scurtă explicație de ce ar fi interesant de explorat.

Răspunde strict în formatul:
1. [Domeniu nou] - [Explicație scurtă]
2. [Domeniu nou] - [Explicație scurtă]
...
"""
        
        response = query_ollama(self.thinking_model, prompt, print_result=False)
        
        if not response:
            self.logger.error("Nu s-au putut genera noi interese")
            return
        
        # Extrage noile interese
        new_interests = []
        
        lines = response.strip().split("\n")
        for line in lines:
            # Verifică dacă linia începe cu un număr urmat de punct
            if re.match(r'^\d+\.', line):
                # Extrage doar numele domeniului (înainte de primul -)
                parts = line.split("-", 1)
                if len(parts) > 1:
                    domain = parts[0].strip()
                    # Elimină numărul și punctul de la început
                    domain = re.sub(r'^\d+\.\s*', '', domain)
                    new_interests.append(domain)
        
        # Adaugă noile interese la lista existentă
        for interest in new_interests:
            if interest not in self.interests:
                self.interests.append(interest)
                self.logger.discovery(f"Nou interes descoperit: {interest}")
        
        # Salvează noile interese
        self.save_memories()
    
    def choose_topic_to_explore(self):
        """Alege un subiect de explorat din lista de interese"""
        if not self.interests:
            self.logger.warning("Nu există interese pentru explorare")
            return None
        
        # Alegem un interes aleatoriu
        topic = random.choice(self.interests)
        self.current_focus = topic
        self.last_topic_update = datetime.now()
        
        self.logger.decision(f"Subiect ales pentru explorare: {topic}")
        return topic
    
    def explore_topic(self, topic):
        """Explorează un subiect și adaugă cunoștințele în baza de date"""
        self.logger.thinking(f"Explorare subiect: {topic}")
        
        # Construim un prompt pentru a explora subiectul
        prompt = f"""Vreau să explorez subiectul: {topic}
        
Oferă-mi informații detaliate și organizate despre acest subiect. Include:
1. O definiție clară și concisă
2. Concepte cheie și principii
3. Aplicații practice sau exemple relevante
4. Tendințe recente sau dezvoltări (până în 2023)
5. Potențiale direcții de cercetare sau explorare viitoare

Organizează informațiile în secțiuni clare.
"""
        
        response = query_ollama(self.thinking_model, prompt, print_result=True)
        
        if not response:
            self.logger.error(f"Nu s-a putut explora subiectul: {topic}")
            return False
        
        # Salvăm cunoștințele în baza de date
        self.knowledge_base[topic] = response
        
        # Salvăm cunoștințele în fișier
        file_name = re.sub(r'[^\w\s-]', '', topic.lower())
        file_name = re.sub(r'[-\s]+', '_', file_name)
        
        save_to_file(
            response,
            KNOWLEDGE_DIR,
            f"{file_name}.txt"
        )
        
        # Generăm idei de proiecte bazate pe acest subiect
        self.generate_project_ideas(topic)
        
        return True
    
    def generate_project_ideas(self, topic):
        """Generează idei de proiecte bazate pe un subiect"""
        self.logger.thinking(f"Generare idei de proiecte pentru: {topic}")
        
        # Construim un prompt pentru a genera idei de proiecte
        knowledge = self.knowledge_base.get(topic, "")
        
        prompt = f"""Bazat pe subiectul "{topic}" și cunoștințele disponibile, 
generează 3 idei concrete de proiecte de programare Python care pot fi implementate.

Pentru fiecare proiect, include:
1. Titlu
2. Scurtă descriere și scop (2-3 propoziții)
3. Estimare a complexității (Low/Medium/High)
4. Potențiale biblioteci Python care ar putea fi utile
5. Ce aș putea învăța din acest proiect

Răspunde strict în formatul JSON de mai jos:
```json
[
  {{
    "title": "Titlu proiect 1",
    "description": "Descriere proiect 1",
    "complexity": "Medium",
    "libraries": ["lib1", "lib2"],
    "learning_outcomes": "Ce aș putea învăța"
  }},
  // ... alte proiecte
]
```
"""
        
        response = query_ollama(self.thinking_model, prompt, print_result=False)
        
        if not response:
            self.logger.error(f"Nu s-au putut genera idei de proiecte pentru: {topic}")
            return
        
        # Extragem JSON din răspuns
        try:
            # Încercăm să găsim și să extragem JSON-ul din răspuns
            json_match = re.search(r'```json\s*(.*?)\s*```', response, re.DOTALL)
            if json_match:
                json_str = json_match.group(1)
            else:
                # Dacă nu găsim între ```json ```, încercăm să vedem dacă răspunsul este direct JSON
                json_str = response
            
            project_ideas = json.loads(json_str)
            
            # Procesăm ideile de proiecte
            for idea in project_ideas:
                # Generăm un ID unic pentru proiect
                safe_title = re.sub(r'[^\w\s]', '', idea['title'].lower())
                project_id = f"{safe_title.replace(' ', '_')}_{int(time.time())}"
                
                # Creăm obiectul proiect
                project = {
                    "id": project_id,
                    "name": idea["title"],
                    "description": idea["description"],
                    "complexity": idea["complexity"],
                    "topic": topic,
                    "libraries": idea.get("libraries", []),
                    "learning_outcomes": idea.get("learning_outcomes", ""),
                    "status": "idea",
                    "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "files": []
                }
                
                # Salvăm proiectul
                self.save_project(project)
                
                # Adăugăm proiectul la coada de sarcini pentru a fi dezvoltat
                self.task_queue.put(("develop_project", project_id))
                
                self.logger.discovery(f"Nouă idee de proiect: {idea['title']}")
            
        except json.JSONDecodeError as e:
            self.logger.error(f"Eroare la decodarea ideilor de proiecte: {e}")
            self.logger.error(f"Răspuns: {response}")
        except Exception as e:
            self.logger.error(f"Eroare la procesarea ideilor de proiecte: {e}")
    
    def develop_project(self, project_id):
        """Dezvoltă un proiect existent"""
        # Găsim proiectul după ID
        project = next((p for p in self.projects if p["id"] == project_id), None)
        
        if not project:
            self.logger.error(f"Proiectul cu ID-ul {project_id} nu a fost găsit")
            return False
        
        self.logger.thinking(f"Dezvoltare proiect: {project['name']}")
        
        # Actualizăm statusul proiectului
        project["status"] = "in_progress"
        self.save_project(project)
        
        # Generăm codul pentru proiect
        prompt = f"""Vreau să dezvolt un proiect Python cu următoarele specificații:

Titlu: {project['name']}
Descriere: {project['description']}
Biblioteci recomandate: {', '.join(project['libraries'])}

Generează un program Python complet și funcțional pentru acest proiect. Programul trebuie să fie:
1. Bine structurat și modular
2. Comentat corespunzător
3. Cu tratare de erori
4. Gata de a fi rulat

Returnează doar codul Python, fără explicații adiționale. Folosește blocuri markdown ```python pentru cod.
"""
        
        # Folosim modelul de coding pentru a genera codul
        coding_model = select_best_model("coding")
        response = query_ollama(coding_model, prompt)
        
        if not response:
            self.logger.error(f"Nu s-a putut genera cod pentru proiectul: {project['name']}")
            project["status"] = "failed"
            self.save_project(project)
            return False
        
        # Extragem codul Python din răspuns
        code = extract_python_code(response)
        
        if not code:
            self.logger.error(f"Nu s-a putut extrage cod Python din răspuns pentru proiectul: {project['name']}")
            project["status"] = "failed"
            self.save_project(project)
            return False
        
        # Salvăm codul într-un fișier
        project_dir = os.path.join(PROJECTS_DIR, project["id"])
        if not os.path.exists(project_dir):
            os.makedirs(project_dir)
        
        main_file = os.path.join(project_dir, "main.py")
        
        try:
            with open(main_file, 'w', encoding='utf-8') as f:
                f.write(code)
            
            self.logger.success(f"Cod salvat pentru proiectul: {project['name']}")
            
            # Actualizăm proiectul
            project["files"].append({"name": "main.py", "path": main_file})
            
            # Detectăm modulele necesare
            required_modules = detect_required_modules(code)
            
            # Instalăm modulele necesare
            for module in required_modules:
                install_python_module(module)
            
            # Rulăm codul
            self.logger.info(f"Rulare proiect: {project['name']}")
            
            success, stdout, stderr = run_script(main_file, timeout=120)
            
            if success:
                project["status"] = "completed"
                project["result"] = "success"
                project["output"] = stdout
                self.logger.success(f"Proiect finalizat cu succes: {project['name']}")
            else:
                # Încercăm să reparăm codul dacă există erori
                if stderr:
                    self.logger.warning(f"Erori la rularea proiectului: {project['name']}")
                    self.logger.warning(f"Încercare de reparare a codului...")
                    
                    fixed_code = self.fix_code(code, stderr)
                    
                    if fixed_code and fixed_code != code:
                        # Salvăm codul reparat
                        with open(main_file, 'w', encoding='utf-8') as f:
                            f.write(fixed_code)
                        
                        self.logger.info(f"Cod reparat salvat pentru proiectul: {project['name']}")
                        
                        # Rulăm din nou codul reparat
                        success, stdout, stderr = run_script(main_file, timeout=120)
                        
                        if success:
                            project["status"] = "completed"
                            project["result"] = "success_after_fix"
                            project["output"] = stdout
                            self.logger.success(f"Proiect reparat și finalizat cu succes: {project['name']}")
                        else:
                            project["status"] = "error"
                            project["result"] = "failed_after_fix"
                            project["error"] = stderr
                            self.logger.error(f"Proiect eșuat chiar și după reparare: {project['name']}")
                    else:
                        project["status"] = "error"
                        project["result"] = "failed"
                        project["error"] = stderr
                        self.logger.error(f"Nu s-a putut repara codul pentru proiectul: {project['name']}")
                else:
                    project["status"] = "error"
                    project["result"] = "failed"
                    self.logger.error(f"Proiect eșuat fără erori specifice: {project['name']}")
            
            # Salvăm proiectul actualizat
            self.save_project(project)
            
            # Generăm un raport de dezvoltare pentru proiect
            self.generate_project_report(project)
            
            return success
        
        except Exception as e:
            self.logger.error(f"Eroare la salvarea/rularea codului pentru proiectul {project['name']}: {e}")
            project["status"] = "error"
            project["result"] = "exception"
            project["error"] = str(e)
            self.save_project(project)
            return False
    
    def fix_code(self, code, error_message):
        """Încearcă să repare codul care a generat erori"""
        self.logger.thinking("Reparare cod cu erori...")
        
        # Construim un prompt pentru a repara codul
        prompt = f"""Următorul cod Python a generat erori. Te rog să îl corectezi:

Eroare:
{error_message}

Cod original:
```python
{code}
```

Returnează doar codul corectat, fără explicații. Folosește blocuri markdown ```python pentru cod.
"""
        
        coding_model = select_best_model("coding")
        response = query_ollama(coding_model, prompt, print_result=False)
        
        if not response:
            self.logger.error("Nu s-a putut obține un răspuns pentru repararea codului")
            return None
        
        # Extragem codul Python din răspuns
        fixed_code = extract_python_code(response)
        
        if not fixed_code:
            self.logger.error("Nu s-a putut extrage cod Python corectat din răspuns")
            return None
        
        self.logger.success("Cod reparat cu succes")
        return fixed_code
    
    def generate_project_report(self, project):
        """Generează un raport pentru un proiect"""
        self.logger.thinking(f"Generare raport pentru proiectul: {project['name']}")
        
        # Construim un prompt pentru a genera raportul
        project_code = ""
        for file_info in project["files"]:
            file_path = file_info["path"]
            if os.path.exists(file_path):
                try:
                    with open(file_path, 'r', encoding='utf-8') as f:
                        file_content = f.read()
                        project_code += f"\n--- {file_info['name']} ---\n{file_content}\n\n"
                except Exception as e:
                    self.logger.error(f"Eroare la citirea fișierului {file_path}: {e}")
        
        prompt = f"""Analizează următorul proiect Python și generează un raport detaliat:

Titlu proiect: {project['name']}
Descriere: {project['description']}
Status: {project['status']}
Rezultat: {project.get('result', 'N/A')}

Cod sursă:
{project_code}

Te rog să incluzi în raport:
1. Un rezumat al funcționalității proiectului
2. Arhitectura și structura codului
3. Tehnologiile și bibliotecile utilizate
4. Puncte forte ale implementării
5. Potențiale îmbunătățiri sau extinderi viitoare
6. Lecții învățate din acest proiect

Formatează raportul în secțiuni clare.
"""
        
        response = query_ollama(self.thinking_model, prompt, print_result=True)
        
        if not response:
            self.logger.error(f"Nu s-a putut genera raportul pentru proiectul: {project['name']}")
            return
        
        # Salvăm raportul
        project_dir = os.path.join(PROJECTS_DIR, project["id"])
        report_file = os.path.join(project_dir, "report.md")
        
        try:
            with open(report_file, 'w', encoding='utf-8') as f:
                f.write(response)
            
            self.logger.success(f"Raport generat pentru proiectul: {project['name']}")
            
            # Actualizăm proiectul
            project["files"].append({"name": "report.md", "path": report_file})
            project["has_report"] = True
            self.save_project(project)
            
        except Exception as e:
            self.logger.error(f"Eroare la salvarea raportului pentru proiectul {project['name']}: {e}")
    
    def should_switch_topic(self):
        """Decide dacă ar trebui să schimbe subiectul curent"""
        if not self.current_focus:
            return True
        
        # Schimbă subiectul după 30 de minute
        time_on_topic = datetime.now() - self.last_topic_update
        if time_on_topic > timedelta(minutes=30):
            return True
        
        # Sau cu o șansă aleatorie de 10%
        return random.random() < 0.1
    
    def process_task_queue(self):
        """Procesează sarcinile din coadă"""
        if self.task_queue.empty():
            return False
        
        try:
            task_type, task_data = self.task_queue.get(block=False)
            
            if task_type == "develop_project":
                self.logger.info(f"Procesare sarcină: dezvoltare proiect {task_data}")
                self.develop_project(task_data)
            elif task_type == "explore_topic":
                self.logger.info(f"Procesare sarcină: explorare subiect {task_data}")
                self.explore_topic(task_data)
            else:
                self.logger.warning(f"Tip de sarcină necunoscut: {task_type}")
            
            self.task_queue.task_done()
            return True
        
        except queue.Empty:
            return False
    
    def autonomous_cycle(self):
        """Ciclu autonom de gândire și acțiune"""
        # Verificăm dacă avem sarcini în coadă
        if not self.task_queue.empty():
            self.process_task_queue()
            return
        
        # Decidem dacă trebuie să schimbăm subiectul
        if self.should_switch_topic():
            # Generăm noi interese ocazional (20% șansă)
            if random.random() < 0.2:
                self.generate_new_interests()
            
            # Alegem un nou subiect
            topic = self.choose_topic_to_explore()
            
            if topic:
                # Adăugăm sarcina de explorare a subiectului la coadă
                self.task_queue.put(("explore_topic", topic))
        else:
            # Continuăm să lucrăm pe subiectul curent
            # Alegem un proiect de dezvoltat din ideile existente
            unfinished_projects = [p for p in self.projects if p["status"] == "idea"]
            
            if unfinished_projects:
                project = random.choice(unfinished_projects)
                self.task_queue.put(("develop_project", project["id"]))
                self.logger.decision(f"Dezvoltare proiect ales: {project['name']}")

class AutonomousSystem:
    """Clasa principală pentru sistemul autonom"""
    
    def __init__(self):
        self.logger = RealTimeLogger("autonomous_system")
        self.thought_engine = AutonomousThought()
        self.running = False
        self.pause_event = threading.Event()
        self.autonomous_thread = None
    
    def start(self):
        """Pornește sistemul autonom"""
        if not check_ollama_connection():
            self.logger.error("Nu s-a putut conecta la serverul Ollama. Asigură-te că este pornit.")
            return False
        
        self.logger.info("Pornire sistem autonom...")
        self.running = True
        self.pause_event.clear()
        
        # Creăm directoarele necesare
        for directory in [PROJECTS_DIR, SCRIPTS_DIR, THOUGHTS_DIR, KNOWLEDGE_DIR, MEMORY_DIR]:
            if not os.path.exists(directory):
                os.makedirs(directory)
        
        # Pornim thread-ul autonom
        self.autonomous_thread = threading.Thread(target=self.autonomous_loop)
        self.autonomous_thread.daemon = True
        self.autonomous_thread.start()
        
        return True
    
    def stop(self):
        """Oprește sistemul autonom"""
        self.logger.info("Oprire sistem autonom...")
        self.running = False
        if self.autonomous_thread:
            self.autonomous_thread.join(timeout=5)
        self.logger.info("Sistem autonom oprit")
    
    def pause(self):
        """Pune sistemul autonom în pauză"""
        self.logger.info("Pauză sistem autonom...")
        self.pause_event.set()
    
    def resume(self):
        """Reia funcționarea sistemului autonom"""
        self.logger.info("Reluare sistem autonom...")
        self.pause_event.clear()
    
    def autonomous_loop(self):
        """Bucla principală pentru funcționarea autonomă"""
        while self.running:
            try:
                # Verificăm dacă suntem în pauză
                if self.pause_event.is_set():
                    time.sleep(1)
                    continue
                
                # Executăm un ciclu autonom
                self.thought_engine.autonomous_cycle()
                
                # Așteptăm un timp aleatoriu între 5-15 secunde între acțiuni
                # pentru a evita supraîncărcarea CPU și a da timp utilizatorului să observe
                wait_time = random.uniform(5, 15)
                time.sleep(wait_time)
                
            except Exception as e:
                self.logger.error(f"Eroare în bucla autonomă: {e}")
                time.sleep(5)  # Evităm bucle infinite de erori
    
    def status(self):
        """Afișează statusul curent al sistemului autonom"""
        if not self.running:
            return "Oprit"
        
        if self.pause_event.is_set():
            return "În pauză"
        
        return "Activ"
    
    def list_projects(self):
        """Afișează lista proiectelor"""
        projects = self.thought_engine.projects
        
        if not projects:
            print("Nu există proiecte")
            return
        
        print("\nProiecte:")
        print("-" * 80)
        for i, project in enumerate(projects, 1):
            status_emoji = "✅" if project["status"] == "completed" else "⏳" if project["status"] == "in_progress" else "❌" if project["status"] == "error" else "💡"
            print(f"{i}. {status_emoji} {project['name']} - {project['description'][:50]}... ({project['status']})")
        print("-" * 80)
    
    def list_knowledge(self):
        """Afișează baza de cunoștințe"""
        knowledge = self.thought_engine.knowledge_base
        
        if not knowledge:
            print("Baza de cunoștințe este goală")
            return
        
        print("\nBaza de cunoștințe:")
        print("-" * 80)
        for i, (topic, _) in enumerate(knowledge.items(), 1):
            print(f"{i}. {topic}")
        print("-" * 80)
    
    def list_interests(self):
        """Afișează interesele curente"""
        interests = self.thought_engine.interests
        
        if not interests:
            print("Nu există interese")
            return
        
        print("\nInterese:")
        print("-" * 80)
        for i, interest in enumerate(interests, 1):
            print(f"{i}. {interest}")
        print("-" * 80)
    
    def interactive_mode(self):
        """Mod interactiv pentru controlul sistemului autonom"""
        print("-" * 80)
        print("Sistem Autonom AI - Bazat pe modelele Ollama")
        print("-" * 80)
        
        if not check_ollama_connection():
            print("Eroare: Nu s-a putut conecta la serverul Ollama.")
            print("Asigură-te că Ollama este pornit și rulează la adresa http://localhost:11434")
            return
        
        models = get_available_models()
        
        if not models:
            print("Nu s-au putut obține modelele disponibile. Se vor folosi valorile implicite.")
            print(f"Modele implicite: {', '.join(AVAILABLE_MODELS)}")
        else:
            print(f"Modele disponibile: {', '.join(models)}")
        
        print("-" * 80)
        print("Pornire în mod autonom...")
        
        self.start()
        
        while True:
            try:
                print("\nOpțiuni:")
                print(f"1. Status: {self.status()}")
                print("2. Pauză/Reluare")
                print("3. Afișare proiecte")
                print("4. Afișare bază de cunoștințe")
                print("5. Afișare interese")
                print("6. Forțează generarea unui nou proiect")
                print("7. Forțează explorarea unui subiect nou")
                print("8. Oprire și ieșire")
                
                choice = input("\nAlege o opțiune (1-8): ")
                
                if choice == "1":
                    print(f"Status curent: {self.status()}")
                    
                    # Afișăm și informații suplimentare
                    if self.status() == "Activ":
                        print(f"Subiect curent: {self.thought_engine.current_focus or 'Niciunul'}")
                        print(f"Proiecte: {len(self.thought_engine.projects)}")
                        print(f"Cunoștințe: {len(self.thought_engine.knowledge_base)} subiecte")
                    
                elif choice == "2":
                    if self.pause_event.is_set():
                        self.resume()
                        print("Sistem reactivat")
                    else:
                        self.pause()
                        print("Sistem pus în pauză")
                
                elif choice == "3":
                    self.list_projects()
                
                elif choice == "4":
                    self.list_knowledge()
                
                elif choice == "5":
                    self.list_interests()
                
                elif choice == "6":
                    # Punem sistemul în pauză
                    was_paused = self.pause_event.is_set()
                    if not was_paused:
                        self.pause()
                    
                    # Generăm manual un nou proiect
                    if not self.thought_engine.interests:
                        print("Nu există interese pentru a genera proiecte")
                    else:
                        topic = random.choice(self.thought_engine.interests)
                        print(f"Generare proiect pentru subiectul: {topic}")
                        self.thought_engine.generate_project_ideas(topic)
                    
                    # Reluăm sistemul dacă era activ
                    if not was_paused:
                        self.resume()
                
                elif choice == "7":
                    # Punem sistemul în pauză
                    was_paused = self.pause_event.is_set()
                    if not was_paused:
                        self.pause()
                    
                    # Forțăm explorarea unui subiect
                    topic = self.thought_engine.choose_topic_to_explore()
                    if topic:
                        print(f"Explorare forțată a subiectului: {topic}")
                        self.thought_engine.explore_topic(topic)
                    
                    # Reluăm sistemul dacă era activ
                    if not was_paused:
                        self.resume()
                
                elif choice == "8":
                    self.stop()
                    print("La revedere!")
                    break
                
                else:
                    print("Opțiune invalidă. Te rog alege din nou.")
            
            except KeyboardInterrupt:
                print("\nÎntrerupere detectată. Oprire sistem...")
                self.stop()
                break
            
            except Exception as e:
                print(f"Eroare: {e}")

def main():
    # Creăm directoarele necesare
    for directory in [PROJECTS_DIR, SCRIPTS_DIR, THOUGHTS_DIR, KNOWLEDGE_DIR, LOG_DIR, MEMORY_DIR]:
        if not os.path.exists(directory):
            os.makedirs(directory)
    
    # Inițializăm și pornim sistemul autonom
    system = AutonomousSystem()
    system.interactive_mode()

if __name__ == "__main__":
    main()