<template>
  <div class="billboard">
    <div class="ip"></div>
    <div class="guide" @click="goPage({ title: '地图导览', path: '/guide' })"></div>
    <div class="header">
      <div class="r1">当前位置 <img src="./loc.png" alt="" /></div>
      <div class="r2">{{ bf }}</div>
      <div class="r3"></div>
    </div>
    <div class="list-container" ref="listRef">
      <div
        class="list"
        :style="{
          height: `calc(${columnHeight / 1080} * 100vw)`,
          width: `calc(484px * ${Math.ceil(columns.length / 2) * 2} + 68px)`
        }"
      >
        <div v-for="(col, i) of columns" :key="'col' + i" class="column" :style="{ height: `calc(${columnHeight / 1080} * 100vw)` }">
          <template v-for="(data, j) of col.list">
            <div v-if="data.type === 'format'" class="format" :key="data.name">
              {{ data.name }}
              <span class="meta">/{{ data.length }}个</span>
            </div>

            <div v-else-if="data.type === 'shop'" class="shop" :key="data.code">
              <div class="left">
                <img class="dir" :src="data.dir" />
                <div class="text">
                  {{ data.shopName }}
                </div>
              </div>
              <div class="right"></div>
            </div>

            <div v-else class="placeholder" :key="'placeholder' + i + '_' + j"></div>
          </template>
        </div>
      </div>
    </div>

    <div v-if="showBullets" class="bullets">
      <div v-for="(_, i) of scrollLefts" :key="i" class="bullet" :class="{ active: index === i }">
        <div class="burning" :style="{ transition: `all ${timeout}ms linear` }"></div>
      </div>
      <div class="meta">{{ remainingMinutes }}秒后切页</div>
    </div>
  </div>
</template>

<script setup>
import { computed, ref, watch } from 'vue'
import { storeToRefs } from 'pinia'
import { useStore } from '@/store/root'
import { useRouter } from 'vue-router'
import { getBrandListByFormat } from '@/http/brand/api'

const timeout = 30000
const heights = { shop: 44, format: 49, placeholder: 40 }
const setValue = refInstance => value => Object.assign(refInstance, { value })
const store = useStore()
const router = useRouter()
const shopListByFormat = ref([])
const listRef = ref(null)
const { currentFloor, buildingList } = storeToRefs(store)
const bf = computed(() => (buildingList.length > 1 ? currentFloor.value.building + '-' : '') + currentFloor.value.floor)

const scrollWidth = ref(0)
const setScrollWidth = setValue(scrollWidth)
const scrollLefts = ref([])
const setScrollLefts = setValue(scrollLefts)
const index = ref(null)
const setIndex = setValue(index)
const columns = ref([])
const setColumns = setValue(columns)
const remainingMinutes = ref(Math.ceil(timeout / 1000))
const setRemainingMinutes = setValue(remainingMinutes)

const showBullets = computed(() => scrollLefts.value.length > 1)
const columnHeight = 746

const shops = computed(() =>
  shopListByFormat.value.map(brand => ({
    ...brand,
    shopList: brand.shopList.filter(shop => shop.floor === currentFloor.value.floor)
  }))
)
getBrandListByFormat().then(({ data }) => {
  shopListByFormat.value = data.list
})

try {
  window.Map_QM?.showFloor?.(currentFloor.value.floorOrder)
  window.Map_QM.onShowMeDir()
} catch (error) {
  console.log('error:', error)
}

const goPage = item => {
  store.SET_SELECTED_MODULE(item.title)
  router.push(item.path)
}
watch(shops, (formats, _, onCleanup) => {
  if (formats.length) {
    const list = formats
      .reduce(
        (acc, nxt) =>
          !nxt.shopList.length
            ? [...acc]
            : [
                ...acc,
                {
                  type: 'format',
                  length: nxt.shopList.length,
                  name: nxt.name
                },
                ...nxt.shopList.map(shop => ({
                  ...shop,
                  type: 'shop'
                })),
                { type: 'placeholder' }
              ],
        []
      )
      .reduce((acc, nxt) => {
        const lastColumn = acc[acc.length - 1]
        const nxtHeight = heights[nxt.type]

        if (!lastColumn || lastColumn.height + nxtHeight > columnHeight) {
          if (nxt.type === 'placeholder') return [...acc, { height: 0, list: [], spStartHeight: null }]
          return [
            ...acc,
            {
              height: heights[nxt.type],
              list: [nxt],
              spStartHeight: nxt.isSp ? 0 : null,
              hasBanner: nxt.isSp && nxt.type === 'format'
            }
          ]
        } else {
          if (nxt.type === 'placeholder' && nxt.isSp) {
            lastColumn.spEndHeight = lastColumn.height
          }
          lastColumn.list.push(nxt)
          lastColumn.height += nxtHeight

          return acc
        }
      }, [])
    setColumns(list)

    if (shops.value.length) {
      const tm = setTimeout(() => {
        setScrollWidth(listRef.value.scrollWidth)
      }, 1000)
      onCleanup(() => clearTimeout(tm))
    }
  }
})

watch(index, (nxt, _, onCleanup) => {
  if (nxt === null) return
  listRef.value.scrollLeft = scrollLefts.value[nxt]
  const tm = setTimeout(() => {
    setIndex((nxt + 1) % scrollLefts.value.length)
  }, timeout)
  setRemainingMinutes(Math.ceil(timeout / 1000))
  const interval = setInterval(() => {
    if (remainingMinutes.value > 0) setRemainingMinutes(remainingMinutes.value - 1)
  }, 1000)
  onCleanup(() => {
    clearTimeout(tm)
    clearInterval(interval)
  })
})

watch(scrollWidth, _scrollWidth => {
  if (_scrollWidth > 0) {
    const list = Array.from(document.querySelectorAll('.shop'))
      .map(el => el.getBoundingClientRect().left - (72 / 1080) * window.innerWidth)
      .reduce((acc, nxt) => {
        const last = acc[acc.length - 1]
        return nxt === last ? acc : [...acc, nxt]
      }, [])
      .reduce((acc, nxt, i) => (i % 2 === 0 ? acc.concat(nxt) : acc), [])
    setScrollLefts(list)
  }
})
watch(scrollLefts, _scrollLefts => {
  if (_scrollLefts.length > 1) {
    setIndex(0)
  }
})
</script>
<style lang="scss">
@keyframes counter {
  0% {
    counter-decrement: count 30;
  }

  100% {
    counter-decrement: count 0;
  }
}
</style>
<style lang="scss" scoped>
.billboard {
  position: absolute;
  top: 800px;
  left: 0;
  right: 0;
  bottom: 0;
  background: #dee6f6;
  z-index: 100;
  .ip {
    position: absolute;
    width: 180px;
    height: 257.5px;
    right: 56px;
    top: -57.5px;
    background: center / cover no-repeat url(./ip.png);
    z-index: 1;
  }
  .guide {
    position: absolute;
    height: 200px;
    width: 500px;
    right: 0;
    top: 0;
    z-index: 1;
  }
  .header {
    position: relative;
    height: 200px;
    padding-top: 48px;
    padding-left: 68px;
    background: top / contain no-repeat url(./bg.png);
    z-index: 0;
    .r1 {
      display: flex;
      height: 23px;
      font-weight: 700;
      font-size: 20px;
      line-height: 23px;
      color: rgba(0, 0, 0, 0.6);
      img {
        width: 20px;
        height: 20px;
        margin-left: 4px;
      }
    }
    .r2 {
      margin-top: 9px;
      margin-bottom: 9px;
      font-weight: 900;
      font-size: 48px;
      line-height: 56px;
      color: #000000;
    }
    .r3 {
      width: 184px;
      height: 32px;
      background: center / cover no-repeat url(./meta.png);
    }
  }
  .list-container {
    overflow-x: scroll;
    overflow-y: hidden;
    scroll-behavior: smooth;
    margin-left: 68px;
    padding-top: 56px;
    width: 1012px;
    &::-webkit-scrollbar {
      display: none;
    }
  }
  .list {
    display: flex;
    text-align: left;
    .column {
      position: relative;
      display: inline-block;
      width: 484px;
      .format {
        z-index: 1;
        width: 339.995px;
        height: 54px;
        font-weight: 900;
        font-size: 28px;
        line-height: 33px;
        color: rgba(0, 0, 0, 0.8);
        .meta {
          font-weight: 500;
          font-size: 20px;
          line-height: 23px;
          color: rgba(0, 0, 0, 0.6);
        }
      }
      .shop {
        z-index: 1;
        position: relative;
        display: flex;
        font-weight: 700;
        font-size: 16px;
        line-height: 19px;
        color: rgba(0, 0, 0, 0.8);
        width: 460px;
        height: 40px;
        align-items: center;
        justify-content: space-between;
        break-inside: avoid-column;
        background: rgba(255, 255, 255, 0.8);
        border-radius: 4px;
        padding-left: 16px;
        .left {
          display: flex;
          flex: 1;
          padding-right: 15px;
          align-items: center;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: hidden;
          .text {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
          }
        }
        .right {
          display: inline-flex;
          flex: 0 0 50px;
          font-weight: 500;
          font-size: 16px;
          line-height: 19px;
          text-align: right;
          color: rgba(0, 0, 0, 0.6);
        }
        .dir {
          width: 24px;
          height: 24px;
          margin-right: 12px;
        }
      }
      .shop + .shop {
        margin-top: 4px;
      }
      .placeholder {
        z-index: 1;
        width: 100%;
        height: 40px;
      }
    }
  }

  .bullets {
    position: absolute;
    display: flex;
    width: 123px;
    left: 0;
    right: 0;
    margin: auto;
    bottom: 47px;
    justify-content: center;
    .meta {
      position: absolute;
      left: 0;
      right: 0;
      margin: auto;
      top: 14px;
      font-weight: 500;
      font-size: 16px;
      line-height: 19px;
      text-align: center;
      color: rgba(0, 0, 0, 0.6);
      .num {
        content: counter(count);

        counter-reset: count 30;
      }
    }
    .bullet {
      display: flex;
      width: 0;
      height: 6px;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 6px;
      transition: all 0.5s ease-in-out;
      overflow: hidden;
      .burning {
        flex: 0 0 0;
        height: 6px;
        background: #fff;
      }
      &.active {
        width: 123px;
        .burning {
          flex: 0 0 123px;
        }
      }
    }
  }
}
</style>
