# -*- coding: utf-8 -*-
from __future__ import annotations

import datetime
import typing
import uuid

import pydantic

from hotpocket_common.constants import AssociationsSearchMode

from .base import ModelOut, Query
from .saves import SaveOut


class AssociationOut(ModelOut):
    archived_at: datetime.datetime | None
    starred_at: datetime.datetime | None
    target_uuid: uuid.UUID = pydantic.Field(alias='target_id')
    target_meta: dict
    target_title: str | None
    target_description: str | None

    @property
    def is_starred(self) -> bool:
        return self.starred_at is not None

    def get_title(self) -> str | None:
        return (
            self.target_title
            if self.target_title is not None
            else self.target_meta.get('title', None)
        )

    def get_description(self) -> str | None:
        return (
            self.target_description
            if self.target_description is not None
            else self.target_meta.get('description', None)
        )

    @property
    def title(self) -> str | None:
        return self.get_title()

    @property
    def description(self) -> str | None:
        return self.get_description()


class AssociationWithTargetOut(AssociationOut):
    target: SaveOut

    @classmethod
    def from_association_save(cls: typing.Type[typing.Self],
                              association: AssociationOut,
                              save: SaveOut,
                              ) -> typing.Self:
        return cls.model_validate(
            obj={
                **association.model_dump(by_alias=True),
                'target': save,
            },
        )

    @property
    def title(self) -> str | None:
        return self.get_title() or self.target.title

    @property
    def description(self) -> str | None:
        return self.get_description() or self.target.description


class AssociationIn(pydantic.BaseModel):
    archived_at: datetime.datetime | None


class AssociationsQuery(Query):
    account_uuid: uuid.UUID
    before: uuid.UUID | None = pydantic.Field(default=None)
    after: uuid.UUID | None = pydantic.Field(default=None)
    search: str | None = pydantic.Field(default=None)
    mode: AssociationsSearchMode = pydantic.Field(default=AssociationsSearchMode.DEFAULT)


class AssociationUpdateIn(pydantic.BaseModel):
    target_title: str | None = pydantic.Field(default=None)
    target_description: str | None = pydantic.Field(default=None)
