from sqlalchemy.orm import Session
from typing import Optional, List, Dict, Any
from app.models.site_config import SiteConfig
from app.schemas.site_config import SiteConfigCreate, SiteConfigUpdate


class SiteConfigCRUD:
    def get_by_id(self, db: Session, config_id: int) -> Optional[SiteConfig]:
        """Obtenir une configuration par ID"""
        return db.query(SiteConfig).filter(SiteConfig.id == config_id).first()
    
    def get_by_key(self, db: Session, key: str) -> Optional[SiteConfig]:
        """Obtenir une configuration par clé"""
        return db.query(SiteConfig).filter(SiteConfig.key == key).first()
    
    def get_all(self, db: Session, skip: int = 0, limit: int = 100) -> List[SiteConfig]:
        """Obtenir toutes les configurations"""
        return db.query(SiteConfig).offset(skip).limit(limit).all()
    
    def get_public_configs(self, db: Session) -> Dict[str, str]:
        """Obtenir toutes les configurations publiques sous forme de dictionnaire"""
        configs = db.query(SiteConfig).filter(SiteConfig.is_public == True).all()
        return {config.key: config.value for config in configs}
    
    def get_by_group(self, db: Session, group: str) -> List[SiteConfig]:
        """Obtenir les configurations par groupe"""
        return db.query(SiteConfig).filter(SiteConfig.group == group).all()
    
    def create(self, db: Session, config_create: SiteConfigCreate) -> SiteConfig:
        """Créer une nouvelle configuration"""
        db_config = SiteConfig(**config_create.dict())
        db.add(db_config)
        db.commit()
        db.refresh(db_config)
        return db_config
    
    def update(self, db: Session, config_id: int, config_update: SiteConfigUpdate) -> Optional[SiteConfig]:
        """Mettre à jour une configuration"""
        db_config = self.get_by_id(db, config_id)
        if not db_config:
            return None
        
        update_data = config_update.dict(exclude_unset=True)
        for field, value in update_data.items():
            setattr(db_config, field, value)
        
        db.commit()
        db.refresh(db_config)
        return db_config
    
    def update_by_key(self, db: Session, key: str, value: str) -> Optional[SiteConfig]:
        """Mettre à jour une configuration par clé"""
        db_config = self.get_by_key(db, key)
        if not db_config:
            return None
        
        db_config.value = value
        db.commit()
        db.refresh(db_config)
        return db_config
    
    def delete(self, db: Session, config_id: int) -> bool:
        """Supprimer une configuration"""
        db_config = self.get_by_id(db, config_id)
        if not db_config:
            return False
        
        db.delete(db_config)
        db.commit()
        return True
    
    def get_value(self, db: Session, key: str, default: Any = None) -> Any:
        """Obtenir la valeur d'une configuration"""
        config = self.get_by_key(db, key)
        if not config:
            return default
        
        # Convertir selon le type
        if config.type == "number":
            try:
                return float(config.value) if "." in config.value else int(config.value)
            except ValueError:
                return default
        elif config.type == "boolean":
            return config.value.lower() in ("true", "1", "yes", "on")
        elif config.type == "json":
            try:
                import json
                return json.loads(config.value)
            except (json.JSONDecodeError, TypeError):
                return default
        else:
            return config.value


site_config_crud = SiteConfigCRUD()
