"""

    AUTHOR:

        Khushal P Soonderji

    DATE:

        Monday, 9th Dec., 2024.

    OBJECTIVE:

        To define how user info will be stored in the database.

    REFERENCES:

        N/A

    DOWNLOADS:

        N/A

"""


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                   IMPORT                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# To make sibling directories accessible for imports:
import sys
sys.path.append(".")
sys.path.append("..")

# For making data behaviour_models:
from pydantic import BaseModel, Field, field_validator, PastDatetime, AwareDatetime
from typing import Optional, Literal, Union

# My utils:
from utils_v2.string import regex
from utils_v2.date_time import date_time

# To work with MongoDB:
from bson.objectid import ObjectId

# To work with date and time:
import datetime


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                           MACROS / ONE-TIME INIT                                              ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                VARIABLES                                                      ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


# --- Nothing Yet


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                                  FUNCTIONS                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


class CoreUserInfoModel(BaseModel):

    fullName: str | None = Field(
        description = "the full name of the user as found in the database",
        frozen = True,
        default = None,
        examples = ["Bhopli Narangi"]
    )

    userId: int | str | None = Field(
        description = "the id of the user as found in the database",
        frozen = True,
        default = None
    )

    entityId: int | str | None = Field(
        description = "the id of the entity with which this user is associated",
        frozen = True,
        default = None
    )

    billingAccountId: int | str | None = Field(
        description = "the id of the billing account with which this user is associated",
        frozen = True,
        default = None
    )

    departmentId: int | str | None = Field(
        description = "the id of the dept. in which this user is working",
        frozen = True,
        default = None
    )

    branchId: int | str | None = Field(
        description = "the id of the branch in which this user is working",
        frozen = True,
        default = None
    )

    industry: str | None = Field(
        description = "the name of the industry this user is working in",
        frozen = True,
        default = None
    )

    # ┏┓    ┏•
    # ┃ ┏┓┏┓╋┓┏┓
    # ┗┛┗┛┛┗┛┗┗┫
    #          ┛

    class Config:
        extra = "ignore"
        arbitrary_types_allowed = True

    # ┏┓           ┏┓
    # ┃ ┓┏┏╋┏┓┏┳┓  ┣ ┓┏┏┓┏┏
    # ┗┛┗┻┛┗┗┛┛┗┗  ┻ ┗┻┛┗┗┛

    def matches(
            self,
            other_user: 'CoreUserInfoModel',
            ignore_null: bool = False
    ) -> bool:

        """
        To check if another instance of this user model matches this instance of the user model.
        :param other_user: The other user to check. That user's value must match this user's values to return a positive
            result. Whether, or not, null values are matched will be determined by the next param.
        :param ignore_null: If set to True, null values IN THE OTHER USER will not be compared during the matching.
        :return: True if they match, else False.
        """

        # Start by assuming success:
        are_matching = True

        # Iterate through the required items:
        for k, v in other_user.model_dump().items():

            # Do not consider fields that are nulls if asked to ignore them:
            if ignore_null and v is None: continue

            # Extract the corresponding value from the other user,
            # and test it for being equal:
            _v = getattr(self, k, None)
            if (
                    (not isinstance(v, type(_v))) or
                    (v != _v)
            ):
                are_matching = False
                break

        # Done here:
        return are_matching


#   *****************************************************************************************************************
#  *****                                                                                                          ****
# ***                                               MAIN PROGRAM                                                    ***
#  *****                                                                                                          ****
#   *****************************************************************************************************************


if __name__ == "__main__":

    from utils_v2.string import json

    user_bhopli = CoreUserInfoModel(
        fullName = "Bhopli Narangi",
        userId = 1,
        entityId = 2,
        billingAccountId = 3,
        departmentId = 4,
        branchId = 5,
        industry = "technology"
    )

    user_bhopli_partial = CoreUserInfoModel(
        fullName = "Bhopli Narangi",
        userId = 1,
        entityId = None,
        billingAccountId = None,
        departmentId = 4,
        branchId = None,
        industry = "technology"
    )

    user_polki = CoreUserInfoModel(
        fullName = "Polki Muchhwaali",
        userId = 6,
        entityId = 7,
        billingAccountId = 8,
        departmentId = 9,
        branchId = 10,
        industry = "finance"
    )

    print(user_bhopli.matches(user_bhopli_partial, ignore_null = False))
    print(user_bhopli.matches(user_bhopli_partial, ignore_null = True))
    print(user_bhopli.matches(user_polki, ignore_null = False))
    print(user_bhopli.matches(user_polki, ignore_null = True))
