<script>
import theme from "#build/b24ui/button";
</script>

<script setup>
import { computed, ref, inject } from "vue";
import { defu } from "defu";
import { useForwardProps } from "reka-ui";
import { useAppConfig } from "#imports";
import { useComponentIcons } from "../composables/useComponentIcons";
import { useFieldGroup } from "../composables/useFieldGroup";
import { formLoadingInjectionKey } from "../composables/useFormField";
import { omit, mergeClasses } from "../utils";
import { tv } from "../utils/tv";
import { pickLinkProps } from "../utils/link";
import B24Avatar from "./Avatar.vue";
import B24Link from "./Link.vue";
import B24LinkBase from "./LinkBase.vue";
import ChevronDownSIcon from "@bitrix24/b24icons-vue/outline/ChevronDownSIcon";
import LoaderWaitIcon from "@bitrix24/b24icons-vue/animated/LoaderWaitIcon";
import LoaderClockIcon from "@bitrix24/b24icons-vue/animated/LoaderClockIcon";
import SpinnerIcon from "@bitrix24/b24icons-vue/specialized/SpinnerIcon";
const props = defineProps({
  label: { type: String, required: false },
  color: { type: null, required: false },
  activeColor: { type: null, required: false },
  depth: { type: null, required: false },
  activeDepth: { type: null, required: false },
  size: { type: null, required: false },
  rounded: { type: Boolean, required: false },
  block: { type: Boolean, required: false },
  loadingAuto: { type: Boolean, required: false },
  normalCase: { type: Boolean, required: false, default: true },
  useWait: { type: Boolean, required: false },
  useClock: { type: Boolean, required: false },
  useDropdown: { type: Boolean, required: false },
  onClick: { type: [Function, Array], required: false },
  class: { type: null, required: false },
  activeClass: { type: String, required: false },
  inactiveClass: { type: String, required: false },
  b24ui: { type: null, required: false },
  icon: { type: [Function, Object], required: false },
  avatar: { type: Object, required: false },
  loading: { type: Boolean, required: false },
  as: { type: null, required: false },
  type: { type: null, required: false, default: "button" },
  disabled: { type: Boolean, required: false },
  active: { type: Boolean, required: false },
  exact: { type: Boolean, required: false },
  exactQuery: { type: [Boolean, String], required: false },
  exactHash: { type: Boolean, required: false },
  isAction: { type: Boolean, required: false },
  to: { type: null, required: false },
  href: { type: null, required: false },
  external: { type: Boolean, required: false },
  target: { type: [String, Object, null], required: false },
  rel: { type: [String, Object, null], required: false },
  noRel: { type: Boolean, required: false },
  prefetchedClass: { type: String, required: false },
  prefetch: { type: Boolean, required: false },
  prefetchOn: { type: [String, Object], required: false },
  noPrefetch: { type: Boolean, required: false },
  trailingSlash: { type: String, required: false },
  exactActiveClass: { type: String, required: false },
  ariaCurrentValue: { type: String, required: false },
  viewTransition: { type: Boolean, required: false },
  replace: { type: Boolean, required: false }
});
const slots = defineSlots();
const appConfig = useAppConfig();
const { orientation, size: buttonSize, noSplit } = useFieldGroup(props);
const linkProps = useForwardProps(pickLinkProps(props));
const proxyLinkProps = computed(() => {
  return omit(linkProps.value, ["type", "disabled", "onClick"]);
});
const loadingAutoState = ref(false);
const formLoading = inject(formLoadingInjectionKey, void 0);
async function onClickWrapper(event) {
  loadingAutoState.value = true;
  const callbacks = Array.isArray(props.onClick) ? props.onClick : [props.onClick];
  try {
    await Promise.all(callbacks.map((fn) => fn?.(event)));
  } finally {
    loadingAutoState.value = false;
  }
}
const isLoading = computed(() => {
  return props.loading || props.loadingAuto && (loadingAutoState.value || formLoading?.value && props.type === "submit");
});
const { isLeading, leadingIconName } = useComponentIcons(
  computed(() => ({ ...props, loading: false }))
);
const isLabel = computed(() => {
  let isUseSlot = false;
  if (slots && !!slots.default) {
    isUseSlot = true;
  }
  return (props?.label || "").length > 0 || isUseSlot;
});
const b24ui = computed(() => tv({
  extend: tv(theme),
  ...defu({
    variants: {
      active: {
        true: {
          base: mergeClasses(appConfig.b24ui?.button?.variants?.active?.true?.base, props.activeClass)
        },
        false: {
          base: mergeClasses(appConfig.b24ui?.button?.variants?.active?.false?.base, props.inactiveClass)
        }
      }
    }
  }, appConfig.b24ui?.button || {})
})({
  color: props.color,
  depth: props.depth,
  size: buttonSize.value,
  noSplit: Boolean(noSplit.value),
  loading: Boolean(isLoading.value),
  useLabel: Boolean(isLabel.value),
  block: Boolean(props.block),
  normalCase: Boolean(props.normalCase),
  rounded: Boolean(props.rounded),
  useDropdown: Boolean(props.useDropdown),
  useWait: Boolean(props.useWait),
  useClock: Boolean(props.useClock),
  leading: Boolean(isLeading.value),
  fieldGroup: orientation.value,
  isAir: true
}));
</script>

<template>
  <B24Link
    v-slot="{ active, ...slotProps }"
    :type="type"
    :disabled="disabled || isLoading"
    v-bind="proxyLinkProps"
    custom
  >
    <B24LinkBase
      v-bind="slotProps"
      data-slot="base"
      :class="b24ui.base({
  class: [props.b24ui?.base, props.class],
  active,
  ...active && activeDepth ? { depth: activeDepth } : {},
  ...active && activeColor ? { color: activeColor } : {}
})"
      @click="onClickWrapper"
    >
      <div
        v-if="isLoading"
        data-slot="baseLoading"
        :class="b24ui.baseLoading({ class: props.b24ui?.baseLoading, active })"
      >
        <LoaderWaitIcon v-if="useWait" data-slot="baseLoadingWaitIcon" :class="b24ui.baseLoadingWaitIcon({ class: props.b24ui?.baseLoadingWaitIcon })" aria-hidden="true" />
        <LoaderClockIcon v-else-if="useClock" data-slot="baseLoadingClockIcon" :class="b24ui.baseLoadingClockIcon({ class: props.b24ui?.baseLoadingClockIcon })" aria-hidden="true" />
        <SpinnerIcon v-else data-slot="baseLoadingSpinnerIcon" :class="b24ui.baseLoadingSpinnerIcon({ class: props.b24ui?.baseLoadingSpinnerIcon })" aria-hidden="true" />
      </div>
      <div
        data-slot="baseLine"
        :class="[b24ui.baseLine({ class: [props.b24ui?.baseLine] }), isLoading ? 'invisible' : '']"
      >
        <slot name="leading" :b24ui="b24ui">
          <Component
            :is="leadingIconName"
            v-if="isLeading && typeof leadingIconName !== 'undefined'"
            data-slot="leadingIcon"
            :class="b24ui.leadingIcon({ class: props.b24ui?.leadingIcon })"
          />
          <B24Avatar
            v-else-if="!!avatar"
            :size="props.b24ui?.leadingAvatarSize || b24ui.leadingAvatarSize()"
            v-bind="avatar"
            data-slot="leadingAvatar"
            :class="b24ui.leadingAvatar({ class: props.b24ui?.leadingAvatar })"
          />
        </slot>

        <slot :b24ui="b24ui">
          <span v-if="label !== void 0 && label !== null" data-slot="label" :class="b24ui.label({ class: props.b24ui?.label, active })">
            <span data-slot="labelInner" :class="b24ui.labelInner({ class: props.b24ui?.labelInner, active })">
              {{ label }}
            </span>
          </span>
        </slot>

        <slot name="trailing" :b24ui="b24ui">
          <ChevronDownSIcon
            v-if="useDropdown"
            data-slot="trailingIcon"
            :class="b24ui.trailingIcon({ class: props.b24ui?.trailingIcon })"
            aria-hidden="true"
          />
        </slot>
      </div>
    </B24LinkBase>
  </B24Link>
</template>
