"""
Strategy Application — Vision Service.

سرویس اپلیکیشن برای مدیریت چشم‌اندازهای سازمانی.
"""

from typing import List, Optional
from uuid import UUID

from apps.core.event_bus.events import event_bus

from ..dtos.strategy_dtos import (
    VisionCreateDTO,
    VisionUpdateDTO,
    VisionResponseDTO,
)
from ...domain.entities.vision import Vision
from ...domain.events.strategy_events import (
    VisionCreated,
    VisionActivated,
    VisionArchived,
)
from ...infrastructure.repositories.vision_repo import DjangoVisionRepository


class VisionService:
    """سرویس مدیریت چشم‌انداز."""

    def __init__(self):
        self.repo = DjangoVisionRepository()

    # ─── CRUD ─────────────────────────────────

    def create(self, dto: VisionCreateDTO) -> VisionResponseDTO:
        entity = Vision(
            tenant_id=dto.tenant_id,
            title=dto.title,
            description=dto.description,
            time_horizon_start=dto.time_horizon_start,
            time_horizon_end=dto.time_horizon_end,
            owner_id=dto.owner_id,
            tags=dto.tags or [],
            metadata=dto.metadata or {},
        )
        saved = self.repo.save(entity)

        event_bus.publish(VisionCreated(
            tenant_id=saved.tenant_id,
            vision_id=saved.id,
            title=saved.title,
        ))

        return self._to_response(saved)

    def get_by_id(self, vision_id: UUID) -> Optional[VisionResponseDTO]:
        entity = self.repo.find_by_id(vision_id)
        if not entity:
            return None
        return self._to_response(entity)

    def list_by_tenant(self, tenant_id: UUID) -> List[VisionResponseDTO]:
        entities = self.repo.find_by_tenant(tenant_id)
        return [self._to_response(e) for e in entities]

    def list_active(self, tenant_id: UUID) -> List[VisionResponseDTO]:
        entities = self.repo.find_active_by_tenant(tenant_id)
        return [self._to_response(e) for e in entities]

    def update(self, vision_id: UUID, dto: VisionUpdateDTO) -> Optional[VisionResponseDTO]:
        entity = self.repo.find_by_id(vision_id)
        if not entity:
            return None

        if dto.title is not None:
            entity.title = dto.title
        if dto.description is not None:
            entity.description = dto.description
        if dto.time_horizon_start is not None:
            entity.time_horizon_start = dto.time_horizon_start
        if dto.time_horizon_end is not None:
            entity.time_horizon_end = dto.time_horizon_end
        if dto.owner_id is not None:
            entity.owner_id = dto.owner_id
        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, vision_id: UUID) -> bool:
        return self.repo.delete(vision_id)

    # ─── Status Transitions ───────────────────

    def activate(self, vision_id: UUID) -> Optional[VisionResponseDTO]:
        entity = self.repo.find_by_id(vision_id)
        if not entity:
            return None
        entity.activate()
        saved = self.repo.save(entity)

        event_bus.publish(VisionActivated(
            tenant_id=saved.tenant_id,
            vision_id=saved.id,
        ))

        return self._to_response(saved)

    def archive(self, vision_id: UUID) -> Optional[VisionResponseDTO]:
        entity = self.repo.find_by_id(vision_id)
        if not entity:
            return None
        entity.archive()
        saved = self.repo.save(entity)

        event_bus.publish(VisionArchived(
            tenant_id=saved.tenant_id,
            vision_id=saved.id,
        ))

        return self._to_response(saved)

    # ─── Helpers ──────────────────────────────

    @staticmethod
    def _to_response(entity: Vision) -> VisionResponseDTO:
        return VisionResponseDTO(
            id=entity.id,
            tenant_id=entity.tenant_id,
            title=entity.title,
            description=entity.description,
            time_horizon_start=entity.time_horizon_start,
            time_horizon_end=entity.time_horizon_end,
            status=entity.status,
            owner_id=entity.owner_id,
            tags=entity.tags or [],
            metadata=entity.metadata or {},
            created_at=entity.created_at,
            updated_at=entity.updated_at,
        )
