from pydantic import BaseModel, Schema
from typing import Dict, List
from datetime import datetime
from fastapi import HTTPException
import logging
from time import time

rels = dict(issupplementto="IsSupplementTo", issupplementedby="IsSupplementedBy", references="References",
            isreferencedby="IsReferencedBy")

class LinkProvider(BaseModel):
    name:str = Schema(None, title= "The name of the Provider that provides the links", max_length= 300)
    totalRelationships:int=Schema(None, title= "The number of links that It provides")

class LinkPublisher(BaseModel):
    name:str = Schema(None, title= "The name of the Publisher that provides the links", max_length= 300)
    totalRelationships:int=Schema(None, title= "The number of links that It provides")


class IdentifierType(BaseModel):
    ID: str = None
    IDScheme:str = None
    IDURL:str= None

class ScholixProviderType(BaseModel):
    name:str = None
    identifier:List[IdentifierType] = []

class RelationshipType(BaseModel):
    Name:str
    SubType:str = None
    SubTypeSchema:str = None

class CreatorType(BaseModel):
    Name: str
    Identifier:List[IdentifierType] = []
    


class ScholixItemType(BaseModel):
    Identifier:IdentifierType = None
    Title:str = None
    Type:str 
    Creator:List[CreatorType] = []
    PublicationDate:str = None
    Publisher:List[ScholixProviderType] =[]    

class ScholixType(BaseModel):
    HarvestDate:str=None
    LicenseURL:str=None
    LinkProvider:List[ScholixProviderType] =[]
    LinkPublicationDate: str = None
    RelationshipType:RelationshipType
    source:ScholixItemType
    target:ScholixItemType
    

class PageResultType(BaseModel):
    currentPage:int
    totalLinks:int
    totalPages:int
    result:List[ScholixType] = []


def get_scholix_resource(item, pid=None):
    title = ''
    if 'title' in item:
        title = item.title
    if title is not None and len(title):
        if title[0] == '"' and title[-1] == '"':
            title = title[1:-1]
    identifier = [dict(ID=x.identifier, IDScheme=x.schema, IDURL=x.url) for x in
                  item.identifier]

    if pid!= None:
        items = [x for x in identifier if pid == x["ID"]]
        if len(items) >0:
            identifier = items[0]
        else:
            identifier = identifier[0]
    else:
        identifier = identifier[0]
    creator = []
    if 'creator' in item and item.creator is not None:        
        creator = [dict(Name=x.name) for x in item.creator]
    publicationDate = None
    if 'publicationDate' in item:
        publicationDate = item.publicationDate
    publisher = []
    if 'publisher' in item and item.publisher is not None:
        publisher = [dict(name= x.name) for x in item.publisher if x.name is not None]
    c_type = item.objectType
    if item.objectType == 'publication':
        c_type = 'literature'

    resource = dict(Title=title, Identifier=identifier, Creator=creator, PublicationDate= publicationDate, Publisher = publisher, Type= c_type)

    return resource


def convert_response(response, sourcePid=None, targetPid=None):
    now = datetime.now()
    log = logging.getLogger("scholexplorer")
    start = time()
    for item in response.hits:
        current_item = {'LinkPublicationDate': item.publicationDate, 'HarvestDate': item.publicationDate,
                         "LinkProvider": []}
        for linkProvider in item.linkprovider:
            current_item['LinkProvider'].append(ScholixProviderType(name=linkProvider.name,
                                                     identifier=[IdentifierType(ID=x.identifier, IDScheme=x.schema) for x in
                                                                 linkProvider.identifiers]))

        rel_sub_type = rels.get(item.relationship.name.lower(), "IsRelatedTo")
        current_item['RelationshipType'] = dict(Name=rel_sub_type, SubType=item.relationship.name,
                                                SubTypeSchema=item.relationship.schema)

        current_item['source'] = get_scholix_resource(item.source, sourcePid)
        current_item['target'] = get_scholix_resource(item.target, targetPid)

        yield current_item
    end = time()
    log.debug("response converted in {} ms".format(end-start))

def create_response(response, current_page, sourcePid=None,targetPid=None):
    log = logging.getLogger("scholexplorer")    
    if current_page > 9999:
        raise HTTPException(status_code=400,detail="MAX NUMBER OF PAGE REACHED")

    start = time()

    
    result = {'totalLinks': response.hits.total.value, 'currentPage': current_page /100,
              'totalPages': 1 + response.hits.total.value / 100, 'result': []}
    result['result'] = convert_response(response, sourcePid, targetPid)
    end = time()

    log.debug("response created in {} ms".format(end-start))
    return result