import inkex
import inkex.transforms
import inkex.colors
import io
import colorsys

def get_fill(elem):
    if elem.get("fill"):
        return elem.get("fill")
    if elem.style.get("fill"):
        return elem.style["fill"]
    return "#000000"


def get_bottom_edge_colour(elem):
    fill = inkex.colors.Color(get_fill(elem))
    h, s, l = fill.to("hsl").hue / 255 * 360, fill.to("hsl").saturation / 255 * 100, fill.to("hsl").lightness / 255 * 100
    inkex.errormsg((h, s, l))
    if s < 10:
        if l > 80:
            return "#212121", 0.1
        return "#212121", 0.2
    if 203 < h <= 315:
        return "#1A237E", 0.2
    if 65 < h <= 203:
        return "#263238", 0.2
    if 25 < h <= 65:
        return "#BF360C", 0.2
    return "#3E2723", 0.2


def get_top_edge_colour(elem):
    fill = inkex.colors.Color(get_fill(elem))
    h, s, l = fill.to("hsl").hue / 255 * 360, fill.to("hsl").saturation / 255 * 100, fill.to("hsl").lightness / 255 * 100
    if s < 10 and l > 80:
        return "#ffffff", 0.4
    return "#ffffff", 0.2


class MaterialShading(inkex.EffectExtension):
    def effect(self):
        selected = list(self.svg.selection)

        dy = self.svg.unittouu("1px")

        if not selected:
            inkex.errormsg("Select one or more paths or path-convertible objects first!")
            return

        ids_to_difference = []
        for elem in selected:
            shifted_up = elem.copy()
            parent = elem.getparent()
            index = parent.index(elem)

            shifted_up = elem.copy()
            shifted_up.transform = elem.transform @ inkex.transforms.Transform(f"translate(0, {-dy})")
            parent.insert(index + 1, shifted_up)
            shifted_down = elem.copy()
            shifted_down.transform = elem.transform @ inkex.transforms.Transform(f"translate(0, {dy})")
            parent.insert(index + 1, shifted_down)
            copy_1 = elem.copy()
            copy_1.style["fill"], copy_1.style["fill-opacity"] = get_bottom_edge_colour(elem)
            parent.insert(index + 1, copy_1)
            copy_2 = elem.copy()
            copy_2.style["fill"], copy_2.style["fill-opacity"] = get_top_edge_colour(elem)
            parent.insert(index + 1, copy_2)
            ids_to_difference.append(",".join((copy_1.get_id(), shifted_up.get_id())))
            ids_to_difference.append(",".join((copy_2.get_id(), shifted_down.get_id())))

        svg_bytes = inkex.command.inkscape_command(
            self.document,
            actions="".join(f"select-by-id:{ids}; path-difference; select-clear; " for ids in ids_to_difference).removesuffix("; ")
        )

        self.document = inkex.load_svg(svg_bytes)


if __name__ == "__main__":
    MaterialShading().run()
