<template>
  <div class="patientList-container" :class="{ 'patientList-container-unexpand': !currentExpand }">
    <div
      class="patientList-operate"
      :class="{ 'patientList-operate-unexpand': !currentExpand }"
      v-if="currentExpand"
    >
      <el-input
        class="patientList-search-input"
        placeholder="床号/住院号/姓名"
        v-model="searchKeyword"
        @keyup.enter="handleSearch"
        :prefix-icon="Search"
      />
      <el-button class="icon-btn" circle @click="handleRefresh" type="text" plain>
        <el-icon icon-class="Refresh" size="24" :class="{ 'is-rotating': refreshing }">
          <Refresh />
        </el-icon>
      </el-button>
    </div>

    <transition name="patient-list-toggle" mode="out-in">
      <div key="expanded" class="patientList-list" v-if="currentExpand">
        <div class="patient-cards" v-loading="isLoading">
          <template v-if="filteredCardData && filteredCardData.length > 0">
            <el-scrollbar ref="expandScrollbarRef" class="patient-cards-scrollbar">
              <div
                class="patient-card"
                v-for="item in filteredCardData"
                :key="item.encounterId"
                :id="item.encounterId"
                @click="handleItemClick(item)"
                :class="{ actived: activeCardId === item.encounterId }"
              >
                <div class="patient-card-header">
                  <div class="header-top">
                    <div class="bed-container">
                      <div class="bed">
                        <div class="bed-info">
                          <div v-if="item.houseName" class="house-name">{{ item.houseName }}</div>
                          <div class="bed-name">{{ item.bedName || '未分床' }}</div>
                        </div>
                      </div>
                    </div>
                    <el-space>
                      <el-tag
                        v-if="item.statusEnum_enumText"
                        size="small"
                        class="payer-tag-status"
                        effect="light"
                        :style="getStatusStyle(item.statusEnum)"
                      >
                        {{ item.statusEnum_enumText }}
                      </el-tag>
                      <el-tag
                        v-if="item.contractName"
                        size="small"
                        class="payer-tag"
                        effect="light"
                      >
                        {{ item.contractName }}
                      </el-tag>
                    </el-space>
                  </div>

                  <div class="header-bottom">
                    <span class="bus-no">住院号：{{ item.busNo || '-' }}</span>
                    <span class="insurance-type" v-if="item.insutype_dictText">
                      险种类型：{{ item.insutype_dictText }}
                    </span>
                  </div>
                </div>

                <div class="doctor-parent-line" />

                <div class="patient-card-body">
                  <div class="personal-info-container">
                    <div class="name-container">
                      <div class="name">
                        <el-text :text="item.patientName" tclass="name" width="auto">
                          {{ item.patientName || '-' }}
                        </el-text>
                      </div>
                      <div class="age">
                        <el-tag
                          size="small"
                          class="age-tag"
                          effect="plain"
                          :class="{ 'age-tag-female': item.genderEnum_enumText === '女性' }"
                        >
                          {{ item.genderEnum_enumText || '-' }}
                          <span v-if="item.age"> · {{ item.age }}</span>
                        </el-tag>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </el-scrollbar>
          </template>
          <el-empty v-else description="暂无数据" />
        </div>
      </div>
      <div
        key="collapsed"
        class="patientList-list"
        v-else
        v-loading="isLoading"
        :class="{ 'patientList-list-unexpand': !currentExpand }"
      >
        <el-scrollbar ref="contractScrollbarRef" class="patient-cards-scrollbar">
          <template v-if="filteredCardData && filteredCardData.length > 0">
            <el-tooltip
              v-for="item in filteredCardData"
              :show-after="200"
              :key="item.encounterId"
              :show-arrow="true"
              placement="right"
              effect="light"
              :offset="4"
            >
              <template #content>
                <div class="card-tooltip">
                  <div class="card-tooltip-main">
                    <span class="card-tooltip-bed">{{ item.bedName }}</span>
                    <span class="card-tooltip-name">{{ item.patientName }}</span>
                  </div>
                  <div class="card-tooltip-sex">
                    <span class="card-tooltip-sex-text">
                      {{ item.genderEnum_enumText || '-' }}
                      <span v-if="item.age"> · {{ item.age }}</span>
                    </span>
                  </div>
                </div>
              </template>

              <div>
                <div
                  class="card-small"
                  :class="{ 'patient-active': activeCardId === item.encounterId }"
                  @click="handleSmallCardClick(item)"
                  :key="item.encounterId"
                >
                  {{ item.bedName }}
                </div>
                <div class="patient-card-small-border"></div>
              </div>
            </el-tooltip>
          </template>
          <el-empty v-else description="暂无数据" :image-size="50" />
        </el-scrollbar>
      </div>
    </transition>

    <div
      class="patientList-toggle-btn-wrap"
      :class="{ 'patientList-toggle-btn-wrap-unexpand': !currentExpand }"
    >
      <el-button class="icon-btn" circle @click="updateExpand">
        <el-icon class="svg-sty-menu" size="24">
          <Expand v-if="!currentExpand" />
          <Fold v-if="currentExpand" />
        </el-icon>
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import {computed, ref, watch} from 'vue';
import {Expand, Fold, Refresh, Search} from '@element-plus/icons-vue';
import type {ElScrollbar} from 'element-plus';

interface PatientCardItem {
  encounterId: string;
  bedName?: string;
  busNo?: string;
  patientName?: string;
  genderEnum_enumText?: string;
  age?: number | string;
  contractName?: string;
  [key: string]: any;
}

interface Props {
  // 过滤后的卡片数据
  filteredCardData?: PatientCardItem[];
  // 当前激活的卡片ID
  activeCardId?: string;
  // 是否展开（不传则为不受控模式，组件内部自己管理）
  expand?: boolean;
  // 加载状态
  loading?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  filteredCardData: () => [],
  activeCardId: '',
  expand: undefined,
  loading: false,
});

interface Emits {
  (e: 'item-click', item: PatientCardItem): void;
  (e: 'search', keyword: string): void;
  (e: 'refresh'): void;
  (e: 'update:expand', value: boolean): void;
}

const emit = defineEmits<Emits>();

const searchKeyword = ref<string>('');
const refreshing = ref<boolean>(false);
const refreshLoading = ref<boolean>(false);

const internalExpand = ref<boolean>(true);

const isControlled = computed<boolean>(() => props.expand !== undefined);

const currentExpand = computed<boolean>(() => {
  return isControlled.value ? props.expand! : internalExpand.value;
});

const isLoading = computed<boolean>(() => {
  return props.loading || refreshLoading.value;
});

const handleItemClick = (item: PatientCardItem): void => {
  emit('item-click', item);
};

const handleSmallCardClick = (item: PatientCardItem): void => {
  emit('item-click', item);
};

const handleSearch = (): void => {
  emit('search', searchKeyword.value);
};

const handleRefresh = (): void => {
  if (refreshing.value) return;
  refreshing.value = true;
  refreshLoading.value = true;
  emit('refresh');
  setTimeout(() => {
    refreshing.value = false;
  }, 600);

  setTimeout(() => {
    if (!props.loading) {
      refreshLoading.value = false;
    }
  }, 500);
};

const updateExpand = (): void => {
  const newValue = !currentExpand.value;
  if (isControlled.value) {
    emit('update:expand', newValue);
  } else {
    internalExpand.value = newValue;
  }
};

// 根据状态枚举值返回文本颜色
const getStatusColor = (statusEnum?: number): string => {
  if (statusEnum === undefined || statusEnum === null) {
    return '';
  }

  switch (statusEnum) {
    case 2: // REGISTERED - 待入科
      return '#E6A23C'; // 橙色
    case 3: // AWAITING_DISCHARGE - 待出院
      return '#F56C6C'; // 红色
    case 4: // DISCHARGED_FROM_HOSPITAL - 待出院结算
      return '#909399'; // 灰色
    case 5: // ADMITTED_TO_THE_HOSPITAL - 已入院
      return '#67C23A'; // 绿色
    case 6: // PENDING_TRANSFER - 待转科
      return '#409EFF'; // 蓝色
    default:
      return '';
  }
};

// 根据状态枚举值返回带透明背景的样式
const getStatusStyle = (statusEnum?: number): Record<string, string> => {
  const color = getStatusColor(statusEnum);
  if (!color) {
    return {};
  }

  // 不同状态对应的半透明背景色
  let backgroundColor = '';
  switch (statusEnum) {
    case 2: // 橙色
      backgroundColor = 'rgba(230, 162, 60, 0.12)';
      break;
    case 3: // 红色
      backgroundColor = 'rgba(245, 108, 108, 0.12)';
      break;
    case 4: // 灰色
      backgroundColor = 'rgba(144, 147, 153, 0.12)';
      break;
    case 5: // 绿色
      backgroundColor = 'rgba(103, 194, 58, 0.12)';
      break;
    case 6: // 蓝色
      backgroundColor = 'rgba(64, 158, 255, 0.12)';
      break;
    default:
      backgroundColor = 'rgba(148, 163, 184, 0.12)';
  }

  return {
    color,
    backgroundColor,
    borderColor: 'transparent',
  };
};

// 保险类型映射表
const insuranceTypeMap: Record<number, string> = {
  310: '职工基本医疗保险',
  320: '公务员医疗补助',
  330: '大额医疗费用补助',
  340: '离休人员医疗保障',
  350: '一至六级残废军人医疗补助',
  360: '老红军医疗保障',
  370: '企业补充医疗保险',
  380: '新型农村合作医疗',
  390: '城乡居民基本医疗保险',
  391: '城镇居民基本医疗保险',
  392: '城乡居民大病医疗保险',
  399: '其他特殊人员医疗保障',
  410: '长期照护保险',
};

watch(
  () => props.loading,
  (newLoading) => {
    if (!newLoading && refreshLoading.value) {
      refreshLoading.value = false;
    }
  }
);
</script>

<style lang="scss" scoped>
.patient-card {
  width: 100%;
  overflow: hidden;
  background-color: #fff;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, 0.04);
  box-shadow: 0 2px 6px 0 rgba(15, 35, 52, 0.12);
  cursor: pointer;
  transition: transform 0.2s ease;

  &:hover {
    box-shadow: 0 4px 12px rgba(15, 35, 52, 0.18);
    transform: translateY(-1px);
  }

  &.actived {
    background-color: rgba(7, 155, 140, 0.06);
    border-color: var(--el-color-primary);
    box-shadow: 0 0 0 1px rgba(7, 155, 140, 0.3), 0 4px 14px rgba(7, 155, 140, 0.25);
  }

  .patient-card-header {
    display: flex;
    flex-direction: column;
    padding: 10px 12px 4px;

    .header-top {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;

      .bed-container {
        display: flex;
        flex: 1;
        align-items: center;
        min-width: 0;

        .bed {
          flex-grow: 0;
          flex-shrink: 1;
          min-width: 0;

          .bed-info {
            display: flex;
            flex-direction: column;
            line-height: 1.4;

            .house-name {
              color: #1f2933;
              font-weight: 600;
              font-size: 16px;
              white-space: normal;
              word-break: break-all;
            }

            .bed-name {
              color: #1f2933;
              font-weight: 600;
              font-size: 16px;
              white-space: normal;
              word-break: break-all;
            }
          }
        }
      }

      .payer-tag {
        max-width: 120px;
        font-size: 12px;
        border-radius: 999px;
        font-weight: bolder;
      }
      .payer-tag-status {
        font-weight: bolder;
        border-radius: 999px;
      }
    }

    .header-bottom {
      margin-top: 4px;
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: flex-start;
      gap: 2px;
      color: #6b7280;
      font-size: 12px;

      .bus-no {
        white-space: nowrap;
      }

      .insurance-type {
        white-space: nowrap;
      }
    }
  }

  .doctor-parent-line {
    margin: 6px 12px 0;
    border-bottom: 1px dashed #e5e7eb;
  }

  .patient-card-body {
    padding: 8px 12px 10px;

    .personal-info-container {
      display: block;

      .name-container {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        width: 100%;

        .name {
          color: #111827;
          font-weight: 600;
          font-size: 16px;
        }

        .age {
          flex-shrink: 0;

          .age-tag {
            border-radius: 999px;
            padding: 0 8px;
          }

          .age-tag-female {
            border-color: rgb(255, 55, 158);
            color: rgb(255, 126, 184);
          }
        }
      }
    }
  }
}

.patientList-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  height: 100%;
  border-right: 1px solid #ebeef5;
  background-color: #ffffff;
  width: 240px;
  min-width: 240px;
  &-unexpand {
    width: 84px;
    min-width: 84px;
  }
  .patientList-operate {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 44px;
    border-bottom: 1px solid #ebeef5;
    flex: none;
    padding: 0 0 0 8px;

    &-unexpand {
      justify-content: space-around;
    }
  }

  .patientList-list {
    display: flex;
    flex: 1;
    flex-direction: column;
    height: 0;
    width: 240px;
    &-unexpand {
      width: 84px;
    }

    .search-operate {
      padding: 0 8px;
      height: 48px;
      display: flex;
      align-items: center;
      flex: none;
    }

    .patient-cards {
      flex: 1;
      padding: 0 8px;

      overflow: hidden;

      :deep(.patient-cards-scrollbar) {
        width: 100%;
        height: 100%;

        .el-scrollbar__bar {
          width: 0;
        }
      }
    }

    .card-small {
      height: 44px;
      padding: 0 10px 0 12px;
      overflow: hidden;
      font-size: 14px;
      line-height: 44px;
      white-space: nowrap;
      text-overflow: ellipsis;
      border-right: none;
      cursor: pointer;
    }

    .patient-active {
      background-color: #e6f7ff;
      font-weight: 600;
      color: var(--el-color-primary);
    }

    .patient-card-small-border {
      display: block;
      width: 100%;
      height: 2px;
      background-color: #f1faff;
    }
  }
}

.patientList-toggle-btn-wrap {
  display: flex;
  justify-content: flex-end;
  padding: 4px 16px 8px;
  &-unexpand {
    justify-content: center;
  }
}

.patient-list-toggle-enter-active,
.patient-list-toggle-leave-active {
  transition: transform 0.2s ease;
}

.patient-list-toggle-enter-from,
.patient-list-toggle-leave-to {
  opacity: 0;
  transform: translateY(-8px);
}

.card-tooltip {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  min-width: 140px;
  max-width: 220px;
  padding: 6px 10px;
  border-radius: 6px;
  background-color: #ffffff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
}

.card-tooltip-main {
  display: flex;
  flex-direction: column;
  margin-right: 8px;
}

.card-tooltip-bed {
  font-size: 15px;
  font-weight: 600;
  color: #111827;
  margin-bottom: 2px;
}

.card-tooltip-name {
  font-size: 13px;
  color: #4b5563;
}

.card-tooltip-sex {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.card-tooltip-sex-text {
  font-size: 12px;
  color: #6b7280;
}

.svg-gray {
  fill: var(--hip-color-text-unit);
}

.icon-btn {
  border: none;
  background-color: transparent;
  box-shadow: none;
  padding: 4px;
}

.is-rotating {
  animation: patient-refresh-rotate 0.6s linear;
}

@keyframes patient-refresh-rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

:deep(.scrollbar) {
  width: 100%;
  height: 100%;

  .el-scrollbar__bar {
    width: 0;
  }
}

.f-16 {
  font-weight: 600;
  font-size: 16px;
}

.f-14 {
  font-size: 14px;
}

.empty-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;

  .empty-text-sty {
    margin-top: 0;
  }
}
</style>
