<!-- $lib/ElementsUI/ButtonProps.svelte -->
<script lang="ts">
  import { T } from "../locales/i18n"
  import { type UIComponent, type IButtonProps, type IOption, updateProperty, type IUIComponentHandler } from "../types"
  import * as UI from ".."
  import { optionsStore } from "../options"
  import { twMerge } from "tailwind-merge"
  import { ICONS } from "../icons"
  import CommonSnippets from "../CommonSnippets.svelte"
  import InfoIcon from "../libIcons/InfoIcon.svelte"

  const {
    component,
    onPropertyChange,
    forConstructor = true,
  } = $props<{
    component: UIComponent & { properties: Partial<IButtonProps> }
    onPropertyChange: (updates: Partial<{ properties?: string | object; name?: string; access?: string; eventHandler?: IUIComponentHandler }>) => void
    forConstructor?: boolean
  }>()

  /* Argument пуст — поле ниже лишь визуально показывает "ModCfg", реальное значение нужно проставить в состояние */
  $effect(() => {
    if (!component.eventHandler.Argument) onPropertyChange({ eventHandler: { Argument: "ModCfg" } })
  })

  let hasValue: boolean = $derived(component.eventHandler.Value)

  let Header: IOption = $derived(
    $optionsStore.HEADER_OPTIONS.find((h) => h.value === component.eventHandler.Header) ?? { id: "", name: "", value: "", class: "!w-1/4" },
  )

  const initialColor = $derived(
    $optionsStore.COLOR_OPTIONS.find((c) =>
      (c.value as string).includes(component.properties.componentClass?.split(" ").find((cls: string) => cls.startsWith("bg-"))),
    ),
  )

  const initialHeight = $derived(
    $optionsStore.HEIGHT_OPTIONS.find((h) =>
      (h.value as string).includes(component.properties.componentClass?.split(" ").find((cls: string) => cls.startsWith("py-"))),
    ),
  )
  const updateIconProperty = (propertyName: string, value: string) => {
    updateProperty(propertyName, value, component, onPropertyChange)
    if (component.properties.content.icon && !component.properties.content.name?.trim())
      updateProperty("componentClass", twMerge((component.properties as UI.IButtonProps).componentClass, "w-fit p-2"), component, onPropertyChange)
    else if (
      (component.properties.content.icon && component.properties.content.name?.trim()) ||
      (!component.properties.content.icon && !component.properties.content.name?.trim())
    )
      updateProperty("componentClass", twMerge((component.properties as UI.IButtonProps).componentClass, "w-full px-1 py-1"), component, onPropertyChange)
  }

  const updateButtonColor = (option: UI.IOption<string>) => {
    if (initialColor?.value === option.value)
      updateProperty("componentClass", twMerge(component.properties.componentClass, "bg-transparent"), component, onPropertyChange)
    else
      updateProperty(
        "componentClass",
        twMerge((component.properties as UI.IButtonProps).componentClass, (option as UI.IOption<string>).value),
        component,
        onPropertyChange,
      )
  }
</script>

{#snippet ButtonHeaderArgument()}
  <UI.Select
    label={{ name: $T("constructor.props.header") }}
    type="buttons"
    value={Header}
    options={$optionsStore.HEADER_OPTIONS}
    onUpdate={(option) => onPropertyChange({ eventHandler: { Header: (option as IOption<string>).value as string } })}
  />
  <UI.Input
    label={{ name: $T("constructor.props.argument") }}
    value={component.eventHandler.Argument || "ModCfg"}
    maxlength={32}
    help={{ info: $T("constructor.props.argument.info"), autocomplete: "on", regExp: /^[a-zA-Z0-9\-_]{0,32}$/ }}
    onUpdate={(value) => onPropertyChange({ eventHandler: { Argument: value as string } })}
  />
{/snippet}

{#snippet ButtonVariables()}
  {#if component.eventHandler.Argument !== "ModCfg" || Header.value === "SET"}
    <UI.Input
      label={{ name: $T("constructor.props.value") }}
      value={component.eventHandler.Value}
      help={{ info: $T("constructor.props.value.info") }}
      maxlength={500}
      onUpdate={(value) => onPropertyChange({ eventHandler: { Value: value as string } })}
    />
  {/if}
  <UI.Input
    label={{ name: $T("constructor.props.variables") }}
    disabled={hasValue}
    value={component.eventHandler.Variables.join(" ")}
    help={{ info: $T("constructor.props.variables.info"), autocomplete: "on", regExp: /^[a-zA-Z0-9.\-_ ":{}]{0,500}$/ }}
    maxlength={500}
    onUpdate={(value) => onPropertyChange({ eventHandler: { Variables: (value as string).trim().split(/\s+/) } })}
  />
{/snippet}

{#snippet ButtonName()}
  <UI.Input
    label={{ name: $T("constructor.props.name") }}
    value={component.properties.content.name}
    onUpdate={(value) => updateIconProperty("content.name", value as string)}
  />
{/snippet}

{#snippet ButtonHeight()}
  {#if !(!component.properties.content.name?.trim() && component.properties.content.icon)}
    <UI.Select
      label={{ name: $T("constructor.props.height") }}
      type="buttons"
      options={$optionsStore.HEIGHT_OPTIONS}
      value={initialHeight}
      onUpdate={(option) =>
        updateProperty("componentClass", twMerge(component.properties.componentClass, (option as IOption<string>).value), component, onPropertyChange)}
    />
  {/if}
{/snippet}

{#snippet ButtonInfo()}
  <UI.Input
    label={{ name: $T("constructor.props.info") }}
    value={component.properties.content.info.text}
    onUpdate={(value) => updateProperty("content.info.text", value as string, component, onPropertyChange)}
  />
{/snippet}

{#snippet ButtonInfoSide()}
  <UI.Select
    label={{ name: $T("constructor.props.info.side") }}
    type="buttons"
    options={$optionsStore.INFO_SIDE_OPTIONS}
    value={$optionsStore.INFO_SIDE_OPTIONS.find((h) => h.value === component.properties.content.info.side)}
    onUpdate={(option) => updateProperty("content.info.side", (option as IOption<string>).value as string, component, onPropertyChange)}
  />
{/snippet}

{#snippet ButtonComponentClass()}
  <UI.Input
    label={{ name: $T("constructor.props.componentclass") }}
    value={component.properties.componentClass}
    onUpdate={(value) => updateProperty("componentClass", value as string, component, onPropertyChange)}
  />
{/snippet}

{#snippet ButtonColors()}
  <div class="flex items-end gap-2">
    <UI.Button wrapperClass="w-8" content={{ icon: InfoIcon, info: { text: $T("constructor.props.button.colors.hint"), side: "right" } }} />
    <CommonSnippets
      snippet="Colors"
      initialValue={{
        color: initialColor,
        updateProperty: (option: UI.IOption<string>) => updateButtonColor(option),
      }}
      {component}
      {onPropertyChange}
    />
  </div>
{/snippet}

{#if forConstructor}
  <div class="relative flex flex-row items-start justify-center">
    <!-- Сообщение для отправки в ws по нажатию кнопки -->
    <div class="flex w-1/3 flex-col px-2">
      <CommonSnippets snippet="Access" {component} {onPropertyChange} />
      {@render ButtonHeaderArgument()}
    </div>
    <div class="flex w-1/3 flex-col px-2">
      {@render ButtonVariables()}
      {@render ButtonColors()}
    </div>
    <div class="flex w-1/3 flex-col px-2">
      {@render ButtonName()}
      <CommonSnippets
        snippet="IconsLib"
        initialValue={{
          name: $T("constructor.props.buttonIcon"),
          icon: component.properties.content.icon,
          updateProperty: (icon: string) => updateIconProperty("content.icon", icon as string),
          icons: { array: ICONS },
        }}
        {component}
        {onPropertyChange}
      />
      {@render ButtonHeight()}
    </div>
  </div>
{:else}
  <div class="relative flex flex-row items-start justify-center">
    <div class="flex w-1/3 flex-col px-2">
      <CommonSnippets snippet="Identificator" {component} {onPropertyChange} />
      <CommonSnippets snippet="Access" {component} {onPropertyChange} />
      <CommonSnippets snippet="WrapperClass" {component} {onPropertyChange} />
      <CommonSnippets snippet="Disabled" {component} {onPropertyChange} />
    </div>
    <div class="flex w-1/3 flex-col px-2">
      {@render ButtonName()}
      {@render ButtonInfo()}
      {@render ButtonInfoSide()}
    </div>
    <div class="flex w-1/3 flex-col px-2">
      {@render ButtonComponentClass()}
      {@render ButtonColors()}
      <CommonSnippets
        snippet="IconsLib"
        initialValue={{
          name: $T("constructor.props.buttonIcon"),
          icon: component.properties.content.icon,
          updateProperty: (icon: string) => updateIconProperty("content.icon", icon as string),
          icons: { array: ICONS },
        }}
        {component}
        {onPropertyChange}
      />
    </div>
  </div>
{/if}
