from rephorm.dict.legend_positions import legend_positions
from rephorm.utility.report.resolve_color import resolve_color

def update_layout(title, settings, figure, img_w = None, img_h= None, y_range = None):

    font_size = settings.styles["chart"]["legend"]["font_size"]

    legend_pos = settings.legend_position.upper()

    # Normalize "rephorm" margin values to None so they fall through to defaults.
    margins = {
        k: (None if isinstance(v, str) and v.lower() == "rephorm" else v)
        for k, v in settings.styles["chart"]["margin"].items()
    }

    # Bottom margin auto-calculation:
    # Only when legend is at the bottom (SO, SEO, SWO) and user has not explicitly set a bottom margin for the legend.
    if legend_pos in ("SO", "SEO", "SWO") and margins["b"] is None:
        total = sum((len(t.name or "")+10)* font_size * 0.6 for t in figure.data)
        # img_w is essentially usable width for the chart. (In px)
        rows = -(-total // img_w)

        margins["b"] = (rows + 1) * (font_size + 8) + 20
        if img_h:
            # never exceed 30% of image height
            margins["b"] = min(margins["b"], img_h * 0.3)

    # Default to standard values if style margins are undefined (None).
    b_margin = margins["b"] or 0
    t_margin = margins["t"] or 5
    r_margin = margins["r"] or 0
    l_margin = margins["l"] or 0


    # Dict comprehension to include only margins that are not set to "plotly" in settings,
    # allowing Plotly to handle those automatically.
    final_margins = {
        k: v for k, v in {
            "b": b_margin,
            "t": t_margin,
            "r": r_margin,
            "l": l_margin
        }.items()
        if str(settings.styles["chart"]["margin"][k]).lower() != "plotly"
    }

    # Todo: extract this, but basically this is how to get title style in plotly for chart or for label too (I guess same way for label)
    font_style = settings.styles["chart"]["title"]["font_style"]
    if font_style == "B":
        formatted_title = f"<b>{title}</b>"
    elif font_style == "I":
        formatted_title = f"<i>{title}</i>"
    elif font_style == "BI":
        formatted_title = f"<b><i>{title}</i></b>"
    else:
        formatted_title = title

    layout = {
                "showlegend": settings.show_legend if hasattr(settings, "show_legend") else True,
                "title": {
                    "text": formatted_title,
                    "yref": "container",  # stop overlaps with plot area
                    "yanchor": "top", # align to top
                    "x": 0.5,
                    "automargin": True,  # adjust margins
                    "pad": {"b": 5},  # Fine control
                    "font_size": settings.styles["chart"]["title"]["font_size"],
                    "font_family": settings.styles["chart"]["title"]["font_family"],
                    "font_color": resolve_color(settings.styles["chart"]["title"]["font_color"]),
                },
                "plot_bgcolor": resolve_color(settings.styles["chart"]["bg_color"]),
                # paper_bgcolor is kinda useless for us now,
                # because of PDF image choice it will not support transparent bg
                # https://github.com/plotly/Kaleido/issues/91
                "paper_bgcolor": 'hsla(0, 100%, 50%, 0)',
                "margin": final_margins,
                "xaxis": {
                    # TODO: Later on introduce this parameter, to set number of ticks manually.
                    # "nticks": settings.styles["chart"]["x_axis"]["ticks"]["nticks"],
                    "showgrid": settings.show_grid if settings.show_grid else True,
                    "gridcolor": resolve_color(settings.styles["chart"]["grid_color"]),
                    "mirror": settings.axis_border,
                    "linecolor": resolve_color(settings.styles["chart"]["chart_border_color"]),
                    "showline": True,
                    "ticks": "inside",
                    "tickcolor": "black",
                    "linewidth": 1,
                    "tickwidth": 1,
                    "griddash": "dot",
                    "gridwidth": 1,
                    "tickfont": {"size": settings.styles["chart"]["x_axis"]["ticks"]["font_size"],
                                 "family": settings.styles["chart"]["x_axis"]["ticks"]["font_family"],
                                 "color": settings.styles["chart"]["y_axis"]["ticks"]["font_color"]},
                    "title": {
                        "text": settings.xaxis_title,
                        "font": {
                            "size": settings.styles["chart"]["x_axis"]["label"]["font_size"],
                            "family": settings.styles["chart"]["x_axis"]["label"]["font_family"]}},
                },
                "yaxis": {
                    "zeroline": settings.zeroline if hasattr(settings, 'zeroline') else True,
                    "showgrid": settings.show_grid if hasattr(settings, 'show_grid') else True,
                    "gridcolor": resolve_color(settings.styles["chart"]["grid_color"]),
                    "mirror": settings.axis_border,
                    "linecolor": resolve_color(settings.styles["chart"]["chart_border_color"]),
                    "showline": True,
                    "ticks": "inside",
                    "tickcolor": "black",
                    "linewidth": 1,
                    "tickwidth": 1,
                    "griddash": "dot",
                    "gridwidth": 1,
                    "range": y_range,
                    "tickfont": {"size": settings.styles["chart"]["y_axis"]["ticks"]["font_size"],
                                 "family": settings.styles["chart"]["y_axis"]["ticks"]["font_family"],
                                 "color": settings.styles["chart"]["y_axis"]["ticks"]["font_color"]},
                    "title": {
                        "text": settings.yaxis_title,
                        "font": {
                            "size": settings.styles["chart"]["y_axis"]["label"]["font_size"],
                            "family": settings.styles["chart"]["y_axis"]["label"]["font_family"]}},
                },
                "yaxis2": {
                    "overlaying": "y",
                    "side": "right",
                    "linecolor": resolve_color(settings.styles["chart"]["chart_border_color"]),
                    "showline": True,
                    "ticks": "inside",
                    "tickcolor": "black",
                    "linewidth": 1,
                    "tickwidth": 1,
                    "range": y_range,
                    "tickfont": {"size": settings.styles["chart"]["y_axis2"]["ticks"]["font_size"],
                                 "family": settings.styles["chart"]["y_axis2"]["ticks"]["font_family"],
                                 "color": settings.styles["chart"]["y_axis2"]["ticks"]["font_color"]},
                    "title": {
                        "text": settings.yaxis2_title,
                        "font": {
                            "size": settings.styles["chart"]["y_axis2"]["label"]["font_size"],
                            "family": settings.styles["chart"]["y_axis2"]["label"]["font_family"]}},
                },
                "legend": {
                    "font": {
                        "size": settings.styles["chart"]["legend"]["font_size"],
                        "family": settings.styles["chart"]["legend"]["font_family"],
                        "color": resolve_color(settings.styles["chart"]["legend"]["font_color"])
                    },
                    "orientation": settings.legend_orientation.lower(),
                    "x": legend_positions.get(settings.legend_position.upper()).get("x"),
                    "y": legend_positions.get(settings.legend_position.upper()).get("y"),
                    "xanchor": legend_positions.get(settings.legend_position.upper()).get("xanchor"),
                    "yanchor": legend_positions.get(settings.legend_position.upper()).get("yanchor"),
                    "borderwidth": settings.styles["chart"]["legend"]["border_width"],
                    "yref": legend_positions.get(settings.legend_position.upper()).get("yref"),
                    "xref": legend_positions.get(settings.legend_position.upper()).get("xref"),
                    "bgcolor": resolve_color(settings.styles["chart"]["legend"]["bg_color"]),

                }
            }

    # Update conditionally only if the user explicitly specifies 'ncols'.
    legend_ncol = settings.legend_ncol
    if bool(legend_ncol):
        figure.layout.legend["entrywidth"] = 1 / legend_ncol
        figure.layout.legend["entrywidthmode"] = "fraction"

    figure.update_layout(layout)