import json
import logging
from typing import List, Dict, Any

import requests
import urllib3
from PyQt6.QtCore import QThread, pyqtSignal

from core.runtime_platform import detect_runtime_platform

logger = logging.getLogger(__name__)


class AIAgentWorker(QThread):
    response_ready = pyqtSignal(str, int)  # Mesaj ve kalan kota
    status_update = pyqtSignal(str)
    error_occurred = pyqtSignal(str)

    def __init__(self, tenant_manager, db, profile_id: str, question: str):
        super().__init__()
        self.tenant_manager = tenant_manager
        self.db = db
        self.profile_id = profile_id
        self.question = question
        self.api_url = "https://app.golder.biz/api/ai/ask.php"
        self.messages = []

    def _extract_server_error(self, resp: requests.Response) -> str:
        try:
            err_data = resp.json()
        except ValueError:
            err_data = None

        if isinstance(err_data, dict):
            message = err_data.get("message")
            if isinstance(message, str) and message.strip():
                return message.strip()

            error_obj = err_data.get("error")
            if isinstance(error_obj, dict):
                nested_message = error_obj.get("message")
                if isinstance(nested_message, str) and nested_message.strip():
                    return nested_message.strip()

            details = err_data.get("details")
            if isinstance(details, dict):
                nested_error = details.get("error")
                if isinstance(nested_error, dict):
                    nested_message = nested_error.get("message")
                    if isinstance(nested_message, str) and nested_message.strip():
                        return nested_message.strip()

        raw_text = resp.text.strip()
        if raw_text:
            compact_text = " ".join(raw_text.split())
            return compact_text[:300]

        return f"HTTP {resp.status_code} Hatasi"

    def is_safe_sql(self, sql: str) -> bool:
        sql_upper = sql.upper().strip()
        if not sql_upper.startswith("SELECT"):
            return False
        forbidden = ["INSERT", "UPDATE", "DELETE", "DROP", "ALTER", "TRUNCATE", "REPLACE"]
        for word in forbidden:
            if f" {word} " in f" {sql_upper} ":
                return False
        return True

    def run(self):
        try:
            token = self.tenant_manager.get_api_token()
            if not token:
                self.error_occurred.emit("Lütfen önce sisteme giriş yapın (API Token yok).")
                return

            headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
            is_mac = detect_runtime_platform() == "macos"
            verify_ssl = not is_mac
            if is_mac:
                urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
                headers["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
            self.messages.append({"role": "user", "content": self.question})
            is_new_question = True

            for _turn in range(5):
                payload = {
                    "messages": self.messages,
                    "is_new_question": is_new_question,
                    "profile_id": self.profile_id,
                }
                is_new_question = False

                self.status_update.emit("Yapay zeka düşünüyor...")
                resp = requests.post(
                    self.api_url,
                    json=payload,
                    headers=headers,
                    timeout=60 if is_mac else 40,
                    verify=verify_ssl,
                )

                if resp.status_code == 429:
                    self.error_occurred.emit("Günlük 100 soruluk yapay zeka limitinizi doldurdunuz.")
                    return

                if resp.status_code != 200:
                    error_msg = self._extract_server_error(resp)
                    self.error_occurred.emit(f"Sunucu Hatası: {error_msg}")
                    return

                try:
                    data = resp.json()
                except ValueError:
                    self.error_occurred.emit("Sunucu Hatası: Gecersiz JSON yaniti alindi.")
                    return

                if data.get("status") != "ok":
                    self.error_occurred.emit(data.get("message", "API Hatası."))
                    return

                ai_message = data["message"]
                remaining_quota = data.get("remaining_quota", 0)
                self.messages.append(ai_message)

                if ai_message.get("tool_calls"):
                    self.status_update.emit("Veritabanınız inceleniyor...")
                    for tool_call in ai_message["tool_calls"]:
                        if tool_call["function"]["name"] == "execute_sql":
                            args = json.loads(tool_call["function"]["arguments"])
                            query = args.get("query", "")

                            if not self.is_safe_sql(query):
                                tool_result = json.dumps({"error": "Güvenlik: Sadece SELECT kullanılabilir."})
                            else:
                                try:
                                    rows = self.db.fetch_all(query)
                                    # JSON'u kısalt
                                    tool_result = json.dumps(rows, default=str, ensure_ascii=False)
                                    if len(tool_result) > 12000:
                                        tool_result = tool_result[:12000] + "... [ÇOK UZUN]"
                                except Exception as e:
                                    tool_result = json.dumps({"error": str(e)})

                            self.messages.append(
                                {
                                    "tool_call_id": tool_call["id"],
                                    "role": "tool",
                                    "name": "execute_sql",
                                    "content": tool_result,
                                }
                            )
                    continue

                if ai_message.get("content"):
                    self.response_ready.emit(ai_message["content"], remaining_quota)
                    return

            self.error_occurred.emit("Zaman aşımı. Soru çok karmaşıktı.")
        except requests.Timeout:
            self.error_occurred.emit("Bağlantı Hatası: Sunucu zamanında yanıt vermedi.")
        except requests.RequestException as e:
            self.error_occurred.emit(f"Bağlantı Hatası: {str(e)}")
        except Exception as e:
            self.error_occurred.emit(f"Bağlantı Hatası: {str(e)}")




