<script lang='ts' setup>
interface TabsProps {
  modelValue?: string | number;
  type?: "bar" | "line" | "segment";
  size?: "small" | "medium" | "large";
  animated?: boolean;
  closable?: boolean;
  addable?: boolean;
  placement?: "top" | "bottom" | "left" | "right";
  sticky?: boolean;
  stickyTop?: string | number;
  tabStyle?: string | Record<string, any>;
  tabClass?: string;
  paneStyle?: string | Record<string, any>;
  paneClass?: string;
}

interface TabsEmits {
  (e: "update:modelValue", value: string | number): void;
  (e: "tabClick", key: string | number, event: Event): void;
  (e: "tabClose", key: string | number): void;
  (e: "tabAdd"): void;
}

const props = withDefaults(defineProps<TabsProps>(), {
  type: "bar",
  size: "medium",
  animated: true,
  closable: false,
  addable: false,
  placement: "top",
  sticky: false,
  stickyTop: 0,
});

const emit = defineEmits<TabsEmits>();

// 内部状态
const currentTab = ref<string | number>();
const tabsRef = ref<HTMLElement>();
const activeBarRef = ref<HTMLElement>();

// 子组件列表
const tabPanes = ref<Array<{
  name: string | number;
  title: string;
  disabled?: boolean;
  closable?: boolean;
  instance: any;
}>>([]);

// 使用provide/inject在父子组件间传递数据
const tabsContext = {
  currentTab: readonly(currentTab),
  type: toRef(props, "type"),
  size: toRef(props, "size"),
  closable: toRef(props, "closable"),
  animated: toRef(props, "animated"),
  placement: toRef(props, "placement"),
  tabStyle: toRef(props, "tabStyle"),
  tabClass: toRef(props, "tabClass"),
  paneStyle: toRef(props, "paneStyle"),
  paneClass: toRef(props, "paneClass"),
  activateTab,
  closeTab,
  registerTabPane,
  unregisterTabPane,
};

provide("tabs-context", tabsContext);

// 注册tab pane
function registerTabPane(pane: any) {
  const existingIndex = tabPanes.value.findIndex(p => p.name === pane.name);
  if (existingIndex === -1) {
    tabPanes.value.push(pane);
    // 如果当前没有激活的tab且这是第一个可用的tab，则激活它
    if (!currentTab.value && !pane.disabled) {
      currentTab.value = pane.name;
      emit("update:modelValue", pane.name);
      // 延迟更新active bar，确保DOM完全渲染
      setTimeout(() => {
        updateActiveBar();
      }, 10);
    }
  }
}

function unregisterTabPane(pane: any) {
  const index = tabPanes.value.findIndex(p => p.name === pane.name);
  if (index > -1) {
    tabPanes.value.splice(index, 1);
  }
}

// 激活tab
function activateTab(key: string | number, event?: Event) {
  const pane = tabPanes.value.find(p => p.name === key);
  if (!pane || pane.disabled)
    return;

  if (currentTab.value === key)
    return;

  currentTab.value = key;
  emit("update:modelValue", key);

  if (event) {
    emit("tabClick", key, event);
  }

  // 更新active bar位置
  nextTick(updateActiveBar);
}

// 关闭tab
function closeTab(key: string | number) {
  emit("tabClose", key);
}

// 添加tab
function addTab() {
  emit("tabAdd");
}

// 更新active bar位置（用于bar和line类型）
function updateActiveBar() {
  if (props.type !== "bar" && props.type !== "line")
    return;
  if (!tabsRef.value || !activeBarRef.value)
    return;

  const activeTabEl = tabsRef.value.querySelector(`[data-tab-key="${currentTab.value}"]`) as HTMLElement;
  if (!activeTabEl)
    return;

  // 获取tab label元素来计算更精确的宽度
  const labelEl = activeTabEl.querySelector(".ui-tab__label") as HTMLElement;

  if (labelEl) {
    // 创建一个临时元素来测量文本的实际宽度
    const tempEl = document.createElement("span");
    tempEl.style.visibility = "hidden";
    tempEl.style.position = "absolute";
    tempEl.style.fontSize = window.getComputedStyle(labelEl).fontSize;
    tempEl.style.fontFamily = window.getComputedStyle(labelEl).fontFamily;
    tempEl.style.fontWeight = window.getComputedStyle(labelEl).fontWeight;
    tempEl.textContent = labelEl.textContent;
    document.body.appendChild(tempEl);

    const textWidth = tempEl.offsetWidth;
    document.body.removeChild(tempEl);

    const tabsRect = tabsRef.value.getBoundingClientRect();
    const labelRect = labelEl.getBoundingClientRect();

    if (props.placement === "top" || props.placement === "bottom") {
      // 居中对齐文本宽度
      const leftOffset = labelRect.left - tabsRect.left + (labelRect.width - textWidth) / 2;
      activeBarRef.value.style.left = `${leftOffset}px`;
      activeBarRef.value.style.width = `${textWidth}px`;
    }
    else {
      activeBarRef.value.style.top = `${labelRect.top - tabsRect.top}px`;
      activeBarRef.value.style.height = `${textWidth}px`;
    }
  }
  else {
    // 降级到原来的逻辑
    const tabsRect = tabsRef.value.getBoundingClientRect();
    const activeRect = activeTabEl.getBoundingClientRect();

    if (props.placement === "top" || props.placement === "bottom") {
      activeBarRef.value.style.left = `${activeRect.left - tabsRect.left}px`;
      activeBarRef.value.style.width = `${activeRect.width}px`;
    }
    else {
      activeBarRef.value.style.top = `${activeRect.top - tabsRect.top}px`;
      activeBarRef.value.style.height = `${activeRect.height}px`;
    }
  }
}

// 监听modelValue变化
watch(() => props.modelValue, (newValue) => {
  if (newValue !== undefined && newValue !== currentTab.value) {
    currentTab.value = newValue;
    nextTick(updateActiveBar);
  }
}, { immediate: true });

// 监听tabPanes变化，自动设置第一个tab为活跃状态
watch(tabPanes, (newPanes) => {
  if ((!currentTab.value || currentTab.value === "") && newPanes.length > 0) {
    const firstAvailablePane = newPanes.find(pane => !pane.disabled);
    if (firstAvailablePane) {
      currentTab.value = firstAvailablePane.name;
      emit("update:modelValue", firstAvailablePane.name);
      nextTick(updateActiveBar);
    }
  }
}, { flush: "post" });

// 组件挂载后初始化
onMounted(() => {
  // 如果没有当前激活的tab但有可用的tabs，选择第一个
  if (!currentTab.value && tabPanes.value.length > 0) {
    const firstAvailablePane = tabPanes.value.find(pane => !pane.disabled);
    if (firstAvailablePane) {
      currentTab.value = firstAvailablePane.name;
      emit("update:modelValue", firstAvailablePane.name);
    }
  }

  // 延迟更新active bar，确保DOM完全渲染
  setTimeout(() => {
    updateActiveBar();
  });
});

// 暴露方法
defineExpose({
  registerTabPane,
  unregisterTabPane,
  updateActiveBar,
});

// 计算样式类
const tabsClasses = computed(() => [
  "ui-tabs",
  `ui-tabs--${props.type}`,
  `ui-tabs--${props.size}`,
  `ui-tabs--${props.placement}`,
  {
    "ui-tabs--animated": props.animated,
    "ui-tabs--sticky": props.sticky,
  },
]);

// 计算sticky样式
const stickyStyle = computed(() => {
  if (!props.sticky)
    return {};

  const topValue = typeof props.stickyTop === "number"
    ? `${props.stickyTop}px`
    : props.stickyTop;

  return {
    position: "sticky" as const,
    top: topValue,
    zIndex: 100,
  };
});
</script>

<template>
  <div :class="tabsClasses">
    <div
      class="ui-tabs__nav-wrapper"
      :class="[`ui-tabs__nav-wrapper--${placement}`]"
      :style="props.sticky ? stickyStyle : {}"
    >
      <div
        ref="tabsRef"
        class="ui-tabs__nav"
        :class="[`ui-tabs__nav--${type}`, `ui-tabs__nav--${size}`]"
      >
        <!-- 渲染标签列表 -->
        <div
          v-for="pane in tabPanes"
          :key="pane.name"
          class="ui-tab" :class="[
            `ui-tab--${type}`,
            `ui-tab--${size}`,
            {
              'ui-tab--active': currentTab === pane.name,
              'ui-tab--disabled': pane.disabled,
              'ui-tab--closable': pane.closable || closable,
            },
          ]"
          :data-tab-key="pane.name"
          :style="tabStyle"
          @click="activateTab(pane.name, $event)"
        >
          <span class="ui-tab__label">
            {{ pane.title }}
          </span>

          <!-- Close Button -->
          <button
            v-if="(pane.closable || closable) && type !== 'segment'"
            class="ui-tab__close"
            @click.stop="closeTab(pane.name)"
          >
            <ion-icon name="close-outline" />
          </button>
        </div>

        <!-- Active Bar (用于bar和line类型) -->
        <div
          v-if="type === 'bar' || type === 'line'"
          ref="activeBarRef"
          class="ui-tabs__active-bar"
          :class="`ui-tabs__active-bar--${type}`"
        />

        <!-- Add Button -->
        <button
          v-if="addable"
          class="ui-tabs__add-btn"
          @click="addTab"
        >
          <ion-icon name="add-outline" />
        </button>
      </div>
    </div>

    <!-- 标签内容区域 -->
    <div class="ui-tabs__content">
      <slot />
    </div>
  </div>
</template>

<style scoped>
@reference "tailwindcss";

.ui-tabs {
  @apply w-full;
  --ui-tabs-primary: var(--ion-color-primary);
  --ui-tabs-primary-rgb: var(--ion-color-primary-rgb);
  --ui-tabs-background: var(--ion-background-color);
  --ui-tabs-text: var(--ion-text-color);
  --ui-tabs-text-rgb: var(--ion-text-color-rgb);
}

/* 导航包装器 */
.ui-tabs__nav-wrapper {
  @apply relative;
}

/* Sticky 布局 */
.ui-tabs--sticky .ui-tabs__nav-wrapper {
  background-color: var(--ui-tabs-background);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

.ui-tabs--sticky.ui-tabs--animated .ui-tabs__nav-wrapper {
  transition: background-color 0.2s ease;
}

.ui-tabs__nav-wrapper--bottom {
  border-top: 1px solid var(--ion-border-color, #e5e7eb);
}

.ui-tabs__nav-wrapper--left {
  border-right: 1px solid var(--ion-border-color, #e5e7eb);
}

.ui-tabs__nav-wrapper--right {
  border-left: 1px solid var(--ion-border-color, #e5e7eb);
}

/* 导航容器 */
.ui-tabs__nav {
  @apply relative flex;
}

.ui-tabs__nav--bar,
.ui-tabs__nav--line {
  @apply gap-6;
}

.ui-tabs__nav--segment {
  @apply gap-1 p-1 rounded-lg;
  background-color: var(--ion-color-light, #f8f9fa);
}

/* 尺寸 */
.ui-tabs__nav--small {
  @apply text-sm;
}

.ui-tabs__nav--medium {
  @apply text-base;
}

.ui-tabs__nav--large {
  @apply text-lg;
}

/* Tab Labels */
.ui-tab {
  @apply relative flex items-center justify-between cursor-pointer transition-all duration-200;
  color: var(--ion-color-medium, #6b7280);
}

.ui-tab:hover:not(.ui-tab--disabled):not(.ui-tab--active) {
  color: var(--ion-color-primary) !important;
}

.ui-tab--active {
  @apply font-medium;
  color: var(--ion-color-primary) !important;
}

.ui-tab--disabled {
  @apply cursor-not-allowed opacity-50;
  color: var(--ion-color-light-shade, #d1d5db) !important;
}

/* Bar 类型 */
.ui-tab--bar {
  @apply py-3 border-b-2 border-transparent;
}

.ui-tab--bar.ui-tab--active {
  border-color: var(--ion-color-primary) !important;
}

/* Line 类型 */
.ui-tab--line {
  @apply py-3;
}

/* Segment 类型 */
.ui-tab--segment {
  @apply px-3 py-2 rounded-md;
}

.ui-tab--segment.ui-tab--active {
  background-color: var(--ui-tabs-background);
  box-shadow:
    0 1px 3px 0 rgba(0, 0, 0, 0.1),
    0 1px 2px 0 rgba(0, 0, 0, 0.06);
}

/* 尺寸变化 */
.ui-tab--small {
  @apply text-sm;
}

.ui-tab--small.ui-tab--bar,
.ui-tab--small.ui-tab--line {
  @apply py-2;
}

.ui-tab--small.ui-tab--segment {
  @apply px-2 py-1;
}

.ui-tab--large {
  @apply text-lg;
}

.ui-tab--large.ui-tab--bar,
.ui-tab--large.ui-tab--line {
  @apply py-4;
}

.ui-tab--large.ui-tab--segment {
  @apply px-4 py-3;
}

/* Tab Label */
.ui-tab__label {
  @apply flex-1;
}

/* Close Button */
.ui-tab__close {
  @apply ml-2 p-1 rounded-full opacity-60 hover:opacity-100 transition-all duration-200;
  background-color: transparent;
}

.ui-tab__close:hover {
  background-color: rgba(var(--ui-tabs-primary-rgb), 0.1);
}

.ui-tab__close ion-icon {
  @apply text-sm;
}

/* Active Bar */
.ui-tabs__active-bar {
  @apply absolute transition-all duration-300 ease-out;
}

.ui-tabs__active-bar--bar {
  @apply bottom-0;
  height: 2px;
  background-color: var(--ui-tabs-primary);
}

.ui-tabs__active-bar--line {
  @apply bottom-0 h-px;
  background-color: var(--ui-tabs-primary);
}

/* Add Button */
.ui-tabs__add-btn {
  @apply flex items-center justify-center px-3 py-2 transition-colors duration-200;
  color: var(--ion-color-medium, #6b7280);
}

.ui-tabs__add-btn:hover {
  color: var(--ui-tabs-primary);
}

.ui-tabs__add-btn ion-icon {
  @apply text-lg;
}

/* 内容区域 */
.ui-tabs__content {
  @apply relative;
}

/* 动画支持 */
.ui-tabs--animated .ui-tabs__content {
  @apply overflow-hidden;
}

/* 垂直布局 */
.ui-tabs--left,
.ui-tabs--right {
  @apply flex;
}

.ui-tabs--left .ui-tabs__nav-wrapper {
  @apply min-w-48;
}

.ui-tabs--right .ui-tabs__nav-wrapper {
  @apply min-w-48 order-2;
}

.ui-tabs--left .ui-tabs__nav,
.ui-tabs--right .ui-tabs__nav {
  @apply flex-col;
}

.ui-tabs--left .ui-tabs__content,
.ui-tabs--right .ui-tabs__content {
  @apply flex-1;
}

/* 垂直布局tab调整 */
.ui-tabs--left .ui-tab,
.ui-tabs--right .ui-tab {
  @apply justify-start w-full;
}

.ui-tabs--left .ui-tab--bar,
.ui-tabs--right .ui-tab--bar {
  @apply border-b-0 border-r-2;
}

.ui-tabs--left .ui-tab--bar.ui-tab--active,
.ui-tabs--right .ui-tab--bar.ui-tab--active {
  border-color: var(--ui-tabs-primary);
}

/* 垂直布局active bar */
.ui-tabs--left .ui-tabs__active-bar--bar,
.ui-tabs--right .ui-tabs__active-bar--bar {
  @apply right-0 w-0.5 h-0.5;
}

.ui-tabs--left .ui-tabs__active-bar--line,
.ui-tabs--right .ui-tabs__active-bar--line {
  @apply right-0 w-px h-0.5;
}

/* 响应式设计 */
@media (max-width: 640px) {
  .ui-tabs__nav--small .ui-tab--bar,
  .ui-tabs__nav--small .ui-tab--line {
    @apply py-2;
  }

  .ui-tabs__nav--medium .ui-tab--bar,
  .ui-tabs__nav--medium .ui-tab--line {
    @apply py-2;
  }

  .ui-tab__close {
    @apply ml-1;
  }
}

/* Dark mode 支持 */
.ion-palette-dark {
  .ui-tabs {
    --ui-tabs-primary: var(--ion-color-primary, #ffffff);
    --ui-tabs-primary-rgb: var(--ion-color-primary-rgb, 255, 255, 255);
    --ui-tabs-background: var(--ion-background-color, #1a1a1a);
    --ui-tabs-text: var(--ion-text-color, #ffffff);
  }

  .ui-tabs__nav--segment {
    background-color: var(--ion-color-dark, #2d2d2d);
  }

  .ui-tab--segment.ui-tab--active {
    background-color: var(--ion-color-dark-tint, #404040);
  }
}

/* 触摸设备优化 */
@media (hover: none) and (pointer: coarse) {
  .ui-tab--bar,
  .ui-tab--line,
  .ui-tab--segment {
    @apply py-3;
  }

  .ui-tab__close {
    @apply p-2;
  }
}
</style>
