"""Module containg definions of simple detection types."""

from dataclasses import dataclass
from typing import Optional


@dataclass
class Detection:
    """Interface for detections.

    Should be used as base class for all detections.
    It should not be used directly. For other detections see: OtherDetection class
    """

    TYPE_NAME = "detection"

    def __hash__(self) -> int:
        """Hash function for detection."""
        return (type(self), *(self.__dict__.values())).__hash__()


class MorphosyntacticInfoMixin:
    """Mixin for detections with morphosyntactic information.

    Eg. detection of "Rolexes" can be thought of as "Rolex"
        with morphosyntactic tag "NNS" (noun, plural).
    """

    def __init__(
        self,
        morpho_tag: Optional[str] = None,
        lemma: Optional[str] = None,
        *args,
        **kwargs
    ) -> None:
        """Initialization of MorphosyntacticInfoMixin.

        Args:
            morpho_tag (str): Morphosyntactic tag of detection, eg. "NNS",
                "sg:nom:m1" etc.
            lemma (str): Lemma of detection, eg. "Rolex", "Warszawa" etc.

        """
        super().__init__(*args, **kwargs)
        self._morpho_tag = morpho_tag
        self._lemma = lemma

    @property
    def morpho_tag(self) -> str:
        """Morphosyntactic tag of detection."""
        return self._morpho_tag

    @property
    def lemma(self) -> str:
        """Lemma of detection."""
        return self._lemma


class NameDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing name detection.

    Eg.: "John", "Mark"
    """

    TYPE_NAME = "name"


class SurnameDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing surname detection.

    Eg.: "Smith", "Johnson"
    """

    TYPE_NAME = "surname"


class LocationDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing location detection.

    Eg.: "Park Narodowy Białowieski", "Tatry"
    """

    TYPE_NAME = "location"


class OrganizationNameDetection(MorphosyntacticInfoMixin, Detection):
    """Class for organization name detection.

    Eg.: "Apple", "Microsoft"
    """

    TYPE_NAME = "organization_name"


class ProperNameDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing proper name detection.

    Eg.: "Rolex"
    """

    TYPE_NAME = "proper_name"


class TitleDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing title detection.

    Eg.: "Fast and Furious", "The Lord of the Rings"
    """

    TYPE_NAME = "title"


class HydronymDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing hydronym detection.

    Eg.: "Wisła", "Odra"
    """

    TYPE_NAME = "hydronym"


class StreetNameDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing street name detection.

    Eg.: "Marszałkowska", "Kościuszki"
    """

    TYPE_NAME = "street_name"


class CityDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing city detection.

    Eg.: "Warsaw", "Berlin"
    """

    TYPE_NAME = "city"


class CountryDetection(MorphosyntacticInfoMixin, Detection):
    """Class representing country detection.

    Eg.: "Poland", "Germany"
    """

    TYPE_NAME = "country"


class UrlDetection(Detection):
    """Class for url detection.

    Eg.: "https://www.google.com", "www.google.com"
    """

    TYPE_NAME = "url"


class UserDetection(Detection):
    """Class for user detection.

    Eg.: "@bob25", "@angelica111"
    """

    TYPE_NAME = "user"


class EmailDetection(Detection):
    """Class representing email detection.

    Eg.: bob@gmail.com
    """

    TYPE_NAME = "email"


class NumberDetection(Detection):
    """Class for number detection.

    Eg.: "123", "123.456"
    """

    TYPE_NAME = "number"


class PhoneNumberDetection(NumberDetection):
    """Class for phone number detection.

    Eg.: "123-456-789", "+49 123 456 789"
    """

    TYPE_NAME = "phone_number"


class TINDetection(Detection):  # Tax Identification Number
    """Class for NIP (Tax Identification Number) detection.

    Eg.: "123-456-32-18", "1234563218"
    """

    TYPE_NAME = "tin"


class KRSDetection(Detection):  # National Court Register
    """Class for KRS (National Court Register) number detection.

    Eg.: "0000000123"
    """

    TYPE_NAME = "krs"


class SerialNumberDetection(Detection):
    """Serial number detection.

    Eg.: "AB1234567890"
    """

    TYPE_NAME = "serial_number"


class OtherDetection(Detection):  # Non standard entity
    """Detection of an entity that does not fit into other categories."""

    TYPE_NAME = "other"