"""
HRM Use Cases - Position Operations.

Single-purpose handlers for position and job management.
"""
from dataclasses import dataclass
from uuid import uuid4

from ..dtos.hrm_dtos import (
    CreatePositionDTO,
    CreateJobTitleDTO,
    PositionResponseDTO,
    JobTitleResponseDTO,
)
from ...domain.entities.position import Position, JobTitle, PositionStatus
from ...domain.repositories.interfaces import (
    IPositionRepository,
    IJobTitleRepository,
    IJobFamilyRepository,
)
from ...domain.exceptions.hrm_exceptions import PositionNotFoundError


@dataclass
class CreatePositionUseCase:
    """Use Case - ایجاد پست سازمانی."""

    position_repo: IPositionRepository

    def execute(self, dto: CreatePositionDTO, tenant_id=None) -> PositionResponseDTO:
        position = Position(
            id=uuid4(),
            tenant_id=tenant_id,
            title=dto.title,
            code=dto.code,
            job_title_id=dto.job_title_id,
            org_unit_id=dto.org_unit_id,
            legal_entity_id=dto.legal_entity_id,
            location_id=dto.location_id,
            reports_to_position_id=dto.reports_to_position_id,
            is_key_position=dto.is_key_position,
            budget_amount=dto.budget_amount,
            headcount=dto.headcount,
            fte=dto.fte,
            status=PositionStatus.ACTIVE,
        )
        position.validate()
        saved = self.position_repo.save(position)

        return PositionResponseDTO(
            id=saved.id,
            title=saved.title,
            code=saved.code,
            status=saved.status,
            is_vacant=saved.is_vacant,
            org_unit_id=saved.org_unit_id,
        )


@dataclass
class FillPositionUseCase:
    """Use Case - تخصیص کارمند به پست."""

    position_repo: IPositionRepository

    def execute(self, position_id, employee_id) -> PositionResponseDTO:
        position = self.position_repo.get_by_id(position_id)
        if not position:
            raise PositionNotFoundError(str(position_id))

        position.fill(employee_id)
        saved = self.position_repo.save(position)

        return PositionResponseDTO(
            id=saved.id,
            title=saved.title,
            code=saved.code,
            status=saved.status,
            is_vacant=saved.is_vacant,
            incumbent_employee_id=saved.incumbent_employee_id,
            org_unit_id=saved.org_unit_id,
        )


@dataclass
class VacatePositionUseCase:
    """Use Case - خالی کردن پست."""

    position_repo: IPositionRepository

    def execute(self, position_id) -> PositionResponseDTO:
        position = self.position_repo.get_by_id(position_id)
        if not position:
            raise PositionNotFoundError(str(position_id))

        position.vacate()
        saved = self.position_repo.save(position)

        return PositionResponseDTO(
            id=saved.id,
            title=saved.title,
            code=saved.code,
            status=saved.status,
            is_vacant=saved.is_vacant,
            org_unit_id=saved.org_unit_id,
        )


@dataclass
class CreateJobTitleUseCase:
    """Use Case - ایجاد عنوان شغلی."""

    job_title_repo: IJobTitleRepository

    def execute(self, dto: CreateJobTitleDTO, tenant_id=None) -> JobTitleResponseDTO:
        job = JobTitle(
            id=uuid4(),
            tenant_id=tenant_id,
            title=dto.title,
            title_en=dto.title_en,
            code=dto.code,
            job_family_id=dto.job_family_id,
            level=dto.level,
            description=dto.description,
            responsibilities=dto.responsibilities,
            qualifications=dto.qualifications,
            min_experience_years=dto.min_experience_years,
        )
        job.validate()
        saved = self.job_title_repo.save(job)

        return JobTitleResponseDTO(
            id=saved.id,
            title=saved.title,
            code=saved.code,
            level=saved.level,
            is_active=saved.is_active,
        )
