"""
Strategy Application — Strategic Theme Service.

سرویس اپلیکیشن برای مدیریت تم‌های راهبردی.
"""

from typing import List, Optional
from uuid import UUID

from apps.core.event_bus.events import event_bus

from ..dtos.strategy_dtos import (
    StrategicThemeCreateDTO,
    StrategicThemeUpdateDTO,
    StrategicThemeResponseDTO,
)
from ...domain.entities.strategic_theme import StrategicTheme
from ...domain.events.strategy_events import (
    StrategicThemeCreated,
    StrategicThemeActivated,
    StrategicThemeCompleted,
    StrategicThemeArchived,
)
from ...infrastructure.repositories.strategic_theme_repo import DjangoStrategicThemeRepository


class StrategicThemeService:
    """سرویس مدیریت تم راهبردی."""

    def __init__(self):
        self.repo = DjangoStrategicThemeRepository()

    # ─── CRUD ─────────────────────────────────

    def create(self, dto: StrategicThemeCreateDTO) -> StrategicThemeResponseDTO:
        entity = StrategicTheme(
            tenant_id=dto.tenant_id,
            vision_id=dto.vision_id,
            name=dto.name,
            description=dto.description,
            priority=dto.priority,
            owner_id=dto.owner_id,
            start_date=dto.start_date,
            end_date=dto.end_date,
            sort_order=dto.sort_order,
            tags=dto.tags or [],
            metadata=dto.metadata or {},
        )
        saved = self.repo.save(entity)

        event_bus.publish(StrategicThemeCreated(
            tenant_id=saved.tenant_id,
            theme_id=saved.id,
            vision_id=saved.vision_id,
            name=saved.name,
        ))

        return self._to_response(saved)

    def get_by_id(self, theme_id: UUID) -> Optional[StrategicThemeResponseDTO]:
        entity = self.repo.find_by_id(theme_id)
        if not entity:
            return None
        return self._to_response(entity)

    def list_by_tenant(self, tenant_id: UUID) -> List[StrategicThemeResponseDTO]:
        entities = self.repo.find_by_tenant(tenant_id)
        return [self._to_response(e) for e in entities]

    def list_by_vision(self, vision_id: UUID) -> List[StrategicThemeResponseDTO]:
        entities = self.repo.find_by_vision(vision_id)
        return [self._to_response(e) for e in entities]

    def list_active(self, tenant_id: UUID) -> List[StrategicThemeResponseDTO]:
        entities = self.repo.find_active_by_tenant(tenant_id)
        return [self._to_response(e) for e in entities]

    def update(self, theme_id: UUID, dto: StrategicThemeUpdateDTO) -> Optional[StrategicThemeResponseDTO]:
        entity = self.repo.find_by_id(theme_id)
        if not entity:
            return None

        if dto.name is not None:
            entity.name = dto.name
        if dto.description is not None:
            entity.description = dto.description
        if dto.priority is not None:
            entity.set_priority(dto.priority)
        if dto.owner_id is not None:
            entity.owner_id = dto.owner_id
        if dto.start_date is not None:
            entity.start_date = dto.start_date
        if dto.end_date is not None:
            entity.end_date = dto.end_date
        if dto.sort_order is not None:
            entity.sort_order = dto.sort_order
        if dto.tags is not None:
            entity.tags = dto.tags
        if dto.metadata is not None:
            entity.metadata = dto.metadata

        saved = self.repo.save(entity)
        return self._to_response(saved)

    def delete(self, theme_id: UUID) -> bool:
        return self.repo.delete(theme_id)

    # ─── Status Transitions ───────────────────

    def activate(self, theme_id: UUID) -> Optional[StrategicThemeResponseDTO]:
        entity = self.repo.find_by_id(theme_id)
        if not entity:
            return None
        entity.activate()
        saved = self.repo.save(entity)

        event_bus.publish(StrategicThemeActivated(
            tenant_id=saved.tenant_id,
            theme_id=saved.id,
        ))

        return self._to_response(saved)

    def complete(self, theme_id: UUID) -> Optional[StrategicThemeResponseDTO]:
        entity = self.repo.find_by_id(theme_id)
        if not entity:
            return None
        entity.complete()
        saved = self.repo.save(entity)

        event_bus.publish(StrategicThemeCompleted(
            tenant_id=saved.tenant_id,
            theme_id=saved.id,
        ))

        return self._to_response(saved)

    def archive(self, theme_id: UUID) -> Optional[StrategicThemeResponseDTO]:
        entity = self.repo.find_by_id(theme_id)
        if not entity:
            return None
        entity.archive()
        saved = self.repo.save(entity)

        event_bus.publish(StrategicThemeArchived(
            tenant_id=saved.tenant_id,
            theme_id=saved.id,
        ))

        return self._to_response(saved)

    # ─── Helpers ──────────────────────────────

    @staticmethod
    def _to_response(entity: StrategicTheme) -> StrategicThemeResponseDTO:
        return StrategicThemeResponseDTO(
            id=entity.id,
            tenant_id=entity.tenant_id,
            vision_id=entity.vision_id,
            name=entity.name,
            description=entity.description,
            priority=entity.priority,
            status=entity.status,
            owner_id=entity.owner_id,
            start_date=entity.start_date,
            end_date=entity.end_date,
            sort_order=entity.sort_order,
            tags=entity.tags or [],
            metadata=entity.metadata or {},
            created_at=entity.created_at,
            updated_at=entity.updated_at,
        )
