<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { fetchDictByCode } from '@/api/admin/dict'
import TeacherPaperDialog from '@/components/TeacherPaperDialog.vue'
import {
  approveTeacher,
  createUniversity,
  deleteTeacherPaper,
  fetchTeacher,
  fetchTeacherFilterOptions,
  fetchTeacherPapers,
  fetchUniversities,
  rejectTeacher,
  updateTeacher,
  type DictItemBrief,
  type PaperRow,
  type TeacherRow,
} from '@/api/admin/teachers'
import {
  demandStatusTagType,
  fetchDemandHandleLogs,
  fetchDemandsList,
  type DemandHandleLogRow,
  type DemandRow,
} from '@/api/admin/demands'
import { followRuleHint, previewNextFollowDate } from '@/utils/teacherFollowRule'
import { starDisplay } from '@/utils/teacherStar'
import { useAuthStore } from '@/stores/auth'
import { ElMessage, ElMessageBox } from 'element-plus'

const auth = useAuthStore()
const isGridMember = computed(() => auth.isGridMember)

const props = defineProps<{
  modelValue: boolean
  teacherId: number | null
  /** 仅查看，不可编辑（如地图页老师详情） */
  readonly?: boolean
}>()

const isReadonly = computed(() => props.readonly === true)

const dialogTitle = computed(() => {
  const name = teacher.value?.name
  if (isReadonly.value) {
    return name ? `查看 · ${name}` : '老师详情'
  }
  return name ? `编辑 · ${name}` : '编辑老师'
})

function displayUniversity(row: TeacherRow) {
  if (row.university_name) return row.university_name
  if (row.university_text) return `${row.university_text}（未关联高校库）`
  return '—'
}

function displayDirections(row: TeacherRow) {
  if (row.research_direction) return row.research_direction
  return row.research_directions?.map((d) => d.name).join('、') || '—'
}

const emit = defineEmits<{
  'update:modelValue': [boolean]
  saved: []
}>()

async function approveTeacherAction() {
  if (!teacher.value) return
  await approveTeacher(teacher.value.id)
  ElMessage.success('已确认入库')
  emit('saved')
  emit('update:modelValue', false)
}

async function rejectTeacherAction() {
  if (!teacher.value) return
  await ElMessageBox.confirm(`确定驳回「${teacher.value.name}」？驳回后记录会保留。`, '确认驳回', {
    type: 'warning',
  })
  await rejectTeacher(teacher.value.id)
  ElMessage.success('已驳回')
  emit('saved')
  emit('update:modelValue', false)
}

const loading = ref(false)
const teacher = ref<TeacherRow | null>(null)
const loadedStarId = ref<number | null>(null)

const starFollowRule = computed(() => {
  const item = starOptions.value.find((s) => s.id === form.value.star_level_dict_item_id)
  return followRuleHint(item?.value)
})
const papers = ref<PaperRow[]>([])
const demands = ref<DemandRow[]>([])
const starOptions = ref<DictItemBrief[]>([])
const statusOptions = ref<DictItemBrief[]>([])
const universityOptions = ref<{ id: number; name: string; city?: string | null }[]>([])
const directionOptions = ref<{ id: number; name: string }[]>([])

function splitDirectionValues(values: Array<number | string>) {
  const ids: number[] = []
  const names: string[] = []
  for (const value of values) {
    if (typeof value === 'number') {
      ids.push(value)
      continue
    }
    const name = String(value).trim()
    if (name) names.push(name)
  }
  return { ids, names }
}

const form = ref({
  name: '',
  university_id: undefined as number | undefined,
  city: '',
  title: '',
  department: '',
  bio: '',
  research_direction_values: [] as Array<number | string>,
  phone: '',
  email: '',
  star_level_dict_item_id: undefined as number | undefined,
  status_dict_item_id: undefined as number | undefined,
  next_follow_date: '',
})

const universityDialog = ref(false)
const universitySaving = ref(false)
const universityForm = ref({
  name: '',
  city: '',
  province: '',
  longitude: '',
  latitude: '',
})

const paperDialog = ref(false)
const summaryVisible = ref(false)
const summaryText = ref('')

const demandRecordsVisible = ref(false)
const demandRecordsTitle = ref('')
const demandRecords = ref<DemandHandleLogRow[]>([])

async function loadUniversityOptions() {
  const uni = await fetchUniversities({ page: 1, page_size: 200 })
  const scopeIds = auth.user?.grid_scope?.university_ids
  universityOptions.value = scopeIds?.length
    ? uni.items.filter((u) => scopeIds.includes(u.id))
    : uni.items
}

async function refreshDirectionOptions() {
  const filters = await fetchTeacherFilterOptions()
  const scopeDirIds = auth.user?.grid_scope?.research_direction_ids
  directionOptions.value = scopeDirIds?.length
    ? filters.research_directions.filter((d) => scopeDirIds.includes(d.id))
    : filters.research_directions
}

function mergeTeacherDirectionOptions(detail: {
  research_directions?: { id: number; name: string }[]
}) {
  const known = new Set(directionOptions.value.map((d) => d.id))
  for (const d of detail.research_directions || []) {
    if (!known.has(d.id)) {
      directionOptions.value.push({ id: d.id, name: d.name })
      known.add(d.id)
    }
  }
}

function openUniversityCreate() {
  universityForm.value = {
    name: '',
    city: form.value.city || '',
    province: '',
    longitude: '',
    latitude: '',
  }
  universityDialog.value = true
}

async function saveUniversityCreate() {
  const f = universityForm.value
  if (!f.name.trim()) {
    ElMessage.warning('请填写高校名称')
    return
  }
  if (!f.longitude.trim() || !f.latitude.trim()) {
    ElMessage.warning('请填写经度与纬度')
    return
  }
  const longitude = Number(f.longitude)
  const latitude = Number(f.latitude)
  if (Number.isNaN(longitude) || Number.isNaN(latitude)) {
    ElMessage.warning('经纬度须为有效数字')
    return
  }
  universitySaving.value = true
  try {
    const u = await createUniversity({
      name: f.name.trim(),
      city: f.city.trim() || null,
      province: f.province.trim() || null,
      longitude,
      latitude,
    })
    if (!universityOptions.value.some((x) => x.id === u.id)) {
      universityOptions.value.push(u)
    }
    form.value.university_id = u.id
    if (u.city) {
      form.value.city = u.city
    }
    universityDialog.value = false
    ElMessage.success('高校已创建')
  } finally {
    universitySaving.value = false
  }
}

async function load() {
  if (!props.teacherId) return
  loading.value = true
  try {
    const detail = await fetchTeacher(props.teacherId)
    teacher.value = detail
    loadedStarId.value = detail.star_level_dict_item_id ?? null
    mergeTeacherDirectionOptions(detail)
    form.value = {
      name: detail.name || '',
      university_id: detail.university_id ?? undefined,
      research_direction_values: detail.research_direction_ids?.length
        ? [...detail.research_direction_ids]
        : detail.research_directions?.map((d) => d.id) || [],
      city: detail.city || '',
      title: detail.title || '',
      department: detail.department || '',
      bio: detail.bio || '',
      phone: detail.phone || '',
      email: detail.email || '',
      star_level_dict_item_id: detail.star_level_dict_item_id ?? undefined,
      status_dict_item_id: detail.status_dict_item_id ?? undefined,
      next_follow_date: detail.next_follow_date || '',
    }
    const [paperList, demandRes] = await Promise.all([
      fetchTeacherPapers(props.teacherId),
      fetchDemandsList({ teacher_id: props.teacherId, page: 1, page_size: 50 }),
    ])
    papers.value = paperList
    demands.value = demandRes.items
  } finally {
    loading.value = false
  }
}

function validateForm(): boolean {
  const f = form.value
  if (!f.name.trim()) {
    ElMessage.warning('请填写姓名')
    return false
  }
  if (!f.university_id) {
    ElMessage.warning('请选择高校，或点击「新建高校」')
    return false
  }
  if (!f.city.trim()) {
    ElMessage.warning('请填写城市')
    return false
  }
  if (!f.title.trim()) {
    ElMessage.warning('请填写职称')
    return false
  }
  const directions = splitDirectionValues(f.research_direction_values)
  if (!directions.ids.length && !directions.names.length) {
    ElMessage.warning('请至少选择一个或新增研究方向')
    return false
  }
  if (!f.status_dict_item_id) {
    ElMessage.warning('请选择状态')
    return false
  }
  return true
}

async function save() {
  if (!props.teacherId || !teacher.value) return
  if (!validateForm()) return

  const starChanged = (form.value.star_level_dict_item_id ?? null) !== loadedStarId.value

  const directions = splitDirectionValues(form.value.research_direction_values)

  await updateTeacher(props.teacherId, {
    name: form.value.name.trim(),
    university_id: form.value.university_id,
    city: form.value.city.trim(),
    title: form.value.title.trim(),
    department: form.value.department.trim() || null,
    bio: form.value.bio.trim() || null,
    research_direction_ids: directions.ids,
    new_research_directions: directions.names,
    phone: form.value.phone || null,
    email: form.value.email || null,
    star_level_dict_item_id: form.value.star_level_dict_item_id ?? null,
    status_dict_item_id: form.value.status_dict_item_id,
    ...(starChanged
      ? { recalc_next_follow_date: true }
      : { next_follow_date: form.value.next_follow_date || null, recalc_next_follow_date: false }),
  })
  ElMessage.success('已保存')
  emit('saved')
  emit('update:modelValue', false)
}

function onStarChange() {
  const item = starOptions.value.find((s) => s.id === form.value.star_level_dict_item_id)
  form.value.next_follow_date = previewNextFollowDate(item?.value) || ''
}

function onUniversityPick(id: number | undefined) {
  if (!id) return
  const u = universityOptions.value.find((x) => x.id === id)
  if (u?.city && !form.value.city) {
    form.value.city = u.city
  }
}

function openAddPaper() {
  paperDialog.value = true
}

async function reloadPapers() {
  if (!props.teacherId) return
  papers.value = await fetchTeacherPapers(props.teacherId)
}

async function removePaper(row: PaperRow) {
  await ElMessageBox.confirm(`确定删除论文「${row.title}」？`, '确认删除', { type: 'warning' })
  await deleteTeacherPaper(props.teacherId!, row.id)
  papers.value = await fetchTeacherPapers(props.teacherId!)
}

function showSummary(row: PaperRow) {
  summaryText.value = row.summary || '暂无摘要'
  summaryVisible.value = true
}

async function openDemandRecords(row: DemandRow) {
  demandRecordsTitle.value = row.title
  demandRecords.value = await fetchDemandHandleLogs(row.id)
  demandRecordsVisible.value = true
}

watch(
  () => [props.modelValue, props.teacherId] as const,
  async ([open, id]) => {
    if (open && id) {
      if (!starOptions.value.length) {
        const [star, status] = await Promise.all([
          fetchDictByCode('teacher_level'),
          fetchDictByCode('teacher_status'),
        ])
        starOptions.value = star.items
        statusOptions.value = status.items
        await loadUniversityOptions()
      }
      await refreshDirectionOptions()
      await load()
    }
  },
)

watch(
  () => form.value.university_id,
  (id) => onUniversityPick(id),
)
</script>

<template>
  <el-dialog
    :model-value="modelValue"
    :title="dialogTitle"
    width="960px"
    top="4vh"
    destroy-on-close
    @update:model-value="emit('update:modelValue', $event)"
  >
    <div v-loading="loading" class="detail-body">
      <div v-if="isReadonly && teacher" class="basic-info-block">
        <h3 class="basic-info-title">基本信息</h3>
        <el-descriptions :column="3" border size="small" class="view-desc">
          <el-descriptions-item label="姓名">{{ teacher.name }}</el-descriptions-item>
          <el-descriptions-item label="高校">{{ displayUniversity(teacher) }}</el-descriptions-item>
          <el-descriptions-item label="城市">{{ teacher.city || '—' }}</el-descriptions-item>
          <el-descriptions-item label="职称">{{ teacher.title || '—' }}</el-descriptions-item>
          <el-descriptions-item label="研究方向" :span="2">
            {{ displayDirections(teacher) }}
          </el-descriptions-item>
          <el-descriptions-item label="电话">{{ teacher.phone || '—' }}</el-descriptions-item>
          <el-descriptions-item label="邮箱">{{ teacher.email || '—' }}</el-descriptions-item>
          <el-descriptions-item label="星级">
            {{
              starDisplay(teacher.star_level_item?.value, teacher.star_level_item?.label)
            }}
          </el-descriptions-item>
          <el-descriptions-item label="状态">
            {{ teacher.status_item?.label || '—' }}
          </el-descriptions-item>
          <el-descriptions-item label="下次跟进日期">
            {{ teacher.next_follow_date || '—' }}
          </el-descriptions-item>
          <el-descriptions-item v-if="teacher.source_item?.label" label="来源">
            {{ teacher.source_item.label }}
          </el-descriptions-item>
        </el-descriptions>
      </div>

      <div v-else class="basic-info-block">
        <h3 class="basic-info-title">基本信息</h3>
        <el-form label-position="top" class="form-small">
          <el-row :gutter="12">
            <el-col :xs="24" :md="4">
              <el-form-item label="姓名" required>
                <el-input v-model="form.name" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="8">
              <el-form-item label="高校" required>
                <p
                  v-if="teacher?.university_text && !form.university_id"
                  class="crawl-uni-hint"
                >
                  论文抓取高校：{{ teacher.university_text }}（请在下拉中选择或新建以关联）
                </p>
                <div class="uni-row">
                  <el-select
                    v-model="form.university_id"
                    filterable
                    placeholder="选择高校"
                    style="flex: 1"
                  >
                    <el-option v-for="u in universityOptions" :key="u.id" :label="u.name" :value="u.id" />
                  </el-select>
                  <el-button
                    v-if="!isGridMember"
                    type="primary"
                    size="small"
                    class="teachers-primary-btn"
                    @click="openUniversityCreate"
                  >
                    新建高校
                  </el-button>
                </div>
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="4">
              <el-form-item label="城市" required>
                <el-input v-model="form.city" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="8">
              <el-form-item label="职称" required>
                <el-input v-model="form.title" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="8">
              <el-form-item label="所属学院">
                <el-input v-model="form.department" placeholder="如：计算机科学与技术学院" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="16">
              <el-form-item label="个人简介">
                <el-input v-model="form.bio" type="textarea" :rows="3" placeholder="老师个人简介" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="8">
              <el-form-item label="研究方向" required>
                <el-select
                  v-model="form.research_direction_values"
                  multiple
                  filterable
                  allow-create
                  default-first-option
                  collapse-tags
                  collapse-tags-tooltip
                  placeholder="选择或输入研究方向"
                  style="width: 100%"
                >
                  <el-option v-for="d in directionOptions" :key="d.id" :label="d.name" :value="d.id" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="6">
              <el-form-item label="电话">
                <el-input v-model="form.phone" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="6">
              <el-form-item label="邮箱">
                <el-input v-model="form.email" type="email" />
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="4">
              <el-form-item label="星级">
                <el-select v-model="form.star_level_dict_item_id" style="width: 100%" @change="onStarChange">
                  <el-option v-for="o in starOptions" :key="o.id" :label="o.label" :value="o.id" />
                </el-select>
                <span class="star-preview">
                  {{
                    starDisplay(
                      starOptions.find((s) => s.id === form.star_level_dict_item_id)?.value,
                      starOptions.find((s) => s.id === form.star_level_dict_item_id)?.label,
                    )
                  }}
                </span>
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="6">
              <el-form-item label="状态" required>
                <el-select v-model="form.status_dict_item_id" placeholder="请选择状态" style="width: 100%">
                  <el-option v-for="o in statusOptions" :key="o.id" :label="o.label" :value="o.id" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :xs="24" :md="6">
              <el-form-item label="下次跟进日期">
                <el-date-picker
                  v-model="form.next_follow_date"
                  type="date"
                  value-format="YYYY-MM-DD"
                  placeholder="选择日期"
                  style="width: 100%"
                />
                <p v-if="starFollowRule" class="star-follow-rule">{{ starFollowRule }}</p>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>

      <div class="section">
        <div class="section-head">
          <h3>论文列表</h3>
          <span class="muted">共 {{ papers.length }} 篇</span>
          <el-button v-if="!isReadonly" size="small" type="primary" plain @click="openAddPaper">
            添加论文
          </el-button>
        </div>
        <el-table :data="papers" size="small" row-key="id">
          <el-table-column prop="title" label="标题" min-width="200" show-overflow-tooltip />
          <el-table-column prop="authors" label="作者" width="140" />
          <el-table-column prop="school_name" label="学校" width="120" />
          <el-table-column prop="published_at" label="发表时间" width="110" />
          <el-table-column label="链接" width="70">
            <template #default="{ row }">
              <el-link v-if="row.url" :href="row.url" target="_blank">查看</el-link>
            </template>
          </el-table-column>
          <el-table-column label="操作" :width="isReadonly ? 70 : 120">
            <template #default="{ row }">
              <el-button link type="primary" @click="showSummary(row)">摘要</el-button>
              <el-button v-if="!isReadonly" link type="danger" @click="removePaper(row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>

      <div class="section">
        <div class="section-head">
          <h3>需求列表</h3>
          <span class="muted">共 {{ demands.length }} 条</span>
        </div>
        <el-table :data="demands" size="small" row-key="id">
          <el-table-column label="类型" width="100">
            <template #default="{ row }">
              <el-tag size="small" effect="dark">{{ row.type_item?.label }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="title" label="标题" min-width="180" show-overflow-tooltip />
          <el-table-column prop="submitted_at" label="时间" width="110" />
          <el-table-column label="处理状态" width="100">
            <template #default="{ row }">
              <el-tag :type="demandStatusTagType(row.status_item?.value)" size="small" effect="dark">
                {{ row.status_item?.label }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="跟进记录" width="100">
            <template #default="{ row }">
              <el-button size="small" @click="openDemandRecords(row)">
                {{ row.handle_logs_count || 0 }}条记录
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-empty v-if="!demands.length" description="暂无关联需求" :image-size="64" />
      </div>
    </div>

    <template #footer>
      <el-button @click="emit('update:modelValue', false)">关闭</el-button>
      <el-button
        v-if="teacher?.library_status === 'pending' && !isReadonly"
        type="success"
        @click="approveTeacherAction"
      >
        确认入库
      </el-button>
      <el-button
        v-if="teacher?.library_status === 'pending' && !isReadonly"
        type="danger"
        @click="rejectTeacherAction"
      >
        驳回
      </el-button>
      <el-button v-if="!isReadonly" type="primary" class="teachers-primary-btn" @click="save">
        保存
      </el-button>
    </template>

    <el-dialog v-model="universityDialog" title="新建高校" width="480px" append-to-body destroy-on-close>
      <el-form label-position="top" class="form-small">
        <el-form-item label="高校名称" required>
          <el-input v-model="universityForm.name" placeholder="如：复旦大学" />
        </el-form-item>
        <el-row :gutter="12">
          <el-col :span="12">
            <el-form-item label="经度" required>
              <el-input v-model="universityForm.longitude" placeholder="如：121.5031" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="纬度" required>
              <el-input v-model="universityForm.latitude" placeholder="如：31.2970" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="12">
          <el-col :span="12">
            <el-form-item label="省份">
              <el-input v-model="universityForm.province" placeholder="如：上海市" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="城市">
              <el-input v-model="universityForm.city" placeholder="如：上海" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button @click="universityDialog = false">取消</el-button>
        <el-button type="primary" class="teachers-primary-btn" :loading="universitySaving" @click="saveUniversityCreate">
          保存
        </el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="summaryVisible" title="论文摘要" width="520px" append-to-body>
      <p class="summary-body">{{ summaryText }}</p>
    </el-dialog>

    <TeacherPaperDialog
      v-model="paperDialog"
      :teacher-id="teacherId"
      :default-authors="teacher?.name || form.name"
      :default-school-name="universityOptions.find((u) => u.id === form.university_id)?.name || teacher?.university_name || ''"
      @saved="reloadPapers"
    />

    <el-dialog v-model="demandRecordsVisible" title="需求跟进记录" width="640px" append-to-body>
      <p class="follow-summary">{{ demandRecordsTitle }}</p>
      <div v-for="r in demandRecords" :key="r.id" class="log-card">
        <div class="log-head">
          <strong>{{ r.operator_name }}</strong>
          <span>{{ r.handled_at }}</span>
          <el-tag v-if="r.status_item" size="small" :type="demandStatusTagType(r.status_item.value)">
            {{ r.status_item.label }}
          </el-tag>
        </div>
        <p>{{ r.content }}</p>
      </div>
      <el-empty v-if="!demandRecords.length" description="暂无记录" />
    </el-dialog>
  </el-dialog>
</template>

<style scoped>
.detail-body {
  width: 100%;
}
.basic-info-block {
  margin-bottom: 16px;
}
.view-desc {
  width: 100%;
}
.basic-info-title {
  margin: 0 0 12px;
  padding-left: 10px;
  border-left: 3px solid #244e98;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--el-text-color-primary);
}
.crawl-uni-hint {
  margin: 0 0 8px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--el-color-warning);
}
.uni-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
}
.form-small :deep(.el-form-item__label) {
  font-size: 13px;
  padding-bottom: 4px;
}
.star-preview {
  display: block;
  margin-top: 4px;
  color: #e6a23c;
  font-size: 13px;
}
.star-follow-rule {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: #6b7280;
}
.section {
  margin-top: 16px;
  border-top: 1px solid var(--el-border-color-lighter);
  padding-top: 12px;
}
.section-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.section-head h3 {
  margin: 0;
  font-size: 15px;
}
.muted {
  font-size: 13px;
  color: var(--el-text-color-secondary);
}
.section-head .el-button {
  margin-left: auto;
}
.summary-body {
  white-space: pre-wrap;
  margin: 0;
}
.follow-summary {
  margin: 0 0 12px;
  font-weight: 500;
}
.log-card {
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 6px;
  padding: 10px;
  margin-bottom: 8px;
}
.log-head {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 6px;
  font-size: 13px;
}
:global(.teachers-primary-btn.el-button--primary) {
  --el-button-text-color: #fff;
  --el-button-bg-color: #244e98;
  --el-button-border-color: #244e98;
  --el-button-hover-text-color: #fff;
  --el-button-hover-bg-color: #8b1519;
  --el-button-hover-border-color: #8b1519;
  --el-button-active-text-color: #fff;
  --el-button-active-bg-color: #8b1519;
  --el-button-active-border-color: #8b1519;
}
</style>
