<template>
  <Loading v-if="pageLoading && patients.length === 0" text="加载中..." />
  <scroll-view v-else scroll-y class="page-scroll" @scrolltolower="onLoadMore">
    <view :class="['page-content', elderClass]">
      <!-- 搜索栏 -->
      <view class="search-bar">
        <input
          class="search-input"
          placeholder="搜索患者姓名/手机号"
          placeholder-class="search-placeholder"
          :value="search"
          confirm-type="search"
          @input="onSearchInput"
          @confirm="handleSearch"
        />
      </view>

      <!-- 标签过滤 -->
      <scroll-view v-if="tags.length > 0" scroll-x class="tag-filter">
        <view
          :class="['tag-chip', { active: !activeTag }]"
          @tap="handleTagFilter('')"
        >
          <text>全部</text>
        </view>
        <view
          v-for="tag in tags"
          :key="tag.id"
          :class="['tag-chip', { active: activeTag === tag.id }]"
          :style="activeTag === tag.id && tag.color ? `background: ${tag.color}; color: white` : ''"
          @tap="handleTagFilter(tag.id)"
        >
          <text>{{ tag.name }}</text>
        </view>
      </scroll-view>

      <!-- 患者数量 -->
      <view class="patient-count">
        <text>共 {{ total }} 位患者</text>
      </view>

      <!-- 患者卡片列表 -->
      <EmptyState v-if="patients.length === 0" icon="📋" title="暂无患者数据" />
      <view v-else class="patient-cards">
        <view
          v-for="p in patients"
          :key="p.id"
          class="patient-card"
          @tap="goDetail(p.id)"
        >
          <view class="patient-card__header">
            <text class="patient-card__name">{{ p.name }}</text>
            <text class="patient-card__meta">{{ genderLabel(p.gender) }} {{ calcAge(p.birth_date) }}</text>
          </view>
          <view v-if="p.tags && p.tags.length > 0" class="patient-card__tags">
            <view
              v-for="t in p.tags"
              :key="t.id"
              class="patient-tag"
              :style="t.color ? `background: ${t.color}20; color: ${t.color}` : ''"
            >
              <text class="patient-tag__text">{{ t.name }}</text>
            </view>
          </view>
          <text v-if="p.status" :class="['patient-card__status', `patient-card__status--${p.status}`]">
            {{ p.status === 'active' ? '活跃' : p.status === 'inactive' ? '非活跃' : p.status }}
          </text>
        </view>
      </view>

      <!-- 加载更多提示 -->
      <view v-if="!loadingMore && patients.length >= total && total > 0" class="load-hint-wrap">
        <text class="load-hint">没有更多了</text>
      </view>
      <Loading v-if="loadingMore" text="加载中..." />
    </view>
  </scroll-view>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { onShow, onPullDownRefresh } from '@dcloudio/uni-app'
import { useElderClass } from '@/composables/useElderClass'
import { listPatients, listPatientTags } from '@/services/doctor/patient'
import type { PatientItem, PatientTag } from '@/services/doctor/patient'
import Loading from '@/components/Loading.vue'
import EmptyState from '@/components/EmptyState.vue'

const { elderClass } = useElderClass()

const patients = ref<PatientItem[]>([])
const tags = ref<PatientTag[]>([])
const activeTag = ref('')
const search = ref('')
const pageLoading = ref(true)
const loadingMore = ref(false)
const isLoading = ref(false)
const total = ref(0)
const page = ref(1)

function genderLabel(gender?: string): string {
  if (!gender) return ''
  if (gender === 'male') return '男'
  if (gender === 'female') return '女'
  return gender
}

function calcAge(birthDate?: string): string {
  if (!birthDate) return ''
  const birth = new Date(birthDate)
  const now = new Date()
  let age = now.getFullYear() - birth.getFullYear()
  if (
    now.getMonth() < birth.getMonth() ||
    (now.getMonth() === birth.getMonth() && now.getDate() < birth.getDate())
  ) {
    age--
  }
  return `${age}岁`
}

async function loadTags() {
  try {
    const res = await listPatientTags()
    tags.value = res.data || []
  } catch {
    // 静默失败
  }
}

async function loadPatients(pageNum: number, isRefresh = false) {
  if (isLoading.value) return
  isLoading.value = true
  if (isRefresh) {
    pageLoading.value = true
  } else {
    loadingMore.value = true
  }
  try {
    const res = await listPatients({
      page: pageNum,
      page_size: 20,
      search: search.value || undefined,
      tag_id: activeTag.value || undefined,
    })
    const list = res.data || []
    if (isRefresh) {
      patients.value = list
    } else {
      patients.value = [...patients.value, ...list]
    }
    total.value = res.total || 0
    page.value = pageNum
  } catch {
    uni.showToast({ title: '加载失败', icon: 'none' })
  } finally {
    pageLoading.value = false
    loadingMore.value = false
    isLoading.value = false
  }
}

function onSearchInput(e: { detail: { value: string } }) {
  search.value = e.detail.value
}

function handleSearch() {
  loadPatients(1, true)
}

function handleTagFilter(tagId: string) {
  activeTag.value = tagId === activeTag.value ? '' : tagId
}

function goDetail(id: string) {
  uni.navigateTo({ url: `/pages-sub/doctor/patients/detail/index?id=${id}` })
}

function onLoadMore() {
  if (!isLoading.value && patients.value.length < total.value) {
    loadPatients(page.value + 1)
  }
}

watch(activeTag, () => {
  loadPatients(1, true)
})

onMounted(() => {
  loadTags()
  loadPatients(1, true)
})

onPullDownRefresh(() => {
  loadPatients(1, true).finally(() => {
    uni.stopPullDownRefresh()
  })
})

onShow(() => {
  // 从详情页返回时不需要重新加载，保留列表状态
})
</script>

<style lang="scss" scoped>
.page-scroll {
  height: 100vh;
  background: $bg;
}

.page-content {
  padding: 24px;
  padding-bottom: 120px;
}

// ── 搜索栏 ──
.search-bar {
  margin-bottom: 20px;
}

.search-input {
  background: $card;
  border-radius: $r;
  padding: 20px 24px;
  font-size: var(--tk-font-body-lg);
  width: 100%;
  box-sizing: border-box;
  box-shadow: $shadow-sm;
}

.search-placeholder {
  color: $tx3;
}

// ── 标签过滤 ──
.tag-filter {
  white-space: nowrap;
  margin-bottom: 20px;
  width: 100%;
}

.tag-chip {
  display: inline-flex;
  align-items: center;
  padding: 10px 24px;
  min-height: $touch-min;
  border-radius: $r-pill;
  background: $bd-l;
  font-size: var(--tk-font-h2);
  color: $tx2;
  margin-right: 16px;

  &.active {
    background: $pri;
    color: $card;
  }
}

// ── 患者计数 ──
.patient-count {
  margin-bottom: 16px;

  text {
    font-size: var(--tk-font-h2);
    color: $tx3;
  }
}

// ── 患者卡片 ──
.patient-cards {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.patient-card {
  background: $card;
  border-radius: $r-lg;
  padding: 28px;
  box-shadow: $shadow-sm;

  &:active {
    background: $bd-l;
  }

  &__header {
    display: flex;
    align-items: center;
    margin-bottom: 12px;
  }

  &__name {
    font-size: var(--tk-font-num);
    font-weight: 600;
    color: $tx;
    margin-right: 16px;
  }

  &__meta {
    font-size: var(--tk-font-h2);
    color: $tx2;
  }

  &__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 8px;
  }

  &__status {
    @include tag($bg, $tx2);

    &--active {
      @include tag($acc-l, $acc);
    }

    &--inactive {
      @include tag($bd-l, $tx3);
    }
  }
}

.patient-tag {
  padding: 4px 14px;
  border-radius: $r;
  background: $pri-l;

  &__text {
    font-size: var(--tk-font-body);
  }
}

// ── 加载提示 ──
.load-hint-wrap {
  text-align: center;
  padding: 20px;
}

.load-hint {
  font-size: var(--tk-font-h2);
  color: $tx3;
}
</style>
