import logging
import urllib.parse

from pathlib import Path
from typing import Dict

from mongoengine import connect
from mongoengine import Document, StringField, DictField, ListField
#import folium

from kedro.framework.session import KedroSession
from kedro.extras.datasets.yaml import YAMLDataSet
from kedro.extras.datasets.json import JSONDataSet

from actesdataset import JSONDataSetCollection


logger = logging.getLogger(__name__)


#class FoliumMap(Document):
#    globalmap = StringField(required=True)


class Helpers(Document):
    house_trigram = DictField()
    prince_bigram = DictField()


# Database schemas
class House(Document):
    "_id is the name"
    _id = StringField(required=True, max_length=100)
    name = StringField(required=True, max_length=100)
    trigram = StringField(required=True, max_length=3)
    particle = StringField(required=True, max_length=150)


class Acte(Document):
    """_id is the filename"""
    _id = StringField(required=True, max_length=150)
    house = StringField(required=True, max_length=100)
    prince_name = StringField(required=True, max_length=150)
    prince_code = StringField(required=True, max_length=100)
    analysis = StringField(required=True, max_length=3000)
    date = StringField(required=True, max_length=250)
    transcribers = ListField(required=True)
    # FIXME date_teim type shal it be a **real** date object ?
    date_time = StringField(required=True, max_length=15)
    filename = StringField(required=True, max_length=100)
    ref_acte = StringField(required=True, max_length=100)
    xmlcontent = StringField(required=True) # no max_length
    place = DictField()
    folium = StringField(required=False) # no max_length
    diplo_state = StringField(required=False) # sample: "diplo_state": "Original",
    diplo_type = StringField(required=False) # sample: "diplo_type": "Lettres_patentes",


def db_connect(storage_ip, db_name, mongodb_admin, mongodb_password):
    #mongodb://%s:%s@149.202.41.75:27017' % (username, password)
    username = urllib.parse.quote_plus(mongodb_admin)
    password = urllib.parse.quote_plus(mongodb_password)
    mongodb_url = f"mongodb://{username}:{password}@{storage_ip}:27017/"
    #mongodb_url = "mongodb://{}:27017/".format(storage_ip)
    #logger.info("connection to the mongodb server")
    # pymongo settings
    # myclient = pymongo.MongoClient(mongodb_url)
    myclient = connect(db=db_name, host=mongodb_url, authentication_source='admin', alias="default")


# pipeline functions
def populate_mongo(jsondoc: JSONDataSetCollection, storage_ip: str, db_name: str, db_collection_name: str, mongodb_admin: str, mongodb_password: str) -> None:
    "loads the json for an acte"
    jsondatasets = jsondoc.datasets
    housename = jsondoc._housename

    db_connect(storage_ip, db_name, mongodb_admin, mongodb_password)

    #places = []

    for dataset_filenamestem, dataset in jsondatasets.items():
        # a manual load is required here, because
        # the dataset **is not** registered in kedro's catalog
        json_document = dataset._load()
        json_document["_id"] = json_document["filename"]
        acte_entry = Acte(**json_document)
        logger.info("... adding entry: " + json_document["filename"])
        acte_entry.save()

        ## place location in the folium global map
        #if json_document['place'].get('latitude') is not None:
        #    places.append(json_document['place'])

    # folium global map
    # add to mongo db
    #m = folium.Map(location=[46.603354, 1.888334], zoom_start=6)
    #folium.TileLayer(name="Géolocalisation des actes",control=False).add_to(m)
    #for place in places:
    #    folium.Marker(
    #        location=[float(place['latitude']), float(place['longitude'])],
    #        popup=place['name']
    #        #icon=folium.Icon(icon="cloud")
    #        #icon=folium.Icon(color='lightgray', icon='home', prefix='fa')
    #    ).add_to(m)
    #globalmap = m.get_root()._repr_html_()
    ##globalmap = m._repr_html_()
    #folium_map = FoliumMap(globalmap=globalmap)
    #folium_map.save()

    return


def load_houses(yamldoc: YAMLDataSet, storage_ip: str, db_name: str, mongodb_admin: str, mongodb_password: str) -> None:

    db_connect(storage_ip, db_name, mongodb_admin, mongodb_password)

    for house_dict in yamldoc['houses'].values():
        house_dict['_id'] = house_dict['name']
        #houses_col.insert_one(house_dict)
        house_entry = House(**house_dict)
        house_entry.save()

    return

def load_helpers(house_trigram: JSONDataSet, prince_bigram: JSONDataSet,
    storage_ip: str, db_name: str, mongodb_admin: str, mongodb_password: str) -> None:

    db_connect(storage_ip, db_name, mongodb_admin, mongodb_password)

    helper_entry = Helpers(house_trigram=house_trigram, prince_bigram=prince_bigram)
    helper_entry.save()

