<script setup lang="ts">
import { h, ref } from 'vue';

import { VxeUI } from 'vxe-pc-ui';
import { ArrowDownOutlined, ArrowUpOutlined, EditOutlined } from '@ant-design/icons-vue';

import { useWatcher } from 'alova/client';
import { getPatientTagsMethod, patientMethod } from '@/request/api/patient.api';
import { getPatientDiagnosisReportMethod, getPatientHealthIndicatorMethod, getPatientHealthRecordMethod } from '@/request/api/report.api';
import type { PatientModel, PatientTagVO, ReportModel } from '@/model';

import UseDict from '@/core/dictionary/component';
import HealthReportAnalysisWidget from '@/widgets/HealthReportAnalysisWidget.vue';

const props = defineProps<{
  patient: Partial<PatientModel>;
  report: Partial<ReportModel>;
  source?: string;
  sourceInsName?: string;
}>();

const emits = defineEmits<{
  refresh: [];
  destroy: [];
}>();

// 患者基本信息
const { data: patient } = useWatcher(() => patientMethod(props.patient?.id!), [() => props.patient.id], {
  initialData: { ...props.patient },
  immediate: true,
  middleware: (_, next) => {
    if (props.patient.id) next();
  },
});

const { data: patientTags, loading: loadPatientTagsPending } = useWatcher(() => getPatientTagsMethod(props.patient?.id!), [() => props.patient.id], {
  initialData: [],
  immediate: true,
  middleware: (_, next) => {
    if (props.patient.id) next();
  },
});

// 患者最后一次就诊记录
const { data: diagnosisRecord } = useWatcher(() => getPatientDiagnosisReportMethod(0, props.patient?.id!), [() => props.patient.id], {
  initialData: { disease: {}, symptom: {} },
  immediate: true,
  middleware: (_, next) => {
    if (props.patient.id) next();
  },
});

// 患者最后一次健康分析报告
const { data: healthRecord } = useWatcher(() => getPatientHealthRecordMethod(props.report?.id!), [() => props.report.id], {
  initialData: {},
  immediate: true,
  middleware: (_, next) => {
    if (props.report.id) next();
  },
});

const { data: indicator } = useWatcher(() => getPatientHealthIndicatorMethod(props.patient?.id!), [() => props.patient.id], {
  initialData: [],
  immediate: true,
  middleware: (_, next) => {
    if (props.patient.id) next();
  },
});

const panels = shallowReactive([
  {
    id: 'patient-diagnosis-records',
    title: '就诊记录',
    component: defineAsyncComponent(() => import('@/widgets/PatientDiagnosisRecordsWidget.vue')),
  },
  {
    id: 'patient-followUp-records',
    title: '就诊随访',
    component: defineAsyncComponent(() => import('@/widgets/PatientFollowUpRecordsWidget.vue')),
  },
  {
    id: 'patient-service-records',
    title: '调养记录',
    component: defineAsyncComponent(() => import('@/widgets/PatientCareRecordsWidget.vue')),
  },
  {
    id: 'patient-health-records',
    title: '健康分析记录',
    component: defineAsyncComponent(() => import('@/widgets/PatientHealthRecordsWidget.vue')),
  },
  {
    id: 'patient-physicalSign-records',
    title: '生理指标',
    component: defineAsyncComponent(() => import('@/widgets/PatientPhysicalSignRecordsWidget.vue')),
  },
]);

const activePanel = ref(panels[0].id);
const activePanelChange = (event: Event) => {
  (event.target as HTMLElement)?.scrollIntoView({ block: 'start', behavior: 'smooth' });
};

function openPatientTagEdit(event: MouseEvent) {
  const width = 500;
  const offset = 32;
  const component = defineAsyncComponent(() => import('@/components/PatientTagEdit.vue'));
  const id = `PatientTagEdit`;
  VxeUI.modal.open({
    id,
    title: '标签',
    type: 'modal',
    position: {
      top: event.pageY + offset,
      left: event.pageX - width,
    },
    escClosable: true,
    resize: true,
    width,
    minWidth: width,
    mask: false,
    slots: {
      default() {
        return h(component, {
          id: patient.value.id,
          tags: patientTags.value,
          onDestroy(values?: PatientTagVO[]) {
            if (values) {
              patientTags.value = values;
              emits('refresh');
            }
            VxeUI.modal.close(id);
          },
        });
      },
    },
  });
}

function openPatientRecordsPreview() {
  const component = defineAsyncComponent(() => import('@/components/RecordsPatientPreview.vue'));
  const id = `modal:record-patient:preview`;
  const onDestroy = () => {
    VxeUI.modal.close(id);
  };
  onDestroy();
  VxeUI.modal.open({
    id,
    remember: true,
    showMaximize: true,
    mask: false,
    lockView: false,
    padding: false,
    resize: true,
    width: Math.floor(window.innerWidth * 0.5),
    height: Math.floor(window.innerHeight * 0.5),
    escClosable: true,
    maskClosable: true,
    title: `基础信息更新记录`,
    slots: {
      default() {
        return h(component, {
          patient: patient.value,
          onDestroy,
        });
      },
    },
  });
}

function openIndicatorRecordsPreview() {
  const component = defineAsyncComponent(() => import('@/components/RecordsIndicatorPreview.vue'));
  const id = `modal:record-indicator:preview`;
  console.log(patient.value, 'patient======');
  const onDestroy = () => {
    VxeUI.modal.close(id);
  };
  onDestroy();
  VxeUI.modal.open({
    id,
    remember: true,
    showMaximize: true,
    mask: false,
    lockView: false,
    padding: false,
    resize: true,
    width: Math.floor(window.innerWidth * 0.5),
    height: Math.floor(window.innerHeight * 0.5),
    escClosable: true,
    maskClosable: true,
    title: `指标信息更新记录`,
    slots: {
      default() {
        return h(component, {
          patient: patient.value,
          records: indicator.value,
          onDestroy,
        });
      },
    },
  });
}
</script>

<template>
  <div class="p-6">
    <div class="flex">
      <section class="flex-auto">
        <div class="row mb-5" v-if="source || sourceInsName">
          <span class="text-lg mr-12 font-bold">来源</span>
          <a-tag color="pink">{{ source }}</a-tag>
          <a-tag color="red">{{ sourceInsName }}</a-tag>
        </div>
        <header class="flex items-center">
          <div class="title">基本信息</div>
          <a-button type="link" @click="openPatientRecordsPreview">更新记录</a-button>
        </header>
        <main>
          <div class="row">
            <a-space class="separate" :size="0">
              <span>{{ patient.name }}</span>
              <UseDict v-slot="{ value }" sign="sys_user_sex" :raw="patient.gender">
                <span v-if="value">{{ value }}</span>
              </UseDict>
              <span v-if="patient.age">{{ patient.age }} 岁</span>
              <UseDict v-slot="{ value }" sign="women_special_period" :raw="patient.womenSpecialPeriod">
                <span v-if="value && value !== '无'">{{ value }}</span>
              </UseDict>
              <UseDict v-slot="{ value }" sign="job" :raw="patient.job">
                <span v-if="value && value !== '无'">{{ value }}</span>
              </UseDict>
              <span v-if="patient.phone"><label>手机号</label> {{ patient.phone }}</span>
              <span v-if="patient.cardno"><label>身份证号</label> {{ patient.cardno }}</span>
            </a-space>
          </div>
          <div class="row">
            <a-space :size="40">
              <span v-if="patient.height"><label>身高</label> {{ patient.height }} cm</span>
              <span v-if="patient.weight"><label>体重</label> {{ patient.weight }} kg</span>
              <UseDict v-slot="{ value }" sign="sys_yes_no" :raw="patient.drinkState">
                <span v-if="value"><label>饮酒</label> {{ value }}</span>
              </UseDict>
              <UseDict v-slot="{ value }" sign="sys_yes_no" :raw="patient.smokeState">
                <span v-if="value"><label>抽烟</label> {{ value }}</span>
              </UseDict>
              <UseDict v-slot="{ value }" sign="food_allergy" :raw="patient.foodAllergy2" :multiple="true" :separator="[',', '、']">
                <span v-if="value"><label>食物过敏</label> {{ value }}</span>
              </UseDict>
              <UseDict v-slot="{ value }" sign="hobby_flavor" :raw="patient.hobbyFlavor" :multiple="true" :separator="[',', '、']">
                <span v-if="value"><label>喜好口味</label> {{ value }}</span>
              </UseDict>
            </a-space>
          </div>
        </main>
      </section>
      <section class="flex-none min-w-100px max-w-400px">
        <label>标签：</label>
        <a-spin v-if="loadPatientTagsPending"></a-spin>
        <template v-else>
          <a-tag v-for="tag in patientTags" :key="tag.id" :color="tag.color">{{ tag.name }}</a-tag>
          <a-button type="link" @click="openPatientTagEdit($event)">
            <template #icon>
              <EditOutlined />
            </template>
          </a-button>
        </template>
      </section>
    </div>
    <section class="mt-4">
      <header class="flex items-center">
        <div class="title">健康状况</div>
      </header>
      <main>
        <div class="row" v-if="diagnosisRecord">
          <header>
            <label>诊断</label>
            <span>{{ diagnosisRecord.disease?.name }} - {{ diagnosisRecord.symptom?.name }}</span>
            <span v-if="diagnosisRecord.date">（{{ diagnosisRecord.date }}）</span>
          </header>
        </div>
        <div class="row">
          <header>
            <label>健康状态</label>
            <span>{{ healthRecord.result?.status }}</span>
            <span v-if="healthRecord.date">（{{ healthRecord.date }}）</span>
          </header>
          <main>
            <div class="row">
              <a-space :size="24">
                <a-space direction="vertical" :size="12">
                  <span><label>程度</label>{{ healthRecord.result?.level }}</span>
                  <span><label>表现</label>{{ healthRecord.result?.description }}</span>
                  <span><label>症素</label>{{ healthRecord.syndromeElement?.label }}</span>
                </a-space>
                <a-space direction="vertical" :size="12">
                  <span><label>类型</label>{{ healthRecord.result?.category }}</span>
                  <span><label>体质</label>{{ healthRecord.physique?.label }}</span>
                  <span><label>证型</label>{{ healthRecord.syndrome?.label }}</span>
                </a-space>
              </a-space>
            </div>
          </main>
        </div>
        <div class="row">
          <header>
            <label>症状</label>
            <span>{{ healthRecord.symptom?.value || ' - ' }}</span>
            <span v-if="healthRecord.symptom?.duration">，{{ healthRecord.symptom?.duration }}</span>
            <span v-if="healthRecord.symptom?.influence">，{{ healthRecord.symptom?.influence }}</span>
          </header>
        </div>
        <HealthReportAnalysisWidget class="row" category="tongue" :analysis="healthRecord.analysis"></HealthReportAnalysisWidget>
        <HealthReportAnalysisWidget class="row" category="face" :analysis="healthRecord.analysis"></HealthReportAnalysisWidget>
        <div class="row" v-if="indicator.length">
          <header>
            <label>生理指标</label>
            <a-button type="link" @click="openIndicatorRecordsPreview">更新记录</a-button>
          </header>
          <main>
            <div class="flex flex-wrap">
              <div class="text-center w-260px row" v-for="item in indicator" :key="item.id">
                <div class="flex justify-center">
                  <span
                    ><label>{{ item.name }}</label
                    >{{ item.value }}{{ item.unit }}</span
                  >
                  <div class="inline-block ml-2 size-24px">
                    <a-button v-if="item.trend > 0" :icon="h(ArrowUpOutlined)" shape="circle" size="small" class="trend-up" />
                    <a-button v-else-if="item.trend < 0" :icon="h(ArrowDownOutlined)" shape="circle" size="small" class="trend-down" />
                  </div>
                </div>
                <div class="text-center mt-1" style="font-size: 14px; color: rgba(0, 0, 0, 0.45)">{{ item.date }}</div>
              </div>
            </div>
          </main>
        </div>
      </main>
    </section>
    <a-tabs class="panel-wrapper" v-model:activeKey="activePanel">
      <a-tab-pane v-for="panel in panels" :key="panel.id">
        <component :is="panel.component" :patient="patient"></component>
      </a-tab-pane>
      <template #renderTabBar>
        <a-radio-group v-model:value="activePanel" @change="activePanelChange($event.nativeEvent)">
          <a-radio-button v-for="panel in panels" :key="panel.id" :value="panel.id" :disabled="panel.disabled">
            {{ panel.title }}
          </a-radio-button>
        </a-radio-group>
      </template>
    </a-tabs>
  </div>
</template>

<style scoped lang="scss">
.title-text {
  font-size: 16px;
  color: rgba(0, 0, 0, 0.45);
}
section {
  color: rgba(0, 0, 0, 0.85);

  > header {
    font-size: 18px;
    font-weight: 700;

    :deep(.ant-btn-link) {
      padding-block: 0;
      font-size: 18px;
      border: none;
    }
  }

  > main {
    margin-left: 18px * 4;
    padding: 0 15px;
    font-size: 16px;
    color: rgba(0, 0, 0, 0.85);

    > .row > .ant-space {
      font-size: 16px;
    }

    .row {
      padding: 12px 0;

      span > label {
        color: rgba(0, 0, 0, 0.45);
      }

      label::after {
        margin-left: 2px;
        margin-right: 8px;
        content: ':';
      }

      > header::before {
        $size: 10px;
        content: '';
        display: inline-block;
        margin-right: 12px;
        width: $size;
        height: $size;
        border: 2px solid #1d6ff6;
        border-radius: 50%;
      }

      > main {
        margin-left: 18px * 2;
      }
    }
  }

  .ant-tag {
    margin-top: 6px;
  }
}

.separate {
  :deep(.ant-space-item) {
    & + .ant-space-item::before {
      content: '，';
      margin-right: 2px;
    }
  }

  span + span::before {
    content: '，';
    margin-right: 2px;
  }
}

.panel-wrapper {
  :deep(.ant-tabs-content-holder) {
    padding-top: 12px;
    height: calc(100vh - 60px - 24px - 32px);

    .ant-tabs-content {
      height: 100%;
    }
  }
}

.trend-up {
  color: #ff4d4f;
  border-color: #ff4d4f;
}

.trend-down {
  color: #87d068;
  border-color: #87d068;
}
</style>
