import cv2
import io
import json
import numpy as np
import os
import requests
import time
from PIL import Image, ImageDraw
from picsellia import exceptions
import sys
import random
import logging


def display_project_state(project_name, project_type, project_infos=None, network_names=None):
    if project_infos is not None and network_names is not None:
        print(f"Current state of project : {project_name}\nThis is a {project_type} project")
        for i, col in enumerate(project_infos):
            print("-" * 15)
            print(f"{len(col)} training version(s) for Network named : {network_names[i]}")
            print("-" * 15)
            for training in col:
                print(f"\t For training id {training['training_id']}:")
                if training["is_datasplit"]:
                    print("\t\t Train Test Set repartition : DONE")
                else:
                    print("\t\t Train Test Set repartition : NOT DONE")
                if training["is_examples"]:
                    print("\t\t Visual results uploaded to Picsell.ia : DONE")
                else:
                    print("\t\t Visual results uploaded to Picsell.ia : NOT DONE")
                if training["is_metrics"]:
                    print("\t\t Training logs uploaded to Picsell.ia : DONE")
                else:
                    print("\t\t Training logs uploaded to Picsell.ia : NOT DONE")

                print("\t\t Model usable from Picsell.ia : DONE")

    elif project_infos is None and network_names is not None:
        print("-" * 80)
        print(f"Welcome to Picsell.ia Client, this project_token is linked to your project : {project_name}")
        print("-" * 80)
        print("You don't have any Network trained for this project yet.\n")
        print(f"{len(network_names)} Network(s) attached to your project:")
        for e in network_names:
            print(f"\t - {e}")
        print("\nTo initialise a training session, please run create_network(network_name)\n")

    elif project_infos is None and network_names is None:
        print(f"Welcome to Picsell.ia Client, this project_token is linked to your project : {project_name}\n")
        print("You don't have any Network attache to this project yet.\
              \nIf you want to continue without an attached model, please initialise it with init_model(YOUR NAME)")


def train_valid_split_obj_simple(dict_annotations, prop=0.8):
    """Perform Optimized train test split for Object Detection.
       Uses optimization to find the optimal split to have the desired repartition of instances by set.
    Args:
        prop (float) : Percentage of Instances used for training.
        dict_annotations (dict) : annotation from dl_annotations

    Raises:
        ResourceNotFoundError: If not annotations in the Picsell.ia Client yet."""

    if dict_annotations is None:
        raise exceptions.ResourceNotFoundError("No dict_annotations passed")

    list_im = np.linspace(0, len(dict_annotations['images']) - 1, len(dict_annotations['images'])).astype('int')
    random.shuffle(list_im)
    nb_im = int(prop * len(dict_annotations['images']))
    train_list = list_im[:nb_im]
    test_list = list_im[nb_im:]
    index_url = []
    for e in range(len(list_im)):
        if e in train_list:
            index_url.append(1)
        elif e in test_list:
            index_url.append(0)
    return index_url


def get_labels_repartition_obj_detection(dict_annotations, index_url):
    """Perform train test split scanning for Object Detection.
    Returns:
        cate (array[str]) : Array of the classes names
        cnt_train (array[int]) : Array of the number of object per class for the training set.
        cnt_eval (array[int]) : Array of the number of object per class for the evaluation set.

    Raises:
        ResourceNotFoundError: If not annotations in the Picsell.ia Client yet."""

    if dict_annotations is None:
        raise exceptions.ResourceNotFoundError("No dict_annotations passed")

    cate = [v["name"] for v in dict_annotations["categories"]]
    cnt_train = [0] * len(cate)
    cnt_eval = [0] * len(cate)

    for img, index in zip(dict_annotations['images'], index_url):
        internal_picture_id = img["internal_picture_id"]
        for ann in dict_annotations["annotations"]:
            if internal_picture_id == ann["internal_picture_id"]:
                for an in ann['annotations']:
                    idx = cate.index(an['label'])
                    if index == 1:
                        cnt_train[int(idx)] += 1
                    else:
                        cnt_eval[int(idx)] += 1
    return cnt_train, cnt_eval, cate

def is_checkpoint(path, project_type):
    index_path = ""
    data_path = ""
    config_path = ""

    try:
        if not os.path.isdir(path):
            return False
    except Exception:
        return False

    for f in os.listdir(path):
        if ".index" in f:
            index_path = f
        if ".data" in f:
            data_path = f
        if project_type != "classification":
            if "pipeline" in f:
                config_path = f

    if index_path == "" or data_path == "":
        return False

    elif config_path == "" and project_type != "classification":
        return False

    return True
