"""
Prompt Template Service - 提示词模板服务
"""
import logging
from typing import Optional, List, Dict, Any
from datetime import datetime
from sqlmodel import Session, select, func, and_, or_

from src.config.database import engine
from src.models.prompt_template import (
    PromptTemplate,
    PromptTemplateCreate,
    PromptTemplateUpdate,
    PromptTemplateResponse,
    PromptTemplateFavorite
)

logger = logging.getLogger(__name__)


class PromptTemplateService:
    """提示词模板服务类"""
    
    # 默认分类
    DEFAULT_CATEGORIES = [
        ("general", "通用"),
        ("character", "角色"),
        ("scene", "场景"),
        ("style", "风格"),
        ("camera", "镜头"),
        ("lighting", "光照"),
        ("quality", "画质"),
    ]
    
    # 系统预设模板
    DEFAULT_TEMPLATES = [
        {
            "name": "高清写实",
            "description": "适用于需要高质量写实效果的场景",
            "content": "{prompt}, highly detailed, photorealistic, 8k resolution, professional photography, sharp focus, masterpiece",
            "category": "quality",
            "tags": "高清,写实,8k",
            "target_type": "image",
            "is_public": True,
        },
        {
            "name": "动漫风格",
            "description": "日系动漫风格渲染",
            "content": "{prompt}, anime style, manga illustration, vibrant colors, clean line art, studio ghibli inspired",
            "category": "style",
            "tags": "动漫,日系,插画",
            "target_type": "image",
            "is_public": True,
        },
        {
            "name": "赛博朋克",
            "description": "未来科幻赛博朋克风格",
            "content": "{prompt}, cyberpunk style, neon lights, futuristic city, high tech low life, dystopian atmosphere, glowing accents",
            "category": "style",
            "tags": "赛博朋克,科幻,霓虹",
            "target_type": "both",
            "is_public": True,
        },
        {
            "name": "电影镜头",
            "description": "电影级镜头语言",
            "content": "{prompt}, cinematic shot, film grain, dramatic lighting, anamorphic lens, bokeh background, color graded",
            "category": "camera",
            "tags": "电影,镜头, cinematic",
            "target_type": "video",
            "is_public": True,
        },
        {
            "name": "角色白底",
            "description": "适合角色设计的白底图",
            "content": "{prompt}, character design, pure white background, professional studio lighting, clean edges, full body portrait",
            "category": "character",
            "tags": "角色,白底,设计",
            "target_type": "image",
            "is_public": True,
        },
        {
            "name": "自然风景",
            "description": "优美的自然风景场景",
            "content": "{prompt}, natural landscape, breathtaking scenery, golden hour lighting, atmospheric perspective, nature photography",
            "category": "scene",
            "tags": "风景,自然,户外",
            "target_type": "both",
            "is_public": True,
        },
        {
            "name": "史诗场景",
            "description": "宏大史诗感场景",
            "content": "{prompt}, epic scale, grand architecture, dramatic clouds, golden hour, wide angle, concept art style",
            "category": "scene",
            "tags": "史诗,宏大,场景",
            "target_type": "both",
            "is_public": True,
        },
        {
            "name": "柔光人像",
            "description": "柔和光线人像摄影",
            "content": "{prompt}, soft lighting portrait, natural light, shallow depth of field, bokeh, flattering shadows, professional photography",
            "category": "lighting",
            "tags": "人像,柔光,摄影",
            "target_type": "image",
            "is_public": True,
        },
    ]
    
    @staticmethod
    def init_default_templates():
        """初始化系统默认模板"""
        with Session(engine) as session:
            # 检查是否已初始化
            existing_count = session.exec(
                select(func.count()).where(PromptTemplate.user_id == None)
            ).one()
            
            if existing_count > 0:
                logger.info(f"Default templates already initialized ({existing_count} found)")
                return
            
            # 创建默认模板
            for template_data in PromptTemplateService.DEFAULT_TEMPLATES:
                template = PromptTemplate(
                    **template_data,
                    user_id=None,  # 系统模板
                    usage_count=0
                )
                session.add(template)
            
            session.commit()
            logger.info(f"Initialized {len(PromptTemplateService.DEFAULT_TEMPLATES)} default templates")
    
    @staticmethod
    def create_template(
        user_id: str,
        data: PromptTemplateCreate
    ) -> PromptTemplateResponse:
        """创建新模板"""
        with Session(engine) as session:
            template = PromptTemplate(
                **data.model_dump(),
                user_id=user_id
            )
            session.add(template)
            session.commit()
            session.refresh(template)
            
            return PromptTemplateService._to_response(template, user_id)
    
    @staticmethod
    def get_template(
        template_id: str,
        user_id: Optional[str] = None
    ) -> Optional[PromptTemplateResponse]:
        """获取单个模板"""
        with Session(engine) as session:
            template = session.get(PromptTemplate, template_id)
            if not template:
                return None
            
            return PromptTemplateService._to_response(template, user_id)
    
    @staticmethod
    def list_templates(
        user_id: str,
        category: Optional[str] = None,
        target_type: Optional[str] = None,
        search: Optional[str] = None,
        favorites_only: bool = False,
        page: int = 1,
        page_size: int = 20
    ) -> Dict[str, Any]:
        """获取模板列表"""
        with Session(engine) as session:
            # 构建查询条件
            conditions = []
            
            # 公开模板或用户自己的模板
            conditions.append(
                or_(
                    PromptTemplate.is_public == True,
                    PromptTemplate.user_id == user_id
                )
            )
            
            if category:
                conditions.append(PromptTemplate.category == category)
            
            if target_type:
                conditions.append(
                    or_(
                        PromptTemplate.target_type == target_type,
                        PromptTemplate.target_type == "both"
                    )
                )
            
            if search:
                search_term = f"%{search}%"
                conditions.append(
                    or_(
                        PromptTemplate.name.contains(search_term),
                        PromptTemplate.description.contains(search_term),
                        PromptTemplate.tags.contains(search_term)
                    )
                )
            
            # 如果是仅收藏
            if favorites_only:
                favorite_ids = session.exec(
                    select(PromptTemplateFavorite.template_id)
                    .where(PromptTemplateFavorite.user_id == user_id)
                ).all()
                conditions.append(PromptTemplate.id.in_(favorite_ids))
            
            # 构建查询
            query = select(PromptTemplate)
            if conditions:
                query = query.where(and_(*conditions))
            
            # 统计总数
            count_query = select(func.count()).select_from(PromptTemplate)
            if conditions:
                count_query = count_query.where(and_(*conditions))
            total = session.exec(count_query).one()
            
            # 分页和排序
            query = query.order_by(PromptTemplate.usage_count.desc())
            query = query.offset((page - 1) * page_size).limit(page_size)
            
            templates = session.exec(query).all()
            
            # 获取用户收藏列表
            favorite_ids = set(session.exec(
                select(PromptTemplateFavorite.template_id)
                .where(PromptTemplateFavorite.user_id == user_id)
            ).all())
            
            return {
                "items": [
                    PromptTemplateService._to_response(t, user_id, favorite_ids)
                    for t in templates
                ],
                "total": total,
                "page": page,
                "page_size": page_size
            }
    
    @staticmethod
    def update_template(
        template_id: str,
        user_id: str,
        data: PromptTemplateUpdate
    ) -> Optional[PromptTemplateResponse]:
        """更新模板"""
        with Session(engine) as session:
            template = session.get(PromptTemplate, template_id)
            if not template:
                return None
            
            # 检查权限
            if template.user_id != user_id:
                raise PermissionError("Cannot update template created by other users")
            
            # 更新字段
            for key, value in data.model_dump(exclude_unset=True).items():
                setattr(template, key, value)
            
            template.updated_at = datetime.utcnow()
            session.add(template)
            session.commit()
            session.refresh(template)
            
            return PromptTemplateService._to_response(template, user_id)
    
    @staticmethod
    def delete_template(
        template_id: str,
        user_id: str
    ) -> bool:
        """删除模板"""
        with Session(engine) as session:
            template = session.get(PromptTemplate, template_id)
            if not template:
                return False
            
            # 检查权限
            if template.user_id != user_id:
                raise PermissionError("Cannot delete template created by other users")
            
            session.delete(template)
            session.commit()
            return True
    
    @staticmethod
    def toggle_favorite(
        template_id: str,
        user_id: str
    ) -> bool:
        """切换收藏状态"""
        with Session(engine) as session:
            # 检查是否已收藏
            existing = session.exec(
                select(PromptTemplateFavorite).where(
                    and_(
                        PromptTemplateFavorite.user_id == user_id,
                        PromptTemplateFavorite.template_id == template_id
                    )
                )
            ).first()
            
            if existing:
                # 取消收藏
                session.delete(existing)
                session.commit()
                return False
            else:
                # 添加收藏
                favorite = PromptTemplateFavorite(
                    user_id=user_id,
                    template_id=template_id
                )
                session.add(favorite)
                session.commit()
                return True
    
    @staticmethod
    def increment_usage(template_id: str):
        """增加模板使用次数"""
        with Session(engine) as session:
            template = session.get(PromptTemplate, template_id)
            if template:
                template.usage_count += 1
                session.add(template)
                session.commit()
    
    @staticmethod
    def get_categories() -> List[Dict[str, Any]]:
        """获取分类列表及其模板数量"""
        with Session(engine) as session:
            result = []
            for value, label in PromptTemplateService.DEFAULT_CATEGORIES:
                count = session.exec(
                    select(func.count())
                    .where(PromptTemplate.category == value)
                ).one()
                result.append({
                    "value": value,
                    "label": label,
                    "count": count
                })
            return result
    
    @staticmethod
    def apply_template(
        template_id: str,
        user_prompt: str
    ) -> Optional[str]:
        """应用模板到提示词"""
        with Session(engine) as session:
            template = session.get(PromptTemplate, template_id)
            if not template:
                return None
            
            # 增加使用次数
            template.usage_count += 1
            session.add(template)
            session.commit()
            
            # 替换模板中的占位符
            return template.content.replace("{prompt}", user_prompt)
    
    @staticmethod
    def _to_response(
        template: PromptTemplate,
        user_id: Optional[str] = None,
        favorite_ids: Optional[set] = None
    ) -> PromptTemplateResponse:
        """转换为响应模型"""
        if favorite_ids is None and user_id:
            with Session(engine) as session:
                favorite_ids = set(session.exec(
                    select(PromptTemplateFavorite.template_id)
                    .where(PromptTemplateFavorite.user_id == user_id)
                ).all())
        
        is_favorite = template.id in (favorite_ids or set())
        
        return PromptTemplateResponse(
            id=template.id,
            name=template.name,
            description=template.description,
            content=template.content,
            category=template.category,
            tags=template.tags,
            target_type=template.target_type,
            is_public=template.is_public,
            usage_count=template.usage_count,
            user_id=template.user_id,
            created_at=template.created_at,
            updated_at=template.updated_at,
            is_favorite=is_favorite
        )