#! /usr/bin/env python
# -*- coding: utf-8 -*-

from loguru import logger
from pathlib import Path
import skimage.io
import pandas as pd
import json
from matplotlib.path import Path as mplPath
import numpy as np


def mask_from_via_annotation(df, filename_via=None, shape=None, fn_full=None, dtype=np.uint8):
    """
    Generate mask from VGG Image Annotator (VIA).

    :param df: pandas dataframe generated by VIA by CSV export.
    :param fn_full: full file name of input image it can be used to generate filename_via and shape
    :param filename_via: filename used in dataframe to identify image
    :param shape: shape of output mask. It can be obtained by reading input image based on fn_full
    :param dtype: dtype of output mask
    :return: np.ndimage with mask
    """

    if filename_via is None:
        filename_via = fn_full.name
    if shape is None:
        img = skimage.io.imread(fn_full, as_gray=True)
        shape = [img.shape[0], img.shape[1]]
    ln = np.sum(df[df["filename"] == filename_via].region_shape_attributes != "{}")

    mask = np.zeros(shape, dtype=dtype)
    for annotation_id in range(ln):
        #         print("-----------------")
        #         print(annotation_id, ln)
        dfrsa = df[df["filename"] == filename_via].region_shape_attributes.values
        #         print("len and dfrsa", len(dfrsa), " | ", dfrsa)
        region_shape_attributes = json.loads(
            df[df["filename"] == filename_via].region_shape_attributes.values[annotation_id]
        )

        #     plt.imshow(img, cmap="gray")
        polygon_x = region_shape_attributes["all_points_x"]
        polygon_y = region_shape_attributes["all_points_y"]
        logger.debug(f"{annotation_id}, {polygon_x[:3]}, {polygon_y[:3]}")

        polygon = list(zip(polygon_y, polygon_x))
        poly_path = mplPath(polygon)
        x, y = np.mgrid[
               : shape[0], :shape[1]
               ]
        coors = np.hstack(
            (x.reshape(-1, 1), y.reshape(-1, 1))
        )  # coors.shape is (4000000,2)

        mask_i = poly_path.contains_points(coors)
        mask_i = mask_i.reshape([shape[0], shape[1]]).astype(np.uint8)
        #     mask_i = mask.reshape(img.shape[:-1])
        mask += mask_i
    #         mask[mask_i] = 255
    #     plot(region_shape_attributes["all_points_x"],region_shape_attributes["all_points_y"])
    return mask