from typing import List, Dict, Any

from wiser.gcloud.firestore.connectors.firestore_connector import FirestoreConnector
from wiser.gcloud.firestore.types.collection import FirestoreCollection
from wiser.gcloud.firestore.types.document import FirestoreDocument
from wiser.gcloud.firestore.types.query import FirestoreQuery


class Firestore:
    @staticmethod
    def add(collection: FirestoreCollection, document: FirestoreDocument) -> None:
        """
        Adds a document to a collection
        :param collection: the firestore collection
        :param document: the firestore document
        :return: None
        """
        if not isinstance(collection, FirestoreCollection):
            raise ValueError(
                "Passed parameter 'collection' is not a 'FirestoreCollection'"
            )
        if not isinstance(document, FirestoreDocument):
            raise ValueError("Passed parameter 'document' is not a 'FirestoreDocument'")

        FirestoreConnector.add(
            collection_path=collection.collection_name,
            document_id=document.id,
            data=document.data,
        )

    @staticmethod
    def update(collection: FirestoreCollection, document: FirestoreDocument) -> None:
        """
        Updates a document of a collection
        :param collection: the firestore collection
        :param document: the firestore document
        :return: None
        """
        if not isinstance(collection, FirestoreCollection):
            raise ValueError(
                "Passed parameter 'collection' is not a 'FirestoreCollection'"
            )
        if not isinstance(document, FirestoreDocument):
            raise ValueError("Passed parameter 'document' is not a 'FirestoreDocument'")

        if document.id is None:
            raise ValueError("No document id provided")

        FirestoreConnector.update(
            collection_path=collection.collection_name,
            document_id=document.id,
            data=document.data,
        )

    @staticmethod
    def get(
        collection: FirestoreCollection, query: FirestoreQuery
    ) -> List[Dict[Any, Any]]:
        """
        Given a query returns all the documents that match it
        :param collection: the firestore collection
        :param query: the query definition
        :return:
        """
        if not isinstance(collection, FirestoreCollection):
            raise ValueError(
                "Passed parameter 'collection' is not a 'FirestoreCollection'"
            )
        if not isinstance(query, FirestoreQuery):
            raise ValueError("Passed parameter 'query' is not a 'FirestoreQuery'")

        return FirestoreConnector.get(
            collection_name=collection.collection_name,
            where_conditions=query.conditions,
        )

    @staticmethod
    def delete_collection(collection: FirestoreCollection) -> None:
        """
        Deletes a document of a collection
        :param collection: the firestore collection
        :return: None
        """
        if not isinstance(collection, FirestoreCollection):
            raise ValueError(
                "Passed parameter 'collection' is not a 'FirestoreCollection'"
            )

        FirestoreConnector.delete_collection(collection_name=collection.collection_name)
