from research import circular_research
from copy import deepcopy

def coord_to_inter(liste_coord,lat,long,main_street):
    dist=[]
    inter_street=[]
    inter_street_coord=[]
    for inter in liste_coord:
        #Calcul des distances entre les intersections et l'arbre
        d=(inter[0]-long)**2 + (inter[1]-lat)**2
        dist.append(d)
    while len(inter_street)<1 :
        #On regarde l'intersection la plus proche de l'arbre
        print('nouveau candidat')
        try:
            candidat=liste_coord[dist.index(min(dist))]
        except ValueError:
            inter_street.append(main_street)
            inter_street_coord.append([long, lat])
            inter_street.append(main_street)
            inter_street_coord.append([long, lat])
            print('aucune intersection trouvée')
            return inter_street+inter_street_coord
        #On regarde si cette intersection correspond bien au croisement avec une autre rue, on trouve le nom de cette autre rue
        nom_de_rue=circular_research(candidat[1], candidat[0], main_street)
        if nom_de_rue== None :
            #Si on ne trouve pas d'autre rue a cette intersection on écarte cette intersection
            indice=dist.index(min(dist))
            dist.pop(indice)
            liste_coord.pop(indice)
        else : 
            #Si on trouve, on a notre début de tronçon
            inter_street.append(nom_de_rue)
            inter_street_coord.append(candidat)
            indice=dist.index(min(dist))
            d_1 = min(dist)
            dist.pop(indice)
            liste_coord.pop(indice)
    print('Début du tronçon trouvé')
    print(inter_street[0])
    #Recherche de la fin du tronçon
    liste_coord_admissibles = []
    d_1_2 = []
    dist2 = []
    for i in range(len(liste_coord)):
        #On prend la liste des intersection situé du second coté de l'arbe
        #Pour cela on calcule les distances entre le premier point trouvé, l'arbre et les autres points
        #On conserve les points qui permettent de former un triangle avec un angle obtu au niveau de l'arbre
        d=(liste_coord[i][0]-inter_street_coord[0][0])**2 + (liste_coord[i][1]-inter_street_coord[0][1])**2
        if d > dist[i] + d_1:
            liste_coord_admissibles.append(liste_coord[i])
            d_1_2.append(d)
            dist2.append(dist[i])
    while len(inter_street)<2 :
        #On regarde l'intersection admissible la plus proche du début du tronçon
        print('nouveau candidat 2')
        try:
            candidat=liste_coord_admissibles[d_1_2.index(min(d_1_2))]
        except ValueError:
            inter_street.append(inter_street[0])
            inter_street_coord.append(inter_street_coord[0])
            print("Arbre au niveau de l'intersection")
            return inter_street+inter_street_coord
        nom_de_rue=circular_research(candidat[1], candidat[0], main_street)
        if nom_de_rue== None :
            #Si cette intersection ne donne rien, on la rejette
            indice=d_1_2.index(min(d_1_2))
            d_1_2.pop(indice)
            liste_coord_admissibles.pop(indice)
            dist2.pop(indice)
        elif nom_de_rue==inter_street[0]:
            #Si l'intersection est la même rue que le début de tronçon, on rejette
            indice=d_1_2.index(min(d_1_2))
            d_1_2.pop(indice)
            liste_coord_admissibles.pop(indice)
            dist2.pop(indice)
        else : 
            #Sinon on à trouvé la fin de tronçon
            inter_street.append(nom_de_rue)
            inter_street_coord.append(candidat)
            indice=d_1_2.index(min(d_1_2))
            d_2 = dist2[indice]
            liste_coord_admissibles.pop(indice)
    print('fin du tronçon trouvé')
    print(inter_street)
    #On souhaite ensuite s'asssurer que l'on à le couple début/fin de tronçon le plus rapproché possible pour
    #réduire la zone de recherche
    liste_coord_admissibles2 = []
    d_2_1 = []
    for i in range(len(liste_coord)):
        #On prend la liste des intersection situé du premier coté de l'arbe
        #Pour cela on calcule les distances entre le second point trouvé, l'arbre et les autres points
        #On conserve les points qui permettent de former un triangle avec un angle obtu au niveau de l'arbre
        d=(liste_coord[i][0]-inter_street_coord[1][0])**2 + (liste_coord[i][1]-inter_street_coord[1][1])**2

        if d > dist[i] + d_2:  
            liste_coord_admissibles2.append(liste_coord[i])
            d_1_2.append(d)
    inter_street2 = ['', '']
    c = 0
    while inter_street != inter_street2:
        print('MaJ ', c+1)
        #Calcul des intersections admissibles et des distances
        if c % 2 == 0:
            liste_coord_admissibles2 += [inter_street_coord[0]]
            d_2_1 = fct_d_2_1(liste_coord_admissibles2, inter_street_coord)
        else:
            liste_coord_admissibles += [inter_street_coord[1]]
            d_1_2 = fct_d_2_1(liste_coord_admissibles, inter_street_coord)
            print(d_1_2)

        inter_street2 = deepcopy(inter_street)
        #Recherche du nouveau tronçon optimal
        inter_street, inter_street_coord = opti_inter_street(c, main_street, liste_coord_admissibles, liste_coord_admissibles2, d_1_2, d_2_1, inter_street, inter_street_coord)
        c +=1
    return inter_street+inter_street_coord


def opti_inter_street(c, main_street, liste_coord_admissibles, liste_coord_admissibles2, d_1_2, d_2_1, inter_street_init, inter_street_coord_init):
    p = c % 2
    if p == 0:
        liste_coord = liste_coord_admissibles2
        dist = d_2_1
    else:
        liste_coord = liste_coord_admissibles
        dist = d_1_2
    inter_street = deepcopy(inter_street_init)
    inter_street_coord = deepcopy(inter_street_coord_init)
    found = False
    while not(found):
        candidat=liste_coord[dist.index(min(dist))]
        nom_de_rue=circular_research(candidat[1], candidat[0], main_street)
        if nom_de_rue== None :
            indice=dist.index(min(dist))
            dist.pop(indice)
            liste_coord.pop(indice)
        elif nom_de_rue==inter_street[p]:
            indice=dist.index(min(dist))
            dist.pop(indice)
            liste_coord.pop(indice)
            found = True
        else : 
            inter_street[p] = nom_de_rue
            inter_street_coord[p] = candidat
            indice=dist.index(min(dist))
            liste_coord.pop(indice)
            found = True
    return inter_street, inter_street_coord

def fct_d_1_2(liste_coord, inter_street_coord):
    d_1_2 = []
    for i in range(len(liste_coord)):
        #On prend la liste des intersection situé du premier coté de l'arbe
        d=(liste_coord[i][0]-inter_street_coord[0][0])**2 + (liste_coord[i][1]-inter_street_coord[0][1])**2
        d_1_2.append(d)
    return d_1_2

def fct_d_2_1(liste_coord, inter_street_coord):
    d_2_1 = []
    for i in range(len(liste_coord)):
        #On prend la liste des intersection situé du premier coté de l'arbe
        d=(liste_coord[i][0]-inter_street_coord[1][0])**2 + (liste_coord[i][1]-inter_street_coord[1][1])**2
        d_2_1.append(d)
    return d_2_1

def fct_dist(liste_coord, lat, long):
    dist=[]
    for inter in liste_coord:
        d=(inter[0]-long)**2 + (inter[1]-lat)**2
        dist.append(d)
    return dist