import os
import cv2
import numpy as np
import pandas as pd
from scipy import stats
from plotnine import ggplot, aes, geom_line, scale_x_continuous, scale_color_manual, labs
from plantcv.plantcv import fatal_error
from plantcv.plantcv import deprecation_warning
from plantcv.plantcv import params
from plantcv.plantcv._debug import _debug
from plantcv.plantcv import outputs
from plantcv.plantcv.visualize import histogram


def analyze_color(rgb_img, mask, hist_plot_type=None, colorspaces="all", label="default"):
    """Analyze the color properties of an image object
    Inputs:
    rgb_img          = RGB image data
    mask             = Binary mask made from selected contours
    hist_plot_type   = None, 'all', 'rgb','lab' or 'hsv' (to be deprecated)
    colorspaces      = 'all', 'rgb', 'lab', or 'hsv'
    label            = optional label parameter, modifies the variable name of observations recorded

    Returns:
    analysis_image   = histogram output

    :param rgb_img: numpy.ndarray
    :param mask: numpy.ndarray
    :param colorspaces: str
    :param hist_plot_type: str
    :param label: str
    :return analysis_images: list
    """
    # Save user debug setting
    debug = params.debug
    if hist_plot_type is not None:
        deprecation_warning("'hist_plot_type' will be deprecated in a future version of PlantCV. "
                            "Please use 'colorspaces' instead.")
        colorspaces = hist_plot_type

    if len(np.shape(rgb_img)) < 3:
        fatal_error("rgb_img must be an RGB image")

    # Mask the input image
    masked = cv2.bitwise_and(rgb_img, rgb_img, mask=mask)
    # Extract the blue, green, and red channels
    b, g, r = cv2.split(masked)
    # Convert the BGR image to LAB
    lab = cv2.cvtColor(masked, cv2.COLOR_BGR2LAB)
    # Extract the lightness, green-magenta, and blue-yellow channels
    l, m, y = cv2.split(lab)
    # Convert the BGR image to HSV
    hsv = cv2.cvtColor(masked, cv2.COLOR_BGR2HSV)
    # Extract the hue, saturation, and value channels
    h, s, v = cv2.split(hsv)

    # Color channel dictionary
    channels = {"b": b, "g": g, "r": r, "l": l, "m": m, "y": y, "h": h, "s": s, "v": v}

    # Histogram plot types
    hist_types = {"all": ("b", "g", "r", "l", "m", "y", "h", "s", "v"),
                  "rgb": ("b", "g", "r"),
                  "lab": ("l", "m", "y"),
                  "hsv": ("h", "s", "v")}

    if colorspaces.lower() not in hist_types:
        fatal_error(f"Colorspace '{colorspaces}' is not supported, must be be one of the following: " 
                    f"{', '.join(map(str, hist_types.keys()))}")

    # Calculate histogram
    params.debug = None
    histograms = {
        "b": {"label": "blue", "graph_color": "blue",
              "hist": histogram(channels["b"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "g": {"label": "green", "graph_color": "forestgreen",
              "hist": histogram(channels["g"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "r": {"label": "red", "graph_color": "red",
              "hist": histogram(channels["r"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "l": {"label": "lightness", "graph_color": "dimgray",
              "hist": histogram(channels["l"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "m": {"label": "green-magenta", "graph_color": "magenta",
              "hist": histogram(channels["m"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "y": {"label": "blue-yellow", "graph_color": "yellow",
              "hist": histogram(channels["y"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "h": {"label": "hue", "graph_color": "blueviolet",
              "hist": histogram(channels["h"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "s": {"label": "saturation", "graph_color": "cyan",
              "hist": histogram(channels["s"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()},
        "v": {"label": "value", "graph_color": "orange",
              "hist": histogram(channels["v"], mask, 256, 0, 255,
                                hist_data=True)[1]['proportion of pixels (%)'].tolist()}
    }

    # Restore user debug setting
    params.debug = debug

    # Create list of bin labels for 8-bit data
    binval = np.arange(0, 256)

    # Create a dataframe of bin labels and histogram data
    dataset = pd.DataFrame({'bins': binval, 'blue': histograms["b"]["hist"],
                            'green': histograms["g"]["hist"], 'red': histograms["r"]["hist"],
                            'lightness': histograms["l"]["hist"], 'green-magenta': histograms["m"]["hist"],
                            'blue-yellow': histograms["y"]["hist"], 'hue': histograms["h"]["hist"],