import logging
import os
import uuid
from typing import Any, Dict, List, Optional

from dotenv import load_dotenv

try:
    from supabase import create_client, Client
except ImportError:
    create_client = None
    Client = None

load_dotenv(override=True)
logger = logging.getLogger(__name__)

class ChatHistoryManager:
    """
    Mengelola riwayat percakapan chatbot di Supabase PostgreSQL.
    Dioptimalkan menggunakan Supabase REST API untuk menghindari TCP Connection Timeout.
    """

    def __init__(self, table_name: str = "chat_message"):
        self.table_name = table_name
        self.url = os.getenv("SUPABASE_URL")
        self.key = os.getenv("SUPABASE_SERVICE_ROLE_KEY")
        
        self.client = None
        if create_client and self.url and self.key:
            try:
                self.client = create_client(self.url, self.key)
            except Exception as e:
                logger.error(f"Gagal inisialisasi Supabase Client untuk History: {e}")
        else:
            logger.warning("Kredensial Supabase tidak lengkap untuk History.")

    def save_turn(
        self,
        project_id: str,
        user_id: str,
        user_query: str,
        ai_response: str,
        references: Optional[List[Dict[str, Any]]] = None,
        metadata: Optional[Dict[str, Any]] = None,
    ) -> bool:
        """Menyimpan satu turn percakapan ke database.

        Args:
            project_id: ID project pemilik percakapan.
            user_id: ID user terautentikasi.
            user_query: Pertanyaan mentah dari pengguna.
            ai_response: Jawaban akhir dari assistant.
            references: Referensi terstruktur untuk UI.
            metadata: Metadata audit seperti latency dan strategy layer.

        Returns:
            True jika insert berhasil, False jika gagal.
        """
        if not self.client:
            return False

        if not project_id or not user_id:
            logger.error("project_id atau user_id tidak tersedia untuk save_turn")
            return False

        try:
            self.client.table(self.table_name).insert(
                {
                    "id": str(uuid.uuid4()),
                    "project_id": project_id,
                    "user_id": user_id,
                    "user_query": user_query,
                    "ai_response": ai_response,
                    "references": references or [],
                    "metadata": metadata or {},
                }
            ).execute()
            logger.debug("Turn tersimpan untuk project %s", project_id)
            return True
        except Exception as e:
            logger.error("Gagal menyimpan turn history via REST: %s", e)
            return False

    def get_history(
        self, project_id: str, user_id: str, limit: int = 5
    ) -> List[Dict[str, str]]:
        """Mengambil riwayat turn terakhir lalu meratakannya ke format chat model.

        Args:
            project_id: ID project pemilik percakapan.
            user_id: ID user terautentikasi.
            limit: Jumlah turn terbaru yang akan diambil.

        Returns:
            Daftar message berurutan untuk prompt LLM.
        """
        if not self.client:
            return []

        try:
            response = (
                self.client.table(self.table_name)
                .select("user_query, ai_response")
                .eq("project_id", project_id)
                .eq("user_id", user_id)
                .order("created_at", desc=True)
                .limit(limit)
                .execute()
            )

            messages = []
            for row in reversed(response.data):
                user_query = row.get("user_query")
                ai_response = row.get("ai_response")
                if user_query:
                    messages.append({"role": "user", "content": user_query})
                if ai_response:
                    messages.append({"role": "assistant", "content": ai_response})
            return messages
        except Exception as e:
            logger.error("Gagal mengambil riwayat turn via REST: %s", e)
            return []
