<template>
  <div class="billboard" :style="{ backgroundImage: theme.images.billboardBackgroundImg ? `url(${theme.images.billboardBackgroundImg})` : '' }">
    <div class="list-container" ref="listRef">
      <div
        class="list"
        :style="{
          height: `${columnHeight}px`,
          width: `${(isH ? 286 : 484) * Math.ceil(columns.length / 2) * 2 + (isH ? 38 : 68)}px`
        }"
      >
        <div v-for="(col, i) of columns" :key="'col' + i" class="column" :style="{ height: `${columnHeight}px`, opacity: Math.floor(i / 2) === index ? 1 : 0.5 }">
          <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">{{ data.distance ? data.distance + '米' : '' }}</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>
  <div class="ip"></div>
  <div class="guide" @click="goPage({ title: '地图导览', path: '/guide' })"></div>
  <div class="header" :style="{ backgroundImage: `url(${isH ? theme.images.billboardHeaderBgH : theme.images.billboardHeaderBgV})` }">
    <div class="r1">当前位置 <img :src="theme.images.billboardLoc" alt="" /></div>
    <div class="r2">{{ bf }}</div>
    <div class="r3"></div>
    <QRCodeFromText
      v-if="currentFloor"
      class="qrcode"
      :size="100"
      :text="`${config.mobileNav}?code=${currentFloor.projectCode}&s=${currentFloor.floorOrder}_${currentFloor.location}_屏幕的位置`"
    ></QRCodeFromText>
  </div>
</template>

<script setup>
import { computed, ref, watch, nextTick } from 'vue'
import { storeToRefs } from 'pinia'
import { useStore } from '@/store/root'
import { useRouter } from 'vue-router'
import { getBrandListByFormat } from '@/http/brand/api'
import QRCodeFromText from '@/components/QRCodeFromText/QRCodeFromText.vue'
import { useMediaQuery, useWindowSize } from '@vueuse/core'
import { setShopInactive } from '@/composables/useInitMap'

const isH = useMediaQuery('(min-aspect-ratio: 1/1)')
const { width } = useWindowSize()
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 shops = ref([])
const listRef = ref(null)
const { currentFloor, buildingList, currentFloorShopMap, config, theme } = 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 = computed(() => (isH.value ? 706 : 746))

Promise.all([getBrandListByFormat()]).then(([{ data: brandListByFormat }]) => {
  shops.value = brandListByFormat.list.map(brand => {
    return {
      ...brand,
      shopList: brand.shopList
        .filter(shop => shop.floor === currentFloor.value.floor)
        .map(shop => {
          const meta = currentFloorShopMap.value[shop.shopId]
          return { ...shop, ...(meta ? meta : {}) }
        })
    }
  })
})

try {
  window.Map_QM?.showFloor?.(currentFloor.value.floorOrder)
  setShopInactive()
  setTimeout(() => {
    window.Map_QM?.changeMapState('2d')
  }, 500)
} 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.value) {
          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(width, () => {
  if (shops.value.length) {
    setScrollWidth(listRef.value.scrollWidth)
  }
})
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 - (isH.value ? 1326 : 68))
      .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(null)
    nextTick(() => {
      setIndex(0)
    })
  }
})
</script>
<style lang="scss" scoped>
.billboard {
  position: absolute;
  top: 800px;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--billboard-background);
  z-index: 10;

  .list-container {
    position: fixed;
    left: 68px;
    top: 1056px;
    overflow-x: scroll;
    overflow-y: hidden;
    scroll-behavior: smooth;
    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: var(--billboard-titleColor);
        .meta {
          font-weight: 500;
          font-size: 20px;
          line-height: 23px;
          color: var(--billboard-metaColor);
        }
      }
      .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 100px;
          font-weight: 500;
          font-size: 16px;
          line-height: 19px;
          justify-content: flex-end;
          padding-right: 16px;
          color: rgba(0, 0, 0, 0.6);
        }
        .dir {
          width: 24px;
          height: 24px;
          margin-right: 12px;
          background: linear-gradient(113.71deg, #435acd 0%, #749cf3 100%);
          border-radius: var(--billboard-arrowRadius);
        }
      }
      .shop + .shop {
        margin-top: 4px;
      }
      .placeholder {
        z-index: 1;
        width: 100%;
        height: 40px;
      }
    }
  }

  .bullets {
    position: fixed;
    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: var(--billboard-legendColor, rgba(0, 0, 0, 0.6));
    }
    .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;
        }
      }
    }
  }
}
.ip {
  position: fixed;
  width: 180px;
  height: 257.5px;
  right: 56px;
  top: 742.5px;
  background: center / cover no-repeat url(./ip.png);
  z-index: 12;
}
.guide {
  position: fixed;
  height: 200px;
  width: 500px;
  right: 0;
  top: 800px;
  z-index: 13;
}
.header {
  position: fixed;
  width: 100vw;
  height: 200px;
  left: 0;
  top: 800px;
  background: top / contain no-repeat;
  z-index: 11;
  .r1 {
    position: fixed;
    top: 848px;
    left: 68px;
    display: flex;
    height: 23px;
    font-weight: 700;
    font-size: 20px;
    line-height: 23px;
    color: var(--billboard-legendColor, rgba(0, 0, 0, 0.6));
    img {
      width: 20px;
      height: 20px;
      margin-left: 4px;
    }
  }
  .r2 {
    position: fixed;
    top: 880px;
    left: 68px;
    font-weight: 900;
    font-size: 48px;
    line-height: 56px;
    color: var(--billboard-titleColor);
  }
  .r3 {
    position: fixed;
    top: 945px;
    left: 68px;
    width: 184px;
    height: 32px;
    background: center / cover no-repeat url(./metaV.png);
  }
  .qrcode {
    position: fixed;
    display: flex;
    left: 314px;
    top: 857px;
    width: 120px;
    height: 120px;
    background: #ffffff;
    border-radius: 12px;
    justify-content: center;
    align-items: center;
  }
}
@media (min-aspect-ratio: 1/1) {
  .billboard {
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 1;

    .list-container {
      left: 1326px;
      top: 322px;
      width: 594px;
      .column {
        width: 286px;
        .format {
          width: 270px;
        }
        .shop {
          width: 270px;
        }
      }
    }
    .bullets {
      left: auto;
      right: 253px;
      bottom: 35px;
    }
  }
  .ip {
    width: 147.15px;
    height: 210.5px;
    left: 1738.3px;
    top: 71px;
  }
  .guide {
    height: 139px;
    top: 143px;
  }
  .header {
    height: 139px;
    top: 143px;
    .r1 {
      left: 220px;
      top: 163px;
    }
    .r2 {
      left: 220px;
      top: 190px;
      font-size: 40px;
      line-height: 47px;
    }
    .r3 {
      left: 220px;
      top: 241px;
      background: center / cover no-repeat url(./metaH.png);
    }
    .qrcode {
      left: 68px;
      top: 153px;
    }
  }
}
</style>
