"""
Admin Service - Projects Module

包含项目管理相关功能。
"""

import logging
from typing import Optional, Dict, Any, Tuple, List

from sqlmodel import Session, select, func
from datetime import datetime

from src.config.database import engine
from src.models.entities import UserDB, ProjectDB, AssetDB, EpisodeDB, StoryboardDB
from src.models.admin_schemas import (
    AdminProjectListItem,
    AdminProjectDetailResponse,
)

logger = logging.getLogger(__name__)


def _timestamp_to_iso(ts: Optional[float]) -> str:
    """Convert timestamp to ISO format string"""
    if not ts:
        return ""
    return datetime.fromtimestamp(ts).isoformat()


class ProjectManagementService:
    """Project management service for admin operations"""

    async def list_projects(
        self,
        page: int = 1,
        page_size: int = 20,
        filters: Optional[Dict[str, Any]] = None,
        sort_by: str = "created_at",
        sort_order: str = "desc",
    ) -> Tuple[List[AdminProjectListItem], int]:
        """List projects with pagination and filtering"""
        with Session(engine) as session:
            query = select(ProjectDB)

            # Apply filters
            if filters:
                if filters.get("status"):
                    query = query.where(ProjectDB.status == filters["status"])
                if filters.get("type"):
                    query = query.where(ProjectDB.type == filters["type"])
                if filters.get("search"):
                    search = f"%{filters['search']}%"
                    query = query.where(ProjectDB.name.ilike(search))

            # Get total count
            total = session.exec(
                select(func.count()).select_from(query.subquery())
            ).one()

            # Apply sorting
            if sort_by == "created_at":
                sort_column = ProjectDB.created_at
            elif sort_by == "updated_at":
                sort_column = ProjectDB.updated_at
            elif sort_by == "name":
                sort_column = ProjectDB.name
            else:
                sort_column = ProjectDB.created_at

            if sort_order.lower() == "desc":
                query = query.order_by(sort_column.desc())
            else:
                query = query.order_by(sort_column.asc())

            # Apply pagination
            offset = (page - 1) * page_size
            query = query.offset(offset).limit(page_size)

            projects = session.exec(query).all()

            items = []
            for project in projects:
                # Count related entities
                asset_count = session.exec(
                    select(func.count()).select_from(AssetDB).where(AssetDB.project_id == project.id)
                ).one()

                episode_count = session.exec(
                    select(func.count()).select_from(EpisodeDB).where(EpisodeDB.project_id == project.id)
                ).one()

                storyboard_count = session.exec(
                    select(func.count()).select_from(StoryboardDB).where(StoryboardDB.project_id == project.id)
                ).one()

                # Get owner info
                owner_name = None
                owner_email = None
                if project.user_id:
                    user = session.exec(
                        select(UserDB).where(UserDB.id == project.user_id)
                    ).first()
                    if user:
                        owner_name = user.username
                        owner_email = user.email

                items.append(
                    AdminProjectListItem(
                        id=project.id,
                        name=project.name,
                        description=project.description,
                        type=project.type,
                        status=project.status,
                        created_at=_timestamp_to_iso(project.created_at),
                        updated_at=_timestamp_to_iso(project.updated_at),
                        owner_id=project.user_id,
                        owner_name=owner_name,
                        owner_email=owner_email,
                        asset_count=asset_count,
                        episode_count=episode_count,
                        storyboard_count=storyboard_count,
                    )
                )

            return items, total

    async def get_project(self, project_id: str) -> Optional[AdminProjectDetailResponse]:
        """Get project details by ID"""
        with Session(engine) as session:
            project = session.exec(
                select(ProjectDB).where(ProjectDB.id == project_id)
            ).first()

            if not project:
                return None

            # Get related entities
            assets = session.exec(
                select(AssetDB).where(AssetDB.project_id == project_id)
            ).all()

            episodes = session.exec(
                select(EpisodeDB).where(EpisodeDB.project_id == project_id)
            ).all()

            storyboards = session.exec(
                select(StoryboardDB).where(StoryboardDB.project_id == project_id)
            ).all()

            # Get owner info
            owner_name = None
            owner_email = None
            if project.user_id:
                user = session.exec(
                    select(UserDB).where(UserDB.id == project.user_id)
                ).first()
                if user:
                    owner_name = user.username
                    owner_email = user.email

            return AdminProjectDetailResponse(
                id=project.id,
                name=project.name,
                description=project.description,
                type=project.type,
                status=project.status,
                created_at=_timestamp_to_iso(project.created_at),
                updated_at=_timestamp_to_iso(project.updated_at),
                owner_id=project.user_id,
                owner_name=owner_name,
                owner_email=owner_email,
                assets=[
                    {
                        "id": a.id,
                        "name": a.name,
                        "type": a.type,
                        "desc": a.desc,
                    }
                    for a in assets
                ],
                episodes=[
                    {
                        "id": e.id,
                        "title": e.title,
                        "order": e.order_index,
                        "status": e.status,
                    }
                    for e in episodes
                ],
                storyboards=[
                    {
                        "id": s.id,
                        "shot": s.shot,
                        "order": s.order_index,
                        "type": s.type,
                    }
                    for s in storyboards
                ],
            )

    async def delete_project(self, project_id: str) -> bool:
        """Delete a project"""
        with Session(engine) as session:
            project = session.exec(
                select(ProjectDB).where(ProjectDB.id == project_id)
            ).first()

            if not project:
                return False

            session.delete(project)
            session.commit()
            return True
