from datetime import datetime
from typing import Optional
from uuid import UUID

from pydantic import BaseModel
from talentro.acquisition.dataclasses import CampaignInfo
from talentro.candidates.models import Application as ApplicationModel, Document as DocumentModel, \
    Candidate as CandidateModel
from talentro.vacancies.dataclasses import VacancyInfo


class CandidateInfo(BaseModel):
    id: UUID
    created_at: datetime
    updated_at: Optional[datetime]
    organization: UUID

    first_name: Optional[str] = None
    last_name: Optional[str] = None
    email: Optional[str] = None
    phone_number: Optional[str] = None
    city: Optional[str] = None
    country: Optional[str] = None

    @classmethod
    async def from_model(cls: "CandidateInfo", model: CandidateModel) -> 'CandidateInfo':
        return CandidateInfo(
            id=model.id,
            created_at=model.created_at,
            updated_at=model.updated_at,
            organization=model.organization,

            first_name=model.first_name,
            last_name=model.last_name,
            email=model.email,
            phone_number=model.phone_number,
            city=model.city,
            country=model.country,
        )


class ApplicationData(BaseModel):
    status: str
    source: str
    candidate_id: UUID
    vacancy_reference_number: str
    screening_answers: dict


class Application(ApplicationData):
    id: UUID
    created_at: datetime
    updated_at: Optional[datetime]
    organization: UUID


class DocumentInfo(BaseModel):
    id: UUID
    created_at: datetime
    updated_at: Optional[datetime]
    organization: UUID

    type: str
    blob_name: str

    @classmethod
    async def from_model(cls: "DocumentInfo", model: DocumentModel) -> 'DocumentInfo':
        return DocumentInfo(
            id=model.id,
            created_at=model.created_at,
            updated_at=model.updated_at,
            organization=model.organization,
            type=model.type,
            blob_name=model.blob_name
        )


class ApplicationInfo(BaseModel):
    id: UUID
    created_at: datetime
    updated_at: Optional[datetime]
    organization: UUID

    status: str
    screening_answers: dict

    vacancy: Optional[VacancyInfo]
    campaign: Optional[CampaignInfo]
    candidate: Optional[CandidateInfo]

    documents: list[DocumentInfo]

    @classmethod
    async def from_model(cls: "ApplicationInfo", model: ApplicationModel) -> 'ApplicationInfo':
        if model.source:
            campaign = await CampaignInfo.resolve_object(model.source.campaign_id, model.organization)
        else:
            campaign = None

        if model.vacancy_id:
            vacancy = await VacancyInfo.resolve_object(model.vacancy_id, model.organization)
        else:
            vacancy = None

        if model.candidate:
            candidate = await CandidateInfo.from_model(model.candidate)
        else:
            candidate = None

        return cls(
            id=model.id,
            created_at=model.created_at,
            updated_at=model.updated_at,
            organization=model.organization,

            screening_answers=model.screening_answers,
            status=model.status,

            vacancy=vacancy,
            campaign=campaign,
            candidate=candidate,

            documents=[await DocumentInfo.from_model(document) for document in model.documents],
        )
