import logging
from typing import Optional
from sqlalchemy.orm import Session
from datetime import datetime, timezone

from src.marketing.apps.persona.model import StorePersona
from src.marketing.apps.persona import schema
from src.marketing.apps.persona.llm_service import AzureLLMPersonaService

logger = logging.getLogger(__name__)


class PersonaController:
    """Controller for persona management operations."""
    
    def __init__(self, db: Session):
        self.db = db
        self.llm_service = AzureLLMPersonaService()
    
    def generate_persona(
        self, 
        store_id: int, 
        branch_id: Optional[int] = None
    ) -> schema.PersonaGenerationResponse:
        """Generate persona for a store."""
        try:
            logger.info(f"Generating persona for store {store_id}, branch {branch_id}")
            return self.llm_service.generate_persona_for_store(self.db, store_id, branch_id)
            
        except Exception as e:
            logger.error(f"Error generating persona for store {store_id}: {str(e)}")
            return schema.PersonaGenerationResponse(
                success=False,
                message=f"Error generating persona: {str(e)}"
            )
    
    def get_persona(
        self, 
        store_id: int, 
        branch_id: Optional[int] = None
    ) -> Optional[schema.StorePersonaResponse]:
        """Get existing persona for a store."""
        try:
            persona = self._get_existing_persona(store_id, branch_id)
            if persona:
                return self._build_persona_response(persona)
            return None
            
        except Exception as e:
            logger.error(f"Error getting persona for store {store_id}: {str(e)}")
            return None
    
    def update_persona(
        self, 
        store_id: int, 
        branch_id: Optional[int], 
        update_data: schema.PersonaUpdateRequest
    ) -> Optional[schema.StorePersonaResponse]:
        """Update existing persona."""
        try:
            persona = self._get_existing_persona(store_id, branch_id)
            if not persona:
                return None
            
            # Update fields
            if update_data.industry is not None:
                persona.industry = update_data.industry
            if update_data.audience_type is not None:
                persona.audience_type = update_data.audience_type
            if update_data.brand_voice is not None:
                persona.brand_voice = update_data.brand_voice
            if update_data.content_style is not None:
                persona.content_style = update_data.content_style
            
            persona.updated_at = datetime.now(timezone.utc)
            self.db.commit()
            self.db.refresh(persona)
            
            return self._build_persona_response(persona)
            
        except Exception as e:
            logger.error(f"Error updating persona for store {store_id}: {str(e)}")
            self.db.rollback()
            return None
    
    def delete_persona(
        self, 
        store_id: int, 
        branch_id: Optional[int] = None
    ) -> bool:
        """Soft delete persona."""
        try:
            persona = self._get_existing_persona(store_id, branch_id)
            if persona:
                persona.is_active = False
                persona.updated_at = datetime.now(timezone.utc)
                self.db.commit()
                return True
            return False
            
        except Exception as e:
            logger.error(f"Error deleting persona for store {store_id}: {str(e)}")
            self.db.rollback()
            return False
    
    def list_store_personas(
        self, 
        store_id: int
    ) -> list[schema.StorePersonaResponse]:
        """List all personas for a store."""
        try:
            personas = self.db.query(StorePersona).filter(
                StorePersona.store_id == store_id,
                StorePersona.is_active == True
            ).all()
            
            return [self._build_persona_response(persona) for persona in personas]
            
        except Exception as e:
            logger.warning(f"Error listing personas with is_active filter (schema issue?): {str(e)}")
            # Try without the is_active filter as fallback
            try:
                personas = self.db.query(StorePersona).filter(
                    StorePersona.store_id == store_id
                ).all()
                
                return [self._build_persona_response(persona) for persona in personas]
                
            except Exception as e2:
                logger.error(f"Fallback query also failed: {str(e2)}")
                return []
    
    def _get_existing_persona(
        self, 
        store_id: int, 
        branch_id: Optional[int] = None
    ) -> Optional[StorePersona]:
        """Get existing persona for store/branch."""
        try:
            query = self.db.query(StorePersona).filter(StorePersona.store_id == store_id)
            
            if branch_id:
                query = query.filter(StorePersona.branch_id == branch_id)
            return query.filter(StorePersona.is_active == True).first()
        except Exception as e:
            logger.warning(f"Error querying existing persona (schema issue?): {str(e)}")
            # Try without the is_active filter as fallback
            try:
                query = self.db.query(StorePersona).filter(StorePersona.store_id == store_id)
                
                if branch_id:
                    query = query.filter(StorePersona.branch_id == branch_id)
                else:
                    query = query.filter(StorePersona.branch_id.is_(None))
                
                return query.first()
            except Exception as e2:
                logger.error(f"Fallback query also failed: {str(e2)}")
                return None
    
    def _build_persona_response(self, persona: StorePersona) -> schema.StorePersonaResponse:
        """Build response from database model."""
        return schema.StorePersonaResponse(
            id=persona.id,
            store_id=persona.store_id,
            branch_id=persona.branch_id,
            industry=persona.industry,
            audience_type=persona.audience_type,
            brand_voice=persona.brand_voice,
            content_style=persona.content_style,
            analysis_summary=persona.analysis_summary,
            confidence_score=persona.confidence_score,
            last_analyzed=persona.last_analyzed,
            created_at=persona.created_at,
            updated_at=persona.updated_at,
            is_active=persona.is_active
        )
