from fasthtml.components import *

from myfasthtml.core.bindings import Binding
from myfasthtml.core.commands import Command
from myfasthtml.core.utils import merge_classes


class Ids:
  # Please keep the alphabetical order
  Root = "mf-root"
  UserSession = "mf-user_session"


class mk:
  
  @staticmethod
  def button(element, command: Command = None, binding: Binding = None, **kwargs):
    return mk.mk(Button(element, **kwargs), command=command, binding=binding)
  
  @staticmethod
  def dialog_buttons(ok_title: str = "OK",
                     cancel_title: str = "Cancel",
                     on_ok: Command = None,
                     on_cancel: Command = None,
                     cls=None):
    return Div(
      Div(
        mk.button(ok_title, cls="btn btn-primary btn-sm mr-2", command=on_ok),
        mk.button(cancel_title, cls="btn btn-ghost btn-sm", command=on_cancel),
        cls="flex justify-end"
      ),
      cls=merge_classes("flex justify-end w-full mt-1", cls)
    )
  
  @staticmethod
  def icon(icon, size=20,
           can_select=True,
           can_hover=False,
           cls='',
           command: Command = None,
           binding: Binding = None,
           **kwargs):
    merged_cls = merge_classes(f"mf-icon-{size}",
                               'icon-btn' if can_select else '',
                               'mmt-btn' if can_hover else '',
                               cls,
                               kwargs)
    
    return mk.mk(Div(icon, cls=merged_cls, **kwargs), command=command, binding=binding)
  
  @staticmethod
  def label(text: str,
            icon=None,
            size: str = "sm",
            cls='',
            command: Command = None,
            binding: Binding = None,
            **kwargs):
    merged_cls = merge_classes("flex", cls, kwargs)
    icon_part = Span(icon, cls=f"mf-icon-{mk.convert_size(size)} mr-1") if icon else None
    text_part = Span(text, cls=f"text-{size}")
    return mk.mk(Label(icon_part, text_part, cls=merged_cls, **kwargs), command=command, binding=binding)
  
  @staticmethod
  def convert_size(size: str):
    return (size.replace("xs", "16").
            replace("sm", "20").
            replace("md", "24").
            replace("lg", "28").
            replace("xl", "32"))
  
  @staticmethod
  def manage_command(ft, command: Command):
    if command:
      ft = command.bind_ft(ft)
    
    return ft
  
  @staticmethod
  def manage_binding(ft, binding: Binding, ft_attr=None, init_binding=True):
    if not binding:
      return ft
    
    binding.bind_ft(ft, ft_attr)
    if init_binding:
      binding.init()
      # as it is the first binding, remove the hx-swap-oob
      if "hx-swap-oob" in ft.attrs:
        del ft.attrs["hx-swap-oob"]
    
    return ft
  
  @staticmethod
  def mk(ft, command: Command = None, binding: Binding = None, init_binding=True):
    ft = mk.manage_command(ft, command) if command else ft
    ft = mk.manage_binding(ft, binding, init_binding=init_binding) if binding else ft
    return ft
