import requests
import json
import subprocess
import os
import re
import time
import logging
import sys
import importlib
import random
import threading
import queue
from datetime import datetime, timedelta
import keyboard  # For detecting 'q' key press

# 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):
        try:
            self.logger.info(message)
        except Exception as e:
            print(f"Logger error: {e}\nMessage: {message}", file=sys.stderr)
        
    def warning(self, message):
        try:
            self.logger.warning(message)
        except Exception as e:
            print(f"Logger error: {e}\nMessage: {message}", file=sys.stderr)
    
    def error(self, message):
        try:
            self.logger.error(message)
        except Exception as e:
            print(f"Logger error: {e}\nMessage: {message}", file=sys.stderr)
    
    def success(self, message):
        try:
            self.logger.info(f"✅ {message}")
        except Exception as e:
            print(f"Logger error: {e}\nMessage: {message}", file=sys.stderr)
    
    def thinking(self, message):
        try:
            self.logger.info(f"🤔 {message}")
        except Exception as e:
            print(f"Logger error: {e}\nMessage: {message}", file=sys.stderr)
    
    def decision(self, message):
        try:
            self.logger.info(f"🔍 {message}")
        except Exception as e:
            print(f"Logger error: {e}\nMessage: {message}", file=sys.stderr)
    
    def discovery(self, message):
        try:
            self.logger.info(f"💡 {message}")
        except Exception as e:
            print(f"Logger error: {e}\nMessage: {message}", file=sys.stderr)

# 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")
REPORTS_DIR = os.path.join(BASE_DIR, "reports")

# 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

def check_syntax(file_path):
    """Verifică sintaxa scriptului"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            compile(f.read(), file_path, 'exec')
        logger.info("Verificare sintaxă trecută")
        return True
    except SyntaxError as e:
        logger.error(f"Eroare de sintaxă în {file_path}: {e}")
        return False

def check_ollama_connection():
    """Verifică dacă serverul Ollama este disponibil"""
    try:
        response = requests.get("http://localhost:11434/api/tags", timeout=5)
        return response.status_code == 200
    except (requests.exceptions.ConnectionError, Exception) as e:
        logger.error(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:
            return [model["name"] for model in response.json().get("models", [])]
        return []
    except Exception as e:
        logger.error(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() or AVAILABLE_MODELS
    
    model_category = MODEL_CATEGORIES.get(task_type, MODEL_CATEGORIES["general"])
    
    for model in model_category:
        if model in available_models:
            return model
    
    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
    }
    
    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:
            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
    
    patterns = [
        r"```python\s*(.*?)\s*```",
        r"```\s*(.*?)\s*```",
        r"(?:(?:def|import|class|if)\s+.*?(?:\n.*?)+)(?:\n\n|$)"
    ]
    
    for pattern in patterns:
        matches = re.findall(pattern, text, re.DOTALL)
        if matches:
            code = matches[0].strip()
            if 'import' in code or 'def ' in code or 'print(' in code:
                logger.info("Cod Python extras cu succes")
                return code
    
    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}")
    
    env = os.environ.copy()
    if env_vars:
        env.update(env_vars)
    
    try:
        process = subprocess.Popen(
            [sys.executable, script_path],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
            bufsize=1,
            env=env
        )
        
        stdout_chunks = []
        stderr_chunks = []
        start_time = time.time()
        
        while process.poll() is None:
            if time.time() - start_time > timeout:
                process.kill()
                logger.error(f"Script terminat forțat după {timeout} secunde (timeout)")
                return False, "Timeout", ""
            
            stdout_line = process.stdout.readline()
            if stdout_line:
                stdout_chunks.append(stdout_line)
                sys.stdout.write(f"[Script Output]: {stdout_line}")
                sys.stdout.flush()
            
            stderr_line = process.stderr.readline()
            if stderr_line:
                stderr_chunks.append(stderr_line)
                sys.stderr.write(f"[Script Error]: {stderr_line}")
                sys.stderr.flush()
            
            if not stdout_line and not stderr_line:
                time.sleep(0.1)
        
        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"
    ]
    
    import_lines = re.findall(r'^(?:from|import)\s+([a-zA-Z0-9_]+)', code, re.MULTILINE)
    required_modules = [m for m in import_lines if m not in standard_modules]
    
    return list(set(required_modules))

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.coding_model = select_best_model("coding")
        self.knowledge_base = {}
        self.interests = []
        self.explored_topics = set()
        self.generated_projects = set()
        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, interesele și subiectele explorate"""
        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:
            self.interests = INTEREST_DOMAINS.copy()
            self.logger.info("S-au inițializat interesele implicite")
        
        explored_file = os.path.join(MEMORY_DIR, "explored_topics.txt")
        if os.path.exists(explored_file):
            try:
                with open(explored_file, 'r', encoding='utf-8') as f:
                    self.explored_topics = set(line.strip() for line in f if line.strip())
                self.logger.info(f"S-au încărcat {len(self.explored_topics)} subiecte explorate")
            except Exception as e:
                self.logger.error(f"Eroare la încărcarea subiectelor explorate: {e}")
        
        generated_file = os.path.join(MEMORY_DIR, "generated_projects.txt")
        if os.path.exists(generated_file):
            try:
                with open(generated_file, 'r', encoding='utf-8') as f:
                    self.generated_projects = set(line.strip() for line in f if line.strip())
                self.logger.info(f"S-au încărcat {len(self.generated_projects)} proiecte generate")
            except Exception as e:
                self.logger.error(f"Eroare la încărcarea proiectelor generate: {e}")
        
        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ă"""
        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}")
        
        explored_file = os.path.join(MEMORY_DIR, "explored_topics.txt")
        try:
            with open(explored_file, 'w', encoding='utf-8') as f:
                for topic in self.explored_topics:
                    f.write(f"{topic}\n")
            self.logger.info(f"S-au salvat {len(self.explored_topics)} subiecte explorate")
        except Exception as e:
            self.logger.error(f"Eroare la salvarea subiectelor explorate: {e}")
        
        generated_file = os.path.join(MEMORY_DIR, "generated_projects.txt")
        try:
            with open(generated_file, 'w', encoding='utf-8') as f:
                for project in self.generated_projects:
                    f.write(f"{project}\n")
            self.logger.info(f"S-au salvat {len(self.generated_projects)} proiecte generate")
        except Exception as e:
            self.logger.error(f"Eroare la salvarea proiectelor generate: {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)
                        self.generated_projects.add(project_data["name"])
                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']}")
            
            if project_data not in self.projects:
                self.projects.append(project_data)
                self.generated_projects.add(project_data["name"])
                self.save_memories()
            
            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...")
        
        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 care să fie interconectate cu cele existente, dar care să fie noi și neexplorate.
Asigură-te că domeniile nu sunt deja în lista de mai sus.
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
        
        new_interests = []
        lines = response.strip().split("\n")
        for line in lines:
            if re.match(r'^\d+\.', line):
                parts = line.split("-", 1)
                if len(parts) > 1:
                    domain = re.sub(r'^\d+\.\s*', '', parts[0]).strip()
                    if domain not in self.interests and domain not in self.explored_topics:
                        new_interests.append(domain)
        
        for interest in new_interests:
            self.interests.append(interest)
            self.logger.discovery(f"Nou interes descoperit: {interest}")
        
        self.save_memories()
    
    def choose_topic_to_explore(self):
        """Alege un subiect neexplorat din lista de interese"""
        unexplored = [interest for interest in self.interests if interest not in self.explored_topics]
        
        if not unexplored:
            self.logger.warning("Toate subiectele au fost explorate. Generare noi interese...")
            self.generate_new_interests()
            unexplored = [interest for interest in self.interests if interest not in self.explored_topics]
        
        if not unexplored:
            self.logger.error("Nu există subiecte noi pentru explorare")
            return None
        
        topic = random.choice(unexplored)
        self.current_focus = topic
        self.last_topic_update = datetime.now()
        self.explored_topics.add(topic)
        self.save_memories()
        
        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}")
        
        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
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
        
        self.knowledge_base[topic] = response
        
        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")
        
        self.generate_project_ideas(topic)
        
        return True
    
    def generate_project_ideas(self, topic):
        """Generează idei de proiecte unice bazate pe un subiect"""
        self.logger.thinking(f"Generare idei de proiecte pentru: {topic}")
        
        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 să fie unice și să nu fi fost generate anterior.
Asigură-te că titlurile proiectelor sunt noi și nu există în lista de proiecte existente.

Proiecte existente: {', '.join(self.generated_projects)}

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:
```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
        
        try:
            json_match = re.search(r'```json\s*(.*?)\s*```', response, re.DOTALL)
            json_str = json_match.group(1) if json_match else response
            project_ideas = json.loads(json_str)
            
            for idea in project_ideas:
                if idea["title"] in self.generated_projects:
                    self.logger.warning(f"Proiectul {idea['title']} a fost deja generat. Ignorare.")
                    continue
                
                safe_title = re.sub(r'[^\w\s]', '', idea['title'].lower())
                project_id = f"{safe_title.replace(' ', '_')}_{int(time.time())}"
                
                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": []
                }
                
                self.save_project(project)
                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}")
        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"""
        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']}")
        
        project["status"] = "in_progress"
        self.save_project(project)
        
        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.
"""
        
        response = query_ollama(self.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
        
        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
        
        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']}")
            
            project["files"].append({"name": "main.py", "path": main_file})
            
            required_modules = detect_required_modules(code)
            for module in required_modules:
                install_python_module(module)
            
            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:
                if stderr:
                    self.logger.warning(f"Erori la rularea proiectului: {project['name']}")
                    fixed_code = self.fix_code(code, stderr)
                    
                    if fixed_code and fixed_code != code:
                        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']}")
                        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']}")
            
            self.save_project(project)
            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...")
        
        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.
"""
        
        response = query_ollama(self.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
        
        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']}")
        
        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
        
        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']}")
            
            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 handle_user_request(self, request):
        """Gestionează cererea utilizatorului"""
        self.logger.info(f"Procesare cerere utilizator: {request}")
        
        report_content = f"# Raport Cerere Utilizator\n\n"
        report_content += f"**Data și Ora**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
        report_content += f"**Cerere**: {request}\n\n"
        
        if "create" in request.lower() or "build" in request.lower() or "write" in request.lower():
            # Gestionăm cereri legate de programare
            prompt = f"""Scrie un program Python bazat pe următoarea cerere:

{request}

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. Folosește blocuri markdown ```python pentru cod.
"""
            response = query_ollama(self.coding_model, prompt)
            code = extract_python_code(response)
            
            if code:
                project_id = f"user_request_{int(time.time())}"
                project_dir = os.path.join(PROJECTS_DIR, project_id)
                os.makedirs(project_dir, exist_ok=True)
                main_file = os.path.join(project_dir, "main.py")
                
                with open(main_file, 'w', encoding='utf-8') as f:
                    f.write(code)
                
                project = {
                    "id": project_id,
                    "name": f"User Request {int(time.time())}",
                    "description": request,
                    "complexity": "Medium",
                    "topic": "User Request",
                    "libraries": detect_required_modules(code),
                    "learning_outcomes": "Custom user request implementation",
                    "status": "in_progress",
                    "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    "files": [{"name": "main.py", "path": main_file}]
                }
                
                self.save_project(project)
                
                for module in project["libraries"]:
                    install_python_module(module)
                
                success, stdout, stderr = run_script(main_file, timeout=120)
                
                report_content += f"## Rezultat\n"
                if success:
                    project["status"] = "completed"
                    project["result"] = "success"
                    project["output"] = stdout
                    report_content += f"**Status**: Succes\n"
                    report_content += f"**Output**:\n```\n{stdout}\n```\n"
                else:
                    fixed_code = self.fix_code(code, stderr) if stderr else None
                    if fixed_code and fixed_code != code:
                        with open(main_file, 'w', encoding='utf-8') as f:
                            f.write(fixed_code)
                        success, stdout, stderr = run_script(main_file, timeout=120)
                        if success:
                            project["status"] = "completed"
                            project["result"] = "success_after_fix"
                            project["output"] = stdout
                            report_content += f"**Status**: Succes după reparare\n"
                            report_content += f"**Output**:\n```\n{stdout}\n```\n"
                        else:
                            project["status"] = "error"
                            project["result"] = "failed_after_fix"
                            project["error"] = stderr
                            report_content += f"**Status**: Eșuat după reparare\n"
                            report_content += f"**Eroare**:\n```\n{stderr}\n```\n"
                    else:
                        project["status"] = "error"
                        project["result"] = "failed"
                        project["error"] = stderr
                        report_content += f"**Status**: Eșuat\n"
                        report_content += f"**Eroare**:\n```\n{stderr}\n```\n"
                
                self.save_project(project)
            else:
                report_content += f"## Rezultat\n**Status**: Eșuat\n**Detalii**: Nu s-a putut genera cod valid.\n"
        
        else:
            # Gestionăm cereri de explorare sau informații
            prompt = f"""Oferă informații detaliate despre următoarea cerere: {request}

Include:
1. O descriere clară și concisă
2. Detalii relevante și structurate
3. Exemple sau aplicații practice, dacă este cazul

Organizează informațiile în secțiuni clare.
"""
            response = query_ollama(self.thinking_model, prompt, print_result=True)
            
            if response:
                file_name = re.sub(r'[^\w\s-]', '', request.lower()[:50])
                file_name = re.sub(r'[-\s]+', '_', file_name)
                save_to_file(response, KNOWLEDGE_DIR, f"{file_name}.txt")
                self.knowledge_base[request] = response
                self.explored_topics.add(request)
                self.save_memories()
                
                report_content += f"## Rezultat\n**Status**: Succes\n**Detalii**:\n{response}\n"
            else:
                report_content += f"## Rezultat\n**Status**: Eșuat\n**Detalii**: Nu s-a putut obține un răspuns valid.\n"
        
        # Salvăm raportul
        report_file = save_to_file(report_content, REPORTS_DIR, f"user_request_{int(time.time())}.txt")
        self.logger.success(f"Raport cerere utilizator salvat în: {report_file}")
    
    def should_switch_topic(self):
        """Decide dacă ar trebui să schimbe subiectul curent"""
        if not self.current_focus:
            return True
        
        time_on_topic = datetime.now() - self.last_topic_update
        if time_on_topic > timedelta(minutes=30):
            return True
        
        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"""
        if not self.task_queue.empty():
            self.process_task_queue()
            return
        
        if self.should_switch_topic():
            if random.random() < 0.2:
                self.generate_new_interests()
            
            topic = self.choose_topic_to_explore()
            if topic:
                self.task_queue.put(("explore_topic", topic))
        else:
            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
        self.keyboard_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()
        
        for directory in [PROJECTS_DIR, SCRIPTS_DIR, THOUGHTS_DIR, KNOWLEDGE_DIR, MEMORY_DIR, REPORTS_DIR]:
            if not os.path.exists(directory):
                os.makedirs(directory)
        
        self.autonomous_thread = threading.Thread(target=self.autonomous_loop)
        self.autonomous_thread.daemon = True
        self.autonomous_thread.start()
        
        self.keyboard_thread = threading.Thread(target=self.keyboard_listener)
        self.keyboard_thread.daemon = True
        self.keyboard_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)
        if self.keyboard_thread:
            self.keyboard_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 keyboard_listener(self):
        """Ascultă pentru tasta 'q' și gestionează cererile utilizatorului"""
        while self.running:
            try:
                if keyboard.is_pressed('q'):
                    self.pause()
                    print("\nSistem pus în pauză. Ce dorești să fac?")
                    request = input("> ")
                    
                    if request.strip():
                        self.thought_engine.handle_user_request(request)
                    
                    print("Revenire la funcționare autonomă...")
                    self.resume()
                    
                    time.sleep(1)  # Evită detectarea multiplă a aceleiași apăsări
                time.sleep(0.1)
            except Exception as e:
                self.logger.error(f"Eroare în listener-ul de tastatură: {e}")
    
    def autonomous_loop(self):
        """Bucla principală pentru funcționarea autonomă"""
        while self.running:
            try:
                if self.pause_event.is_set():
                    time.sleep(1)
                    continue
                
                self.thought_engine.autonomous_cycle()
                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)
    
    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("Apasă 'q' pentru a întrerupe și a introduce o cerere")
        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...")
        
        # Instalăm modulul keyboard dacă nu este deja instalat
        if not importlib.util.find_spec("keyboard"):
            install_python_module("keyboard")
        
        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()}")
                    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":
                    was_paused = self.pause_event.is_set()
                    if not was_paused:
                        self.pause()
                    
                    if not self.thought_engine.interests:
                        print("Nu există interese pentru a genera proiecte")
                    else:
                        topic = random.choice([t for t in self.thought_engine.interests
                                            if t not in self.thought_engine.explored_topics])
                        if topic:
                            print(f"Generare proiect pentru subiectul: {topic}")
                            self.thought_engine.generate_project_ideas(topic)
                        else:
                            print("Toate subiectele au fost explorate. Generare noi interese...")
                            self.thought_engine.generate_new_interests()
                            topic = random.choice(self.thought_engine.interests)
                            print(f"Generare proiect pentru subiectul nou: {topic}")
                            self.thought_engine.generate_project_ideas(topic)
                    
                    if not was_paused:
                        self.resume()
                
                elif choice == "7":
                    was_paused = self.pause_event.is_set()
                    if not was_paused:
                        self.pause()
                    
                    topic = self.thought_engine.choose_topic_to_explore()
                    if topic:
                        print(f"Explorare forțată a subiectului: {topic}")
                        self.thought_engine.explore_topic(topic)
                    
                    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():
    # Verificăm sintaxa scriptului
    if not check_syntax(__file__):
        sys.exit(1)
    
    # Creăm directoarele necesare
    for directory in [PROJECTS_DIR, SCRIPTS_DIR, THOUGHTS_DIR, KNOWLEDGE_DIR, LOG_DIR, MEMORY_DIR, REPORTS_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()