"""
AI Provider 기본 클래스 정의
모든 AI 프로바이더는 이 기본 클래스를 상속받아 구현합니다.
"""

from abc import ABC, abstractmethod
from typing import Optional, Dict, Any, List
from dataclasses import dataclass
from enum import Enum


class AIProviderType(Enum):
    """지원하는 AI 프로바이더 타입"""
    OPENAI = "openai"
    OPENROUTER = "openrouter"
    GEMINI = "gemini"
    XAI = "xai"


@dataclass
class AIMessage:
    """AI 메시지 데이터 클래스"""
    role: str  # 'system', 'user', 'assistant'
    content: str


@dataclass
class AIResponse:
    """AI 응답 데이터 클래스"""
    content: str
    model: str
    provider: str
    usage: Optional[Dict[str, int]] = None
    raw_response: Optional[Any] = None


class BaseAIProvider(ABC):
    """
    AI Provider 추상 기본 클래스
    모든 AI 프로바이더는 이 클래스를 상속받아 구현해야 합니다.
    """
    
    def __init__(self, api_key: str, model: Optional[str] = None):
        """
        Args:
            api_key: API 키
            model: 사용할 모델명 (None이면 기본 모델 사용)
        """
        self._api_key = api_key
        self._model = model or self.default_model
        self._is_initialized = False
    
    @property
    @abstractmethod
    def provider_type(self) -> AIProviderType:
        """프로바이더 타입 반환"""
        pass
    
    @property
    @abstractmethod
    def provider_name(self) -> str:
        """프로바이더 이름 반환"""
        pass
    
    @property
    @abstractmethod
    def default_model(self) -> str:
        """기본 모델명 반환"""
        pass
    
    @property
    @abstractmethod
    def available_models(self) -> List[str]:
        """사용 가능한 모델 목록 반환"""
        pass
    
    @property
    def model(self) -> str:
        """현재 사용 중인 모델명"""
        return self._model
    
    @model.setter
    def model(self, value: str):
        """모델 변경"""
        self._model = value
    
    @property
    def api_key(self) -> str:
        """API 키 (마스킹된 값)"""
        if self._api_key:
            return self._api_key[:8] + "..." + self._api_key[-4:]
        return ""
    
    def update_api_key(self, api_key: str):
        """API 키 업데이트"""
        self._api_key = api_key
        self._is_initialized = False
    
    @abstractmethod
    def initialize(self) -> bool:
        """
        프로바이더 초기화 (클라이언트 생성 등)
        Returns:
            초기화 성공 여부
        """
        pass
    
    @abstractmethod
    async def chat(
        self,
        messages: List[AIMessage],
        temperature: float = 0.7,
        max_tokens: Optional[int] = None,
        **kwargs
    ) -> AIResponse:
        """
        채팅 요청 (비동기)
        
        Args:
            messages: 대화 메시지 리스트
            temperature: 응답 다양성 (0.0 ~ 1.0)
            max_tokens: 최대 토큰 수
            **kwargs: 추가 파라미터
            
        Returns:
            AI 응답
        """
        pass
    
    @abstractmethod
    def chat_sync(
        self,
        messages: List[AIMessage],
        temperature: float = 0.7,
        max_tokens: Optional[int] = None,
        **kwargs
    ) -> AIResponse:
        """
        채팅 요청 (동기)
        
        Args:
            messages: 대화 메시지 리스트
            temperature: 응답 다양성 (0.0 ~ 1.0)
            max_tokens: 최대 토큰 수
            **kwargs: 추가 파라미터
            
        Returns:
            AI 응답
        """
        pass
    
    def validate_api_key(self) -> bool:
        """API 키 유효성 검사 (간단한 형식 체크)"""
        return bool(self._api_key and len(self._api_key) > 10)
    
    def __repr__(self):
        return f"{self.__class__.__name__}(model={self._model}, initialized={self._is_initialized})"

