<script setup lang="ts">
import NavHomeSelect from '@/assets/images/nav-home.select.png?url';
import NavScheme     from '@/assets/images/nav-scheme.png?url';
import SchemeMedia               from '@/modules/report/SchemeMedia.vue';
import { getReportSchemeMethod } from '@/request/api/report.api';
import { useRouteParams }        from '@vueuse/router';
import { useWatcher }            from 'alova/client';
import { useRouter } from 'vue-router';
import QrcodeVue from 'qrcode.vue';

import MiniProgram from '@/components/MiniProgram.vue';

import type { SchemeGoodsProps } from '@/request/model';
import { createReusableTemplate } from '@vueuse/core';
import { Toast } from '@/platform';
import { useVisitor } from '@/stores';

const miniProgramRef = useTemplateRef<InstanceType<typeof MiniProgram>>('mini-program');

const route = useRoute();
const Visitor = useVisitor();
const id = useRouteParams<string>('id', Visitor.reportId);
const scrollable = ref(true);
const closeable = computed(() => !data.value.payLock);
const { data, loading } = useWatcher(() => getReportSchemeMethod(id.value, !route.meta.toggle), [id], {
  initialData: {
    children: [],
  },
  immediate: true,
}).onSuccess(({ data }) => {
  if ( data?.miniProgramURL && data.payLock ) {
    scrollable.value = false;
    nextTick(() => miniProgramRef.value?.open());
  }
});

const router = useRouter();

const toggleable = computed(() => route.meta.toggle ?? true);

function toggle() {
  const path = router.currentRoute.value.fullPath.replace('/scheme', '');
  router.replace({ path });
}

const { define: PreviewLinkSlot, reuse: ReusePreviewLink } = createReusableTemplate<{ src: string | void; complete?: Function; error?: Function }>();
const panelConfig = reactive({
  fullHeight: 0,
  height: 0,
  anchors: [0],
  goods: void 0 as unknown as SchemeGoodsProps,
  onError() {},
  onComplete(event?: Event) {},
});
const pageHeader = useTemplateRef('page-header');
const container = useTemplateRef('container');
const getHeightAndScrollTop = (value?: HTMLElement | string) => {
  const el = typeof value === 'string' ? container.value?.querySelector<HTMLDivElement>(`#${value}`) : value;
  if (!el) return true;
  el.scrollIntoView({ behavior: 'instant', block: 'start' });
  const maxHeight = window.innerHeight - (pageHeader.value?.getBoundingClientRect().height ?? 0);
  const height = window.innerHeight - el.getBoundingClientRect().bottom - Number.parseFloat(getComputedStyle(el).marginBottom);
  panelConfig.anchors = [0, height, maxHeight];
  panelConfig.height = height;
  panelConfig.fullHeight = maxHeight;
};
let lastFrameSrc: string;
async function openGoodsPanel(goods: SchemeGoodsProps, event?: Event | string) {
  if (panelConfig.goods === goods) {
    panelConfig.height = panelConfig.anchors[panelConfig.anchors.length - 1];
    return;
  }

  if (goods.type === 'link') {
    const toast = lastFrameSrc !== goods.value ? Toast.loading(500) : void 0;
    lastFrameSrc = goods.value;
    panelConfig.goods = goods;
    panelConfig.onComplete = () => {
      toast?.close();
      panelConfig.height = panelConfig.anchors[panelConfig.anchors.length - 1];
    };
    panelConfig.onError = () => {
      Toast.error(`链接加载错误`)
      panelConfig.height = 0;
    };
    if (!toast) setTimeout(panelConfig.onComplete, 100);
  } else if (goods.type === 'miniprogram') {
    return openGoodsScan(goods);
  } else {
    Toast.warning(`暂不支持该操作 (${goods.type})`);
    return;
  }

  if (getHeightAndScrollTop(typeof event === 'string' ? event : (event?.target as HTMLElement))) {
    const height = window.innerHeight * 0.8;
    panelConfig.anchors = [0, height];
    panelConfig.height = height;
    panelConfig.fullHeight = window.innerHeight - (pageHeader.value?.getBoundingClientRect().height ?? 0);
  }
}
const qrConfig = reactive({
  size: 300,
  margin: 2,
  background: '#0f2925',
  foreground: '#38ff6e',
});
const scanConfig = reactive({
  show: false,
  title: '微信扫一扫购买',
  mode: 'img' as 'img' | 'qr',
  url: '',
});
async function openGoodsScan(goods: SchemeGoodsProps) {
  if (goods.type === 'link') {
    scanConfig.mode = 'qr';
  } else if (goods.type === 'miniprogram') {
    scanConfig.mode = 'img';
  } else {
    Toast.warning(`暂不支持该操作 (${goods.type})`);
    return;
  }
  scanConfig.url = goods.value;
  scanConfig.show = true;
}
</script>
<template>
  <div>
    <div ref="page-header" class="page-header flex py-4 px-4">
      <div class="grow shrink-0 h-full min-w-16"></div>
      <div class="grow-[3] shrink mx-2 flex flex-col justify-center overflow-hidden">
        <div class="font-bold text-3xl text-nowrap text-center tracking-wide overflow-ellipsis overflow-hidden">
          调理方案
        </div>
      </div>
      <div class="grow shrink-0 h-full min-w-16">
        <router-link :to="{ path: '/screen' }" replace>
          <img class="size-8 object-scale-down" :src="NavHomeSelect" alt="返回首页" />
        </router-link>
      </div>
    </div>
    <div class="page-content flex flex-col overflow-hidden">
      <!--{{ data }}-->
      <van-skeleton class="flex-auto" title :row="3" :loading>
        <div class="flex-auto px-6" :class="[scrollable ? 'overflow-y-auto' : 'overflow-hidden']" ref="container">
          <div class="card my-6 text-lg" :id="item.id" v-for="item in data.children" :key="item.id">
            <div class="card__title mb-3 text-primary text-2xl font-bold">{{ item.title }}</div>
            <div class="card__content">
              <div class="my-4" :id="'T_' + card.id" v-for="card in item.children" :key="card.id">
                <div class="relative" :class="{ 'has-link': card.goods }">
                  <div class="text-xl text-center text-primary" v-if="card.title">{{ card.title }}</div>
                  <van-button
                    class="!absolute right-0" v-if="card.goods"
                    type="primary" icon="cart-o" size="small" plain
                    @click="openGoodsPanel(card.goods, 'T_' + card.id)"
                  >{{ card.goods.label }}</van-button>
                </div>
                <SchemeMedia :media="card.media"></SchemeMedia>
                <div v-if="card.description">{{ card.description }}</div>
                <div v-for="(item, index) in card.descriptions">
                  <span class="text-primary">【{{ item.title }}】</span>
                  <span v-html="item.description"></span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </van-skeleton>
      <div class="flex-none flex justify-between py-2 nav-wrapper" style="background-color: #12312c">
        <div v-if="toggleable" class="m-auto min-w-16 text-center hover:text-primary" @click="toggle()">
          <img class="nav-img" :src="NavScheme" alt="健康报告" />
          <div class="mt-2">健康报告</div>
        </div>
        <mini-program ref="mini-program" :url="data.miniProgramURL" :closeable="!data.payLock"></mini-program>
      </div>
    </div>

    <PreviewLinkSlot v-slot="{ src, complete, error }">
      <iframe v-if="src" :src="src" :style="{ maxHeight: panelConfig.height - 30 + 'px' }" @load="complete!" @error="error!"></iframe>
    </PreviewLinkSlot>
    <van-floating-panel
      ref="panel-wrapper-ref"
      :class="{ full: panelConfig.height === panelConfig.fullHeight }"
      :content-draggable="false"
      :lock-scroll="true"
      :anchors="panelConfig.anchors"
      v-model:height="panelConfig.height"
    >
      <template #header>
        <div class="van-floating-panel__header !justify-between">
          <div><van-icon class="pl-2" name="qr" @click="panelConfig.height = 0;openGoodsScan(panelConfig.goods)" /></div>
          <div class="van-floating-panel__header-bar"></div>
          <van-icon class="pr-2" name="cross" @click="panelConfig.height = 0" />
        </div>
      </template>
      <ReusePreviewLink v-if="panelConfig.goods?.type === 'link'" :src="panelConfig.goods?.value" :complete="panelConfig.onComplete"></ReusePreviewLink>
    </van-floating-panel>
    <van-dialog
      v-model:show="scanConfig.show"
      :title="scanConfig.title"
      confirm-button-text="关闭"
      close-on-click-overlay
    >
      <div class="scan-content">
        <qrcode-vue v-if="scanConfig.mode === 'qr'" :value="scanConfig.url" v-bind="qrConfig"></qrcode-vue>
        <img v-else-if="scanConfig.mode === 'img'" :src="scanConfig.url" alt="二维码">
        <div v-else>{{ scanConfig.url }}</div>
      </div>
    </van-dialog>
  </div>
</template>
<style scoped lang="scss">
.card {
  padding: 24px;
  border-radius: 24px;
  box-shadow: inset 0 0 80px 0 #34a76b60;
}

.van-button.decorate {
  font-size: 20px;
  height: 62px;
  width: 240px;
  background-size: 80%;
  letter-spacing: 2px;
}

.text-grey {
  color: #e3e3e3;
}

.nav-wrapper {
  .nav-img {
    margin: auto;
    width: 36px;
    height: 36px;
    object-fit: scale-down;
  }
}

.full {
  --van-floating-panel-border-radius: 0;
}

.scan-content {
  display: flex;
  flex-direction: column;
  align-items: center;

  img {
    padding: 10px 0;
    min-width: 320px;
    object-fit: contain;
  }
}

.has-link {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 40px;

  > div + .van-button {
    top: 4px !important;
  }
}

iframe {
  width: 100%;
  height: 100%;
  border: none;
}
</style>
