<template>
  <view
    class="ui-tab"
    ref="tabRef"
    :id="'tab-' + vm.uid"
    :class="[
      props.ui,
      props.tpl,
      props.bg,
      props.align,
      { 'ui-tab-inline': props.inline },
      { 'ui-tab-scrolls': props.scroll },
    ]"
  >
    <block v-if="scroll">
      <view class="ui-tab-scroll-warp">
        <scroll-view
          scroll-x="true"
          class="ui-tab-scroll"
          :scroll-left="state.curValue > 1 ? state.tabNodeList[state.curValue - 1].left : 0"
          scroll-with-animation
          :style="{ width: `${state.content.width}px` }"
        >
          <view class="ss-flex ss-col-center">
            <su-tab-item
              v-for="(item, index) in props.tab"
              :data="item"
              :index="index"
              :key="index"
              @up="upitem"
              @tap.native="click(index, item)"
            ></su-tab-item>
            <view
              class="ui-tab-mark-warp"
              :class="[{ over: state.over }]"
              :style="[{ left: state.markLeft + 'px' }, { width: state.markWidth + 'px' }]"
            >
              <view
                class="ui-tab-mark"
                :class="[props.mark, { 'ui-btn': props.tpl == 'btn' || props.tpl == 'subtitle' }]"
                :style="[
                  {
                    background:
                      props.tpl == 'btn' || props.tpl == 'subtitle' ? titleStyle.activeBg : 'none',
                  },
                ]"
              ></view>
            </view>
          </view>
        </scroll-view>
      </view>
    </block>
    <block v-else>
      <su-tab-item
        v-for="(item, index) in props.tab"
        :data="item"
        :index="index"
        :key="index"
        @up="upitem"
        @tap.native="click(index, item)"
      ></su-tab-item>
      <view
        class="ui-tab-mark-warp"
        :class="[{ over: state.over }]"
        :style="[{ left: state.markLeft + 'px' }, { width: state.markWidth + 'px' }]"
      >
        <view
          class="ui-tab-mark"
          :class="[props.mark, { 'ui-btn': props.tpl == 'btn' || props.tpl == 'subtitle' }]"
        ></view>
      </view>
    </block>
  </view>
</template>

<script>
  export default {
    name: 'SuTab',
  };
</script>

<script setup>
  /**
   * 基础组件 - suTab
   */

  import {
    toRef,
    ref,
    reactive,
    unref,
    onMounted,
    nextTick,
    getCurrentInstance,
    provide,
  } from 'vue';
  const vm = getCurrentInstance();

  // 数据
  const state = reactive({
    curValue: 0,
    tabNodeList: [],
    scrollLeft: 0,
    markLeft: 0,
    markWidth: 0,
    content: {
      width: 100,
    },
    over: false,
  });

  const tabRef = ref(null);
  // 参数
  const props = defineProps({
    modelValue: {
      type: Number,
      default: 0,
    },
    ui: {
      type: String,
      default: '',
    },
    bg: {
      type: String,
      default: '',
    },
    tab: {
      type: Array,
      default() {
        return [];
      },
    },
    // line dot long,subtitle,trapezoid
    tpl: {
      type: String,
      default: 'line',
    },
    mark: {
      type: String,
      default: '',
    },
    align: {
      type: String,
      default: '',
    },
    curColor: {
      type: String,
      default: 'ui-TC',
    },
    defaultColor: {
      type: String,
      default: 'ui-TC',
    },
    scroll: {
      type: Boolean,
      default: false,
    },
    inline: {
      type: Boolean,
      default: false,
    },
    titleStyle: {
      type: Object,
      default: () => ({
        activeBg: '#DA2B10',
        activeColor: '#FEFEFE',
        color: '#D70000',
      }),
    },
    subtitleStyle: {
      type: Object,
      default: () => ({
        activeColor: '#333',
        color: '#C42222',
      }),
    },
  });

  const emits = defineEmits(['update:modelValue', 'change']);

  onMounted(() => {
    state.curValue = props.modelValue;
    setCurValue(props.modelValue);
    nextTick(() => {
      computedQuery();
    });
    uni.onWindowResize((res) => {
      computedQuery();
    });
  });

  const computedQuery = () => {
    uni
      .createSelectorQuery()
      .in(vm)
      .select('#tab-' + vm.uid)
      .boundingClientRect((data) => {
        if (data != null) {
          if (data.left == 0 && data.right == 0) {
            // setTimeout(() => {
            computedQuery();
            // }, 300);
          } else {
            state.content = data;
            setTimeout(() => {
              state.over = true;
            }, 300);
          }
        } else {
          console.log('tab-' + vm.uid + ' data error');
        }
      })
      .exec();
  };

  const setCurValue = (value) => {
    if (value == state.curValue) return;
    state.curValue = value;
    computedMark();
  };

  const click = (index, item) => {
    setCurValue(index);
    emits('update:modelValue', index);
    emits('change', {
      index: index,
      data: item,
    });
  };

  const upitem = (index, e) => {
    state.tabNodeList[index] = e;
    if (index == state.curValue) {
      computedMark();
    }
  };

  const computedMark = () => {
    if (state.tabNodeList.length == 0) return;
    let left = 0;
    let list = unref(state.tabNodeList);
    let cur = state.curValue;
    state.markLeft = list[cur].left - state.content.left;
    state.markWidth = list[cur].width;
  };

  const computedScroll = () => {
    if (state.curValue == 0 || state.curValue == state.tabNodeList.length - 1) {
      return false;
    }
    let i = 0;
    let left = 0;
    let list = state.tabNodeList;
    for (i in list) {
      if (i == state.curValue && i != 0) {
        left = left - list[i - 1].width;
        break;
      }
      left = left + list[i].width;
    }
    state.scrollLeft = left;
  };

  provide('suTabProvide', {
    props,
    curValue: toRef(state, 'curValue'),
  });
</script>

<style lang="scss">
  .ui-tab {
    position: relative;
    display: flex;
    height: 4em;
    align-items: center;

    &.ui-tab-scrolls {
      width: 100%;
      /* #ifdef MP-WEIXIN */
      padding-bottom: 10px;
      /* #endif */
      .ui-tab-scroll-warp {
        overflow: hidden;
        height: inherit;
        width: 100%;
        .ui-tab-scroll {
          position: relative;
          display: block;
          white-space: nowrap;
          overflow: auto;
          min-height: 4em;
          line-height: 4em;
          width: 100% !important;
          .ui-tab-mark-warp {
            display: flex;
            align-items: top;
            justify-content: center;
            .ui-tab-mark.ui-btn {
              /* #ifndef MP-WEIXIN */
              height: 2em;
              width: calc(100% - 0.6em);
              margin-top: 4px;
              /* #endif */
              /* #ifdef MP-WEIXIN */
              height: 2em;
              width: calc(100% - 0.6em);
              margin-top: 4px;
              /* #endif */
            }
          }
        }
      }
    }

    .ui-tab-mark-warp {
      color: inherit;
      position: absolute;
      top: 0;
      height: 100%;
      z-index: 0;

      &.over {
        transition: 0.3s;
      }

      .ui-tab-mark {
        color: var(--ui-BG-Main);
        height: 100%;
      }
    }

    &.line {
      .ui-tab-mark {
        border-bottom: 2px solid currentColor;
      }
    }

    &.topline {
      .ui-tab-mark {
        border-top: 2px solid currentColor;
      }
    }

    &.dot {
      .ui-tab-mark::after {
        content: '';
        width: 0.5em;
        height: 0.5em;
        background-color: currentColor;
        border-radius: 50%;
        display: block;
        position: absolute;
        bottom: 0.3em;
        left: 0;
        right: 0;
        margin: auto;
      }
    }

    &.long {
      .ui-tab-mark::after {
        content: '';
        width: 2em;
        height: 0.35em;
        background-color: currentColor;
        border-radius: 5em;
        display: block;
        position: absolute;
        bottom: 0.3em;
        left: 0;
        right: 0;
        margin: auto;
      }
    }

    &.trapezoid {
      .ui-tab-mark::after {
        content: '';
        width: calc(100% - 2em);
        height: 0.35em;
        background-color: currentColor;
        border-radius: 5em 5em 0 0;
        display: block;
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
      }
    }

    &.btn {
      .ui-tab-mark-warp {
        display: flex;
        align-items: center;
        justify-content: center;

        .ui-tab-mark.ui-btn {
          height: calc(100% - 1.6em);
          width: calc(100% - 0.6em);
        }
      }

      &.sm .ui-tab-mark.ui-btn {
        height: calc(100% - 2px);
        width: calc(100% - 2px);
        border-radius: #{$radius - 2};
      }
    }

    &.subtitle {
      .ui-tab-mark-warp {
        display: flex;
        align-items: top;
        justify-content: center;
        padding-top: 0.6em;

        .ui-tab-mark.ui-btn {
          height: calc(100% - 2.8em);
          width: calc(100% - 0.6em);
        }
      }
    }

    &.ui-tab-inline {
      display: inline-flex;
      height: 3.5em;

      &.ui-tab-scrolls {
        .ui-tab-scroll {
          height: calc(3.5em + 17px);
          line-height: 3.5em;

          .ui-tab-mark-warp {
            height: 3.5em;
          }
        }
      }

      &.btn {
        .ui-tab-mark-warp {
          .ui-tab-mark.ui-btn {
            height: calc(100% - 10px);
            width: calc(100% - 10px);
          }
        }
      }
    }

    &.sm {
      height: 70rpx !important;

      &.ui-tab-inline {
        height: 70rpx;

        &.ui-tab-scrolls {
          .ui-tab-scroll {
            height: calc(70rpx + 17px);
            line-height: 70rpx;

            .ui-tab-mark-warp {
              height: 70rpx;
            }
          }
        }

        &.btn .ui-tab-mark.ui-btn {
          height: calc(100% - 2px);
          width: calc(100% - 2px);
          border-radius: #{$radius - 2};
        }
      }
    }
  }
</style>
