<script setup lang="ts">
import { Dialog, Toast }                    from '@/platform';
import { saveFileMethod, uploadFileMethod } from '@/request/api/camera.api';
import { tryOnMounted, tryOnUnmounted }     from '@vueuse/core';
import { useForm, useRequest }              from 'alova/client';
import { useFlowStore }                     from '@/stores';
import Segmented, { type ConfigProps }      from './camera.config';
import Camera                               from './camera.vue';

import NavHomeSelect from '@/assets/images/nav-home.select.png?url';


let audio: HTMLAudioElement | void;

const Flow = useFlowStore();
const { form: dataset, loading: submitting, send: submit } = useForm(data => saveFileMethod(data), {
  initialForm: { } as Record<string, any>,
}).onSuccess(({ data }) => Flow.router.push()).onError(() => {
  handle();
  step.value = 1;
});

const step = ref(0);
const snapshot = ref<string | void>();
const config = shallowRef<ConfigProps>();

const showExample = ref(false);

watch([ step, snapshot ], ([ step, snapshot ], old, onCleanup) => {
  const { before, after, ..._config } = Segmented[ step - 1 ];
  const old_audio = config.value?.audio;
  config.value = Object.assign(_config, snapshot ? after : before);

  if ( old_audio !== config.value.audio ) {
    audio?.pause();
    if ( config.value.audio && audio ) {
      audio.src = config.value.audio;
      audio.play()
           .catch(() => Dialog.show({ message: '开始拍摄', theme: 'round-button' }))
           .then(() => audio!.play());
    }
  }
});

const cameraRef = useTemplateRef<InstanceType<typeof Camera>>('camera');

const { loading: uploading, send: update } = useRequest((file: File) => uploadFileMethod(file), {
  immediate: false,
});

const handle = () => {
  if ( submitting.value ) return;
  snapshot.value = cameraRef.value?.handle();
};
const next = async () => {
  if ( uploading.value || submitting.value ) return;
  if ( snapshot.value ) {
    uploading.value = true;
    const key = config.value!.key;

    const toast = Toast.loading(50, { message: '上传中...' });

    const response = await fetch(snapshot.value);
    const blob = await response.blob();
    const file = new File(
      [ blob ],
      `${ dataset.value.patientId }_${ key?.replace?.(/img/ig, '') }`,
      { type: blob.type },
    );
    try {
      const { url } = await update(file);
      dataset.value[ key ] = url;
    } finally {
      toast.close();
    }
  }

  if ( step.value === Segmented.length ) {
    submit();
  } else {
    handle();
    step.value += 1;
  }
};

tryOnMounted(() => {
  audio = document.createElement('audio');
  document.body.appendChild(audio);
});
tryOnUnmounted(() => {
  audio?.pause();
  audio = void 0;
});
</script>
<template>
  <div>
    <div 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">
          {{ config?.title }}
        </div>
      </div>
      <div class="grow shrink-0 h-full min-w-16 flex items-center justify-end overflow-hidden">
        <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">
      <header class="flex flex-col justify-center px-24">
        <div class="text-3xl text-center">{{ config?.label }}</div>
        <div class="mt-8 text-lg text-center tracking-wider leading-10">{{ config?.description }}</div>
      </header>
      <main class="flex justify-center items-center">
        <Camera ref="camera" v-bind="config?.video" @loaded="step = 1;">
          <template #shade="{scale}">
            <component :is="config?.shade" :scale="scale"></component>
          </template>
        </Camera>
        <div v-if="config?.example" class="size-40 absolute -top-8 right-2 cursor-pointer hover:text-primary">
          <img class="size-full object-scale-down" :src="config?.example" alt="示例" />
        </div>
      </main>
      <footer class="flex flex-col justify-center items-center">
        <div v-if="snapshot" class="flex justify-evenly w-full cursor-pointer">
          <div class="">
            <img class="h-20" src="@/assets/images/button-cancel.png" alt="重拍" @click="handle()" /></div>
          <div class="cursor-pointer">
            <img class="h-20" src="@/assets/images/button-confirm.png" alt="确认" @click="next()" />
          </div>
        </div>
        <div v-else-if="step" class="h-min text-center cursor-pointer hover:text-primary" @click="handle()">
          <button class="size-28 border-8 rounded-full hover:border-primary"></button>
          <div class="mt-8 text-3xl">点击拍照</div>
        </div>
      </footer>
    </div>
  </div>
</template>
<style scoped lang="scss">
header, footer {
  flex: 1 1 20%;
}

main {
  position: relative;;
  flex: 1 1 40%;
}
</style>
