# model_loader.py
from unsloth import FastLanguageModel
import torch
import ast

class ABSAModelSingleton:
    _instance = None
    _model = None
    _tokenizer = None
    _loaded = False
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(ABSAModelSingleton, cls).__new__(cls)
        return cls._instance
    #george114/LLama_3_1_8B_ASBA_Opinion_Detection
    def load_model(self, model_path="LLama_3_1_8B_ASBA_Opinion_Detection"):
        """Load model once and keep in memory"""
        if self._loaded:
            print("✅ Model already loaded")
            return self._model, self._tokenizer
        
        try:
            print("🔄 Loading ABSA model...")
            self._model, self._tokenizer = FastLanguageModel.from_pretrained(
                model_path,
                max_seq_length=2048,
                dtype=None,
                load_in_4bit=True,
                device_map="auto"
            )
            FastLanguageModel.for_inference(self._model)
            self._loaded = True
            print("✅ ABSA model loaded successfully")
            return self._model, self._tokenizer
            
        except Exception as e:
            print(f"❌ Error loading model: {e}")
            return None, None
    
    def get_model(self):
        """Get the loaded model"""
        if not self._loaded:
            return self.load_model()
        return self._model, self._tokenizer
    
    def unload_model(self):
        """Unload model to free memory"""
        if self._loaded:
            del self._model
            del self._tokenizer
            self._model = None
            self._tokenizer = None
            self._loaded = False
            if torch.cuda.is_available():
                torch.cuda.empty_cache()
            print("✅ Model unloaded")

# Global instance
model_manager = ABSAModelSingleton()