"""Parser for ``<BaseParams>`` elements in DMSContent responses."""
import xml.etree.ElementTree as ET
from datetime import date, datetime


class DmsContentObjectBaseParams:
    """Represents the ``<BaseParams>`` element of a HOL ``<Object>``.

    Available only when ``baseParams=1`` is set in the ``<DmsQuery>``. Provides
    auditing metadata such as creator, timestamps, owner, and archiving information.
    """

    def __init__(self, node: ET.Element):
        self._node = node

    @property
    def creator(self) -> str:
        """Login name of the user who created the object."""
        creator = self._node.find("Creator")
        if creator is not None:
            return creator.text or ""
        return ""

    @property
    def created(self) -> datetime:
        """Timestamp when the object was created (Unix epoch, converted to local time).

        Raises:
            ValueError: If the ``<Created>`` element is absent.
        """
        created = self._node.find("Created")
        if created is not None:
            return datetime.fromtimestamp(int(created.attrib["value"]))

        raise ValueError("<Created> tag in <BaseParams> not found")

    @property
    def modifier(self) -> str:
        """Login name of the user who last modified the object."""
        modifier = self._node.find("Modifier")
        if modifier is not None:
            return modifier.text or ""
        return ""

    @property
    def modified(self) -> datetime:
        """Timestamp when the object was last modified (Unix epoch, converted to local time).

        Raises:
            ValueError: If the ``<Modified>`` element is absent.
        """
        modified = self._node.find("Modified")
        if modified is not None:
            return datetime.fromtimestamp(int(modified.attrib["value"]))

        raise ValueError("<Modified> tag in <BaseParams> not found")

    @property
    def owner(self) -> str:
        """Display name of the object owner."""
        owner = self._node.find("Owner")
        if owner is not None:
            return owner.text or ""
        return ""

    @property
    def owner_osguid(self) -> str:
        """Object storage GUID of the owner user."""
        owner = self._node.find("Owner")
        if owner is not None:
            return owner.attrib["osguid"] or ""
        return ""

    @property
    def links(self) -> int:
        """Number of links pointing to this object."""
        links = self._node.find("Links")
        if links is not None:
            return int(links.text or 0)
        return 0

    @property
    def txt_notice_count(self) -> int:
        """Number of text notes (sticky notes) attached to this object."""
        txt_notice_count = self._node.find("TxtNoticeCount")
        if txt_notice_count is not None:
            return int(txt_notice_count.text or 0)
        return 0

    @property
    def pdf_annotation_count(self) -> int:
        """Number of PDF annotations attached to this object."""
        pdf_annotation_count = self._node.find("PdfAnnotationCount")
        if pdf_annotation_count is not None:
            return int(pdf_annotation_count.text or 0)
        return 0

    @property
    def system_id(self) -> int:
        """Numeric system (cabinet) ID this object belongs to."""
        system_id = self._node.find("SystemID")
        if system_id is not None:
            return int(system_id.text or 0)
        return 0

    @property
    def foreign_id(self) -> str:
        """External (foreign) ID string for cross-system referencing."""
        foreign_id = self._node.find("ForeignID")
        if foreign_id is not None:
            return foreign_id.text or ""
        return ""

    @property
    def archive_state(self) -> str:
        """Display text of the archive state (HOL only, requires ``baseParams=1``)."""
        node = self._node.find("ArchiveState")
        return node.text or "" if node is not None else ""

    @property
    def archive_state_value(self) -> int:
        """Numeric value of the archive state (HOL only, requires ``baseParams=1``)."""
        node = self._node.find("ArchiveState")
        return int(node.get("value", "-1")) if node is not None else -1

    @property
    def archivist(self) -> str:
        """Login name of the user who archived the object (HOL only, requires ``baseParams=1``)."""
        node = self._node.find("Archivist")
        return node.text or "" if node is not None else ""

    @property
    def archive_date(self) -> date | None:
        """Archive date (HOL only, requires ``baseParams=1``).

        Returns:
            date: Parsed date, or ``None`` if the element is absent or empty.
        """
        node = self._node.find("ArchiveDate")
        text = node.text if node is not None else None
        return datetime.strptime(text, "%d.%m.%Y").date() if text else None

    @property
    def locked(self) -> str:
        """Display text of the lock state (HOL only, requires ``baseParams=1``)."""
        node = self._node.find("Locked")
        return node.text or "" if node is not None else ""

    @property
    def locked_value(self) -> int:
        """Numeric lock state value (HOL only, requires ``baseParams=1``)."""
        node = self._node.find("Locked")
        return int(node.get("value", "0")) if node is not None else 0

    @property
    def version(self) -> int:
        """Object version number (HOL only, requires ``baseParams=1``)."""
        node = self._node.find("Version")
        return int(node.text or "0") if node is not None else 0

    @property
    def creation_date(self) -> date | None:
        """Creation date without time (HOL only, requires ``baseParams=1``).

        Returns:
            date: Parsed date, or ``None`` if the element is absent or empty.
        """
        node = self._node.find("CreationDate")
        text = node.text if node is not None else None
        return datetime.strptime(text, "%d.%m.%Y").date() if text else None
