<script setup lang="ts">
import ReportAnalysisEdit   from '@/components/ReportAnalysisEdit.vue';
import ReportHistoryPreview from '@/components/ReportHistoryPreview.vue';
import type { ReportModel } from '@/model';

import { patientMethod, patientTags } from '@/request/api/patient.api';
import {
  confirmSchemeMethod,
  indicatorByReportIdMethod,
  reportMethod,
  reportSchemeMethod,
  reportsMethod,
}                                     from '@/request/api/report.api';

import PatientCardWidget                      from '@/widgets/PatientCardWidget.vue';
import PatientTagWidget                       from '@/widgets/PatientTagWidget.vue';
import ReportCardWidget                       from '@/widgets/ReportCardWidget.vue';
import ReportSchemeCardWidget                 from '@/widgets/ReportSchemeCardWidget.vue';
import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons-vue';
import { useElementSize }                     from '@vueuse/core';
import { useRouteQuery }                      from '@vueuse/router';

import { invalidateCache }                                    from 'alova';
import { actionDelegationMiddleware, useRequest, useWatcher } from 'alova/client';

import { h }               from 'vue';
import { useRouter }       from 'vue-router';
import { RecycleScroller } from 'vue-virtual-scroller';
import { VxeUI }           from 'vxe-pc-ui';


const patientId = useRouteQuery<string>('patientId');
const reportId = useRouteQuery<string>('reportId');

const reportCollapsed = ref(true);
const schemeCollapsed = ref(false);
const { data: patient, loading: patientLoading } = useWatcher(
  () => patientMethod(patientId.value),
  [ patientId ],
  {
    initialData: {}, immediate: true,
    middleware: (_, next) => { if ( patientId.value ) next(); },
  },
).onSuccess(() => {
  reportCollapsed.value = true;
  schemeCollapsed.value = false;
  unref(patientCardRef.value?.elementTarget)?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
});

const { data: tags, loading: tagsLoading, send: loadTags } = useWatcher(
  () => patientTags(patientId.value),
  [ patientId ],
  {
    initialData: [], immediate: true,
    middleware: (_, next) => { if ( patientId.value ) next(); },
  },
);

const { data: reports, loading: reportsLoading } = useWatcher(
  () => reportsMethod(patientId.value),
  [ patientId ],
  {
    initialData: [], immediate: true,
    middleware: (_, next) => { if ( patientId.value ) next(); },
  },
);

const { data: report, loading: reportLoading, send: loadReport } = useWatcher(
  () => reportMethod(reportId.value!),
  [ reportId ],
  {
    initialData: {}, immediate: true,
    middleware: (_, next) => { if ( reportId.value ) next(); },
  },
);

const { data: indicator, loading: indicatorLoading } = useWatcher(
  () => indicatorByReportIdMethod(reportId.value!),
  [ reportId ],
  {
    initialData: [], immediate: true,
    middleware: (_, next) => {
      if ( reportId.value ) return actionDelegationMiddleware('updatePatientIndicator')(_, next);
    },
  },
);

const { data: scheme, loading: schemeLoading, send: schemeRefresh } = useWatcher(
  () => reportSchemeMethod(reportId.value!),
  [ reportId ],
  {
    initialData: {}, immediate: true,
    middleware: (_, next) => { if ( reportId.value ) next(); },
  },
);
const { loading: confirmSchemeLoading, send: confirmScheme } = useRequest(
  () => confirmSchemeMethod(reportId.value),
  { immediate: false },
).onSuccess(() => {
  loadReport(reportId.value!);
});

watchEffect(() => {
  if ( !reportId.value ) {
    report.value = {} as any;
    scheme.value = {} as any;
  }
});

const router = useRouter();

function handle(model: ReportModel) {
  router.replace({
    path: router.currentRoute.value.path,
    query: { ...router.currentRoute.value.query, patientId: patientId.value, reportId: model.id },
  });
}

function schemeRefreshHandle(id?: string) {
  invalidateCache(reportSchemeMethod(reportId.value!));
  schemeRefresh().then(() => nextTick()).then(() => {
    if ( id ) {
      document.querySelector(`#scrollable_scheme_${ id }`)?.scrollIntoView(
        { behavior: 'smooth', block: 'start', inline: 'nearest' });
    }
  });
}

const analysisReportPreviewOpening = ref();
const historyReportPreviewOpening = ref();

function openHistoryPreviewHandle() {
  const id = `drawer:report-history:preview`;
  const onDestroy = () => { VxeUI.drawer.close(id); };
  onDestroy();
  VxeUI.drawer.open({
    id,
    title: `健康档案`,
    maskClosable: true,
    escClosable: true,
    padding: false,
    width: window.innerWidth - 256,
    slots: {
      default() {
        return h(ReportHistoryPreview, {
          patient: patient.value,
          report: reports.value[ 0 ],
          onDestroy,
        });
      },
    },
    onHide() {
      VxeUI.modal.close();
      historyReportPreviewOpening.value = false;
    },
  });
}

function openAnalysisEditHandle() {
  const id = `drawer:report-analysis:edit`;
  const onDestroy = () => { VxeUI.drawer.close(id); };
  VxeUI.drawer.open({
    id,
    title: `信息采集`,
    maskClosable: true,
    escClosable: true,
    padding: false,
    width: window.innerWidth - 256,
    slots: {
      default() {
        return h(ReportAnalysisEdit, {
          patient: patient.value,
          report: report.value,
          onDestroy,
        });
      },
    },
    onHide() {
      VxeUI.modal.close();
      analysisReportPreviewOpening.value = false;
    },
  });
}

const patientCardRef = ref<HTMLElement & { elementTarget: HTMLElement }>();
const { height } = useElementSize(patientCardRef);
</script>
<template>
  <div id="page-container-scroller" class="page-container flex flex-row">
    <div class="page-container-main flex-auto flex flex-col">
      <div class="area">
        <PatientCardWidget ref="patientCardRef" :dataset="patient" :loading="patientLoading" />
        <ReportCardWidget :dataset="report" :loading="reportLoading" collapsible v-model:collapsed="reportCollapsed">
          <template #analysis v-if="report.analysable">
            <a-button
              type="primary" size="small"
              :loading="analysisReportPreviewOpening"
              @click="analysisReportPreviewOpening = true;openAnalysisEditHandle()"
            >
              信息采集
            </a-button>
          </template>
          <a-card class="card background no-bordered-8" size="small" title="指标信息" :loading="indicatorLoading">
            <a-descriptions v-if="indicator?.length" :column="3" size="small">
              <a-descriptions-item v-for="item in indicator" :key="item.id" :label="item.name">
                <div v-if="item.value">
                  <span>{{ item.value }}</span>
                  <span v-if="item.unit">{{ item.unit }}</span>
                  <ArrowUpOutlined class="icon" v-if="item.records?.[0]?.abnormal === 1" />
                  <ArrowDownOutlined class="icon" v-if="item.records?.[0]?.abnormal === -1" />
                </div>
                <span v-else>-</span>
              </a-descriptions-item>
            </a-descriptions>
            <div v-else style="padding-bottom: 8px;">暂无数据</div>
          </a-card>
        </ReportCardWidget>
      </div>
      <div class="area flex-auto" v-if="report?.scheme?.show">
        <ReportSchemeCardWidget
          :dataset="scheme" :loading="schemeLoading" :editable="report?.scheme?.editable"
          v-model:collapsed="schemeCollapsed"
          @refresh="schemeRefreshHandle($event)"
        >
          <template #footer v-if="report?.scheme?.editable">
            <div style="padding: 8px;background-color: #fff;text-align: center;">
              <a-button type="primary" :loading="confirmSchemeLoading" @click="confirmScheme()">确认</a-button>
            </div>
          </template>
        </ReportSchemeCardWidget>
      </div>
      <a-result class="area" v-if="!patientId" style="background-color: #fff;" status="warning" title="未选择用户">
        <template #extra>
          <div>请在左侧重新选择</div>
        </template>
      </a-result>
      <a-result class="area" v-else-if="!reportId" style="background-color: #fff;" status="warning"
                title="暂无健康分析"
      >
        <template #extra>
          <div>请重新选择</div>
        </template>
      </a-result>
    </div>
    <div class="page-container-aside flex-none flex flex-col">
      <PatientTagWidget
        style="min-height: 112px;flex: none"
        :style="{height: `${height}px`}"
        :dataset="tags" :loading="tagsLoading"
        editable @refresh="loadTags()"
      />
      <div class="flex-auto flex flex-col overflow-hidden">
        <div class="card__header flex justify-between items-center">
          <div class="card__title flex-none">
            <span>报告记录</span>
            <a-spin v-if="reportsLoading" size="small" style="margin-left: 4px;" />
          </div>
          <a-button type="primary" size="small" :disabled="!reportId"
                    :loading="reportLoading || historyReportPreviewOpening"
                    @click="historyReportPreviewOpening = true;openHistoryPreviewHandle();"
          >
            健康档案
          </a-button>
        </div>
        <div class="flex-auto overflow-auto" style="background-color: #f1f1f1;">
          <a-empty v-if="!reportsLoading && !reports.length" />
          <RecycleScroller v-else ref="scroller" class="record-scroller" key-field="id"
                           :items="reports" :item-size="40"
          >
            <template v-slot="{ item }">
              <div class="record-item flex justify-center items-center h-40px cursor-pointer"
                   :class="{active: reportId == item.id}"
                   @click="handle(item)"
              >
                {{ item.time }}
              </div>
            </template>
          </RecycleScroller>
        </div>
      </div>
    </div>
  </div>
</template>
<style scoped lang="scss">
@import "@/themes/report-card";

.page-container {
  background-color: #dfe0eb;
  max-height: var(--page-main-container);
}

.page-container-main {
  overflow-y: auto;

  > .area {
    margin-left: 12px;
    margin-bottom: 12px;
    background-color: #fff;

    &:last-of-type {
      margin-bottom: 0;
    }
  }
}

.page-container-aside {
  width: 256px;
  background-color: #fff;
}

.record-scroller {
  width: 100%;
  height: 100%;

  .record-item {
    padding: 4px 8px;
    color: #333;
    border-bottom: 1px solid #e5e5e5;

    &:hover,
    &.active {
      color: #fff;
      background-color: #999;
    }
  }
}

.ant-empty {
  margin: 24px;
}
</style>
