<template>
  <div class="app-container">
    <el-form
      ref="queryForm"
      :model="queryParams"
      size="small"
      :inline="true"
      v-show="showSearch"
      label-width="80px"
    >
      <el-form-item label="专家姓名" prop="expertName">
        <el-input
          v-model="queryParams.expertName"
          placeholder="请输入专家姓名"
          clearable
          style="width: 220px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="专家编号" prop="expertCode">
        <el-input
          v-model="queryParams.expertCode"
          placeholder="请输入专家编号"
          clearable
          style="width: 220px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="所属单位" prop="organization">
        <el-input
          v-model="queryParams.organization"
          placeholder="请输入所属单位"
          clearable
          style="width: 220px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="专长领域" prop="specialty">
        <el-select
          v-model="queryParams.specialty"
          placeholder="请选择专长领域"
          clearable
          filterable
          style="width: 220px"
          :loading="specialtyLoading"
        >
          <el-option
            v-for="item in specialtyOptions"
            :key="item.dictValue || item.value"
            :label="item.dictLabel || item.label"
            :value="item.dictValue || item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 220px">
          <el-option
            v-for="dict in dict.type.expert_status"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="关联账号" prop="sysUserId">
        <el-select
          v-model="queryParams.sysUserId"
          placeholder="请选择系统账号"
          clearable
          filterable
          remote
          reserve-keyword
          :remote-method="searchSysUsers"
          :loading="userLoading"
          style="width: 220px"
          @focus="searchSysUsers('')"
        >
          <el-option
            v-for="user in userOptions"
            :key="user.value"
            :label="user.label"
            :value="user.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-hasPermi="['resource:expert:add']"
        >新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate()"
          v-hasPermi="['resource:expert:edit']"
        >修改</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          plain
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete()"
          v-hasPermi="['resource:expert:remove']"
        >删除</el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" />
    </el-row>

    <el-table
      v-loading="loading"
      :data="expertList"
      border
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="50" align="center" />
      <el-table-column label="专家姓名" prop="expertName" min-width="140" show-overflow-tooltip>
        <template slot-scope="scope">
          <el-link type="primary" @click="handleView(scope.row)">{{ scope.row.expertName }}</el-link>
        </template>
      </el-table-column>
      <el-table-column label="专家编号" prop="expertCode" min-width="120" show-overflow-tooltip />
      <el-table-column label="所属单位" prop="organization" min-width="160" show-overflow-tooltip />
      <el-table-column label="专长领域" min-width="200">
        <template slot-scope="scope">
          <span v-if="!scope.row.specialtiesArray.length" class="text-placeholder">-</span>
          <el-tag
            v-for="(item, index) in scope.row.specialtiesArray"
            :key="index"
            size="mini"
            type="info"
            class="mr4"
          >{{ getSpecialtyLabel(item) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="能力标签" min-width="200">
        <template slot-scope="scope">
          <span v-if="!scope.row.capabilitiesArray.length" class="text-placeholder">-</span>
          <el-tag
            v-for="(item, index) in scope.row.capabilitiesArray"
            :key="index"
            size="mini"
            type="success"
            class="mr4"
          >{{ item }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="关联账号" width="180">
        <template slot-scope="scope">
          {{ formatSysUserDisplay(scope.row) }}
        </template>
      </el-table-column>
      <el-table-column label="联系方式" min-width="160">
        <template slot-scope="scope">
          <span v-if="!scope.row.contactsArray.length" class="text-placeholder">-</span>
          <el-tooltip v-else placement="top">
            <div slot="content">
              <div v-for="(item, index) in scope.row.contactsArray" :key="index">
                <strong>{{ contactTypeLabel(item.type) }}</strong>
                <span v-if="item.label">（{{ item.label }}）</span>
                ：{{ item.value }}
              </div>
            </div>
            <span>{{ scope.row.contactsArray[0].value }}</span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column label="评分" prop="rating" width="120" align="center">
        <template slot-scope="scope">
          <span class="rating-text">{{ renderRating(scope.row.rating) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="状态" prop="status" width="110" align="center">
        <template slot-scope="scope">
          <dict-tag :options="dict.type.expert_status" :value="scope.row.status" />
        </template>
      </el-table-column>
      <el-table-column label="更新时间" prop="updateTime" width="160" align="center">
        <template slot-scope="scope">
          <span>{{ parseTime(scope.row.updateTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="260" fixed="right" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-view"
            @click="handleView(scope.row)"
            v-hasPermi="['resource:expert:query']"
          >详情</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            v-hasPermi="['resource:expert:edit']"
          >编辑</el-button>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-star-off"
            @click="openRatingDialog(scope.row)"
            v-hasPermi="['resource:expert:rate']"
          >评分</el-button>
          <el-dropdown>
            <span class="el-dropdown-link">
              状态<i class="el-icon-arrow-down el-icon--right" />
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item
                v-if="scope.row.status !== 'active' && scope.row.status !== 'blacklisted'"
                v-hasPermi="['resource:expert:activate']"
                @click.native="handleActivate(scope.row)"
              >启用</el-dropdown-item>
              <el-dropdown-item
                v-if="scope.row.status !== 'inactive' && scope.row.status !== 'blacklisted'"
                v-hasPermi="['resource:expert:deactivate']"
                @click.native="handleDeactivate(scope.row)"
              >停用</el-dropdown-item>
              <el-dropdown-item
                v-if="scope.row.status !== 'blacklisted'"
                v-hasPermi="['resource:expert:blacklist']"
                @click.native="handleBlacklist(scope.row)"
              >黑名单</el-dropdown-item>
              <el-dropdown-item
                v-if="scope.row.status === 'blacklisted'"
                v-hasPermi="['resource:expert:blacklist']"
                @click.native="handleUnblacklist(scope.row)"
              >解除黑名单</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            v-hasPermi="['resource:expert:remove']"
          >删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 新增/编辑专家 -->
    <el-dialog :title="title" :visible.sync="open" width="760px" append-to-body :close-on-click-modal="false">
      <el-form ref="form" :model="form" :rules="rules" label-width="110px">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="专家姓名" prop="expertName">
              <el-input v-model="form.expertName" placeholder="请输入专家姓名" maxlength="64" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="专家编号" prop="expertCode">
              <el-input v-model="form.expertCode" placeholder="请输入专家编号" maxlength="50" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="身份证号" prop="idCard">
              <el-input v-model="form.idCard" placeholder="请输入身份证号" maxlength="18" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="所属单位" prop="organization">
              <el-input v-model="form.organization" placeholder="请输入所属单位" maxlength="200" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="联系电话" prop="phone">
              <el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="20" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="邮箱" prop="email">
              <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="100" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="关联账号" prop="sysUserId">
              <el-select
                v-model="form.sysUserId"
                placeholder="请选择系统账号"
                clearable
                filterable
                remote
                reserve-keyword
                :remote-method="searchSysUsers"
                :loading="userLoading"
                style="width: 100%"
                @focus="searchSysUsers('')"
              >
                <el-option
                  v-for="user in userOptions"
                  :key="user.value"
                  :label="user.label"
                  :value="user.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="状态" prop="status">
              <el-select v-model="form.status" placeholder="请选择状态" style="width: 100%">
                <el-option
                  v-for="dict in dict.type.expert_status"
                  :key="dict.value"
                  :label="dict.label"
                  :value="dict.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="评分" prop="rating">
              <el-rate v-model="form.rating" :max="5" show-score />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="专长领域" prop="specialties">
          <el-select
            v-model="form.specialties"
            multiple
            filterable
            allow-create
            default-first-option
            placeholder="请选择或输入专长领域"
            style="width: 100%"
            :loading="specialtyLoading"
          >
            <el-option
              v-for="item in specialtyOptions"
              :key="item.dictValue || item.value"
              :label="item.dictLabel || item.label"
              :value="item.dictValue || item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="能力标签" prop="capabilities">
          <el-select
            v-model="form.capabilities"
            multiple
            filterable
            allow-create
            default-first-option
            placeholder="请输入能力标签"
            style="width: 100%"
          >
            <el-option
              v-for="item in capabilityOptions"
              :key="item"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="联系方式">
          <div v-for="(item, index) in contactList" :key="index" class="contact-row">
            <el-select v-model="item.type" placeholder="类型" style="width: 140px">
              <el-option
                v-for="opt in contactTypeOptions"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              />
            </el-select>
            <el-input
              v-model="item.label"
              placeholder="标签"
              style="width: 160px; margin-left: 8px"
              maxlength="32"
            />
            <el-input
              v-model="item.value"
              placeholder="联系方式"
              style="width: 220px; margin-left: 8px"
              maxlength="100"
            />
            <el-button
              type="text"
              icon="el-icon-delete"
              @click="removeContactRow(index)"
              v-if="contactList.length > 1"
            />
          </div>
          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="addContactRow">新增联系方式</el-button>
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="24">
            <el-form-item label="常驻地址" prop="address">
              <div class="address-with-location">
                <el-input
                  v-model="form.address"
                  type="textarea"
                  placeholder="请使用地图选择地址"
                  maxlength="500"
                  :rows="2"
                  readonly
                />
                <div class="location-actions">
                  <span
                    v-if="form.longitude != null && form.latitude != null"
                    class="location-status"
                  >
                    已选择位置：{{ form.locationName || '未知地点' }}
                  </span>
                  <span
                    v-else
                    class="location-status is-empty"
                  >
                    未选择坐标
                  </span>
                  <el-button
                    size="mini"
                    type="primary"
                    plain
                    icon="el-icon-location"
                    @click="openLocationPicker"
                  >
                    选择位置
                  </el-button>
                </div>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入备注" maxlength="500" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 专家详情抽屉 -->
    <el-drawer
      title="专家详情"
      :visible.sync="detailVisible"
      size="480px"
      direction="rtl"
      append-to-body
    >
      <div v-if="detailData" class="detail-body">
        <el-descriptions :column="1" border size="small" label-class-name="detail-label">
          <el-descriptions-item label="专家姓名">{{ detailData.expertName }}</el-descriptions-item>
          <el-descriptions-item label="专家编号">{{ detailData.expertCode || '-' }}</el-descriptions-item>
          <el-descriptions-item label="所属单位">{{ detailData.organization || '-' }}</el-descriptions-item>
          <el-descriptions-item label="身份证号">{{ detailData.idCard || '-' }}</el-descriptions-item>
          <el-descriptions-item label="评分">{{ renderRating(detailData.rating) }}</el-descriptions-item>
          <el-descriptions-item label="状态">
            <dict-tag :options="dict.type.expert_status" :value="detailData.status" />
          </el-descriptions-item>
          <el-descriptions-item label="专长领域">
            <span v-if="!detailData.specialtiesArray.length">-</span>
            <el-tag
              v-for="(item, index) in detailData.specialtiesArray"
              :key="index"
              size="mini"
              class="mr4"
            >{{ getSpecialtyLabel(item) }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="能力标签">
            <span v-if="!detailData.capabilitiesArray.length">-</span>
            <el-tag
              v-for="(item, index) in detailData.capabilitiesArray"
              :key="index"
              size="mini"
              type="success"
              class="mr4"
            >{{ item }}</el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="电话">{{ detailData.phone || '-' }}</el-descriptions-item>
          <el-descriptions-item label="邮箱">{{ detailData.email || '-' }}</el-descriptions-item>
          <el-descriptions-item label="关联账号">
            {{ formatSysUserDisplay(detailData) }}
          </el-descriptions-item>
          <el-descriptions-item label="联系方式">
            <div v-if="detailData.contactsArray.length" class="contact-list">
              <div v-for="(item, index) in detailData.contactsArray" :key="index" class="contact-item">
                <strong>{{ contactTypeLabel(item.type) }}</strong>
                <span v-if="item.label">（{{ item.label }}）</span>
                <span>：{{ item.value }}</span>
              </div>
            </div>
            <span v-else>-</span>
          </el-descriptions-item>
          <el-descriptions-item label="备注">{{ detailData.remark || '-' }}</el-descriptions-item>
          <el-descriptions-item label="创建信息">
            <div>创建人：{{ detailData.createBy || '-' }}</div>
            <div>创建时间：{{ parseTime(detailData.createTime) || '-' }}</div>
          </el-descriptions-item>
          <el-descriptions-item label="更新信息">
            <div>更新人：{{ detailData.updateBy || '-' }}</div>
            <div>更新时间：{{ parseTime(detailData.updateTime) || '-' }}</div>
          </el-descriptions-item>
        </el-descriptions>
      </div>
      <div v-else class="detail-empty">暂无数据</div>
    </el-drawer>

    <!-- 评分对话框 -->
    <el-dialog title="专家评分" :visible.sync="ratingDialogVisible" width="380px" append-to-body :close-on-click-modal="false">
      <div class="rating-body">
        <el-rate v-model="ratingForm.rating" :max="5" show-score />
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitRating">确 定</el-button>
        <el-button @click="ratingDialogVisible = false">取 消</el-button>
      </div>
    </el-dialog>
    <LocationPickerDialog
      :visible.sync="locationPickerVisible"
      :initial-location="{
        longitude: locationPickerTarget ? locationPickerTarget.longitude : undefined,
        latitude: locationPickerTarget ? locationPickerTarget.latitude : undefined,
        locationName: locationPickerTarget ? locationPickerTarget.locationName : undefined
      }"
      @confirm="handleLocationConfirm"
    />
  </div>
</template>

<script>
import {
  listExpert,
  getExpert,
  addExpert,
  updateExpert,
  delExpert,
  activateExpert,
  deactivateExpert,
  blacklistExpert,
  unblacklistExpert,
  rateExpert,
  getSpecialtyDict
} from '@/api/resource/expert'
import { listUser, getUser } from '@/api/system/user'
import LocationPickerDialog from '@/components/location/LocationPickerDialog.vue'

export default {
  name: 'ResourceExpert',
  dicts: ['expert_status'],
  components: {
    LocationPickerDialog
  },
  data() {
    return {
      loading: false,
      showSearch: true,
      total: 0,
      expertList: [],
      title: '',
      open: false,
      detailVisible: false,
      detailData: null,
      ratingDialogVisible: false,
      ratingForm: {
        id: undefined,
        rating: 5
      },
      ids: [],
      expertNames: [],
      single: true,
      multiple: true,
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        expertName: undefined,
        expertCode: undefined,
        organization: undefined,
        status: undefined,
        specialty: undefined,
        sysUserId: undefined
      },
      form: {},
      locationPickerVisible: false,
      locationPickerTarget: null,
      rules: {
        expertName: [
          { required: true, message: '专家姓名不能为空', trigger: 'blur' },
          { min: 1, max: 64, message: '专家姓名长度需在1-64字符内', trigger: 'blur' }
        ],
        expertCode: [
          { max: 50, message: '专家编号长度不能超过50个字符', trigger: 'blur' }
        ],
        idCard: [
          {
            validator: (rule, value, callback) => {
              if (!value) {
                callback()
              } else if (/^\d{17}[\dXx]$/.test(value)) {
                callback()
              } else {
                callback(new Error('请输入正确的身份证号'))
              }
            },
            trigger: 'blur'
          }
        ],
        phone: [
          {
            validator: (rule, value, callback) => {
              if (!value) return callback()
              const phoneReg = /^((\+?\d{1,4}[\s-]?)?(\d{3,4}[\s-]?){2,3}\d{3,4})$/
              if (phoneReg.test(value)) {
                callback()
              } else {
                callback(new Error('请输入正确的联系电话'))
              }
            },
            trigger: 'blur'
          }
        ],
        email: [
          { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
        ],
        remark: [
          { max: 500, message: '备注长度不能超过500个字符', trigger: 'blur' }
        ]
      },
      specialtyOptions: [],
      specialtyLoading: false,
      capabilityOptions: ['救援调度', '风险研判', '医疗支持', '舆情分析'],
      contactList: [],
      contactTypeOptions: [
        { label: '电话', value: 'phone' },
        { label: '手机', value: 'mobile' },
        { label: '邮箱', value: 'email' },
        { label: '微信', value: 'wechat' },
        { label: '紧急联系人', value: 'emergency' }
      ],
      userOptions: [],
      userLoading: false
    }
  },
  created() {
    this.resetFormData()
    this.loadSpecialtyDict()
    this.searchSysUsers('')
    this.getList()
  },
  methods: {
    /** 查询专家列表 */
    getList() {
      this.loading = true
      const params = { ...this.queryParams }
      if (params.specialty) {
        params.specialties = params.specialty
      }
      listExpert(params).then(response => {
        const rows = response.rows || []
        this.expertList = rows.map(item => this.decorateExpert(item))
        this.total = response.total || 0
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    /** 装饰专家数据 */
    decorateExpert(data) {
      const clone = { ...data }
      clone.specialtiesArray = this.safeJsonArray(clone.specialties)
      clone.capabilitiesArray = this.safeJsonArray(clone.capabilities)
      clone.contactsArray = this.safeJsonArray(clone.contacts)
      return clone
    },
    /** 安全解析 JSON 数组 */
    safeJsonArray(val) {
      if (!val) return []
      try {
        const arr = JSON.parse(val)
        return Array.isArray(arr) ? arr : []
      } catch (e) {
        return []
      }
    },
    /** 搜索操作 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置搜索 */
    resetQuery() {
      this.resetForm('queryForm')
      this.queryParams.pageNum = 1
      this.queryParams.pageSize = 10
      this.getList()
    },
    /** 表单重置 */
    resetFormData() {
      this.form = {
        id: undefined,
        expertName: undefined,
        expertCode: undefined,
        idCard: undefined,
        organization: undefined,
        specialties: [],
        capabilities: [],
        phone: undefined,
        email: undefined,
        sysUserId: undefined,
        status: 'active',
        rating: 5,
        address: undefined,
        locationName: undefined,
        longitude: undefined,
        latitude: undefined,
        remark: undefined
      }
      this.contactList = [
        {
          type: 'phone',
          label: '办公电话',
          value: ''
        }
      ]
      this.resetForm('form')
    },
    /** 多选框操作 */
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.expertNames = selection.map(item => item.expertName)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增按钮 */
    handleAdd() {
      this.resetFormData()
      this.open = true
      this.title = '新增专家'
    },
    /** 修改按钮 */
    handleUpdate(row) {
      this.resetFormData()
      const id = (row && row.id) || this.ids[0]
      if (!id) return
      getExpert(id).then(response => {
        const data = response.data || {}
        this.form = {
          id: data.id,
          expertName: data.expertName,
          expertCode: data.expertCode,
          idCard: data.idCard,
          organization: data.organization,
          specialties: this.safeJsonArray(data.specialties),
          capabilities: this.safeJsonArray(data.capabilities),
          phone: data.phone,
          email: data.email,
          sysUserId: data.sysUserId != null ? String(data.sysUserId) : undefined,
          status: data.status || 'active',
          rating: data.rating || 5,
          address: data.address,
          locationName: data.locationName,
          longitude: data.longitude,
          latitude: data.latitude,
          remark: data.remark
        }
        const contacts = this.safeJsonArray(data.contacts)
        this.contactList = contacts.length ? contacts : [{ type: 'phone', label: '办公电话', value: '' }]
        if (data.sysUserId) {
          this.ensureUserOption(data.sysUserId)
        }
        this.open = true
        this.title = '编辑专家'
      })
    },
    /** 查看详情 */
    handleView(row) {
      getExpert(row.id).then(response => {
        this.detailData = this.decorateExpert(response.data || {})
        this.detailVisible = true
      })
    },
    /** 提交表单 */
    submitForm() {
      this.$refs['form'].validate(valid => {
        if (!valid) return
        // 处理评分：el-rate 可能返回浮点数，需要四舍五入为整数
        const rating = this.form.rating ? Math.round(this.form.rating) : null
        const payload = {
          ...this.form,
          rating: rating,
          specialties: JSON.stringify(this.form.specialties || []),
          capabilities: JSON.stringify(this.form.capabilities || []),
          contacts: JSON.stringify(this.serializeContacts()),
          sysUserId: this.form.sysUserId || null
        }
        if (payload.id) {
          updateExpert(payload).then(() => {
            this.$modal.msgSuccess('修改成功')
            this.open = false
            this.getList()
          })
        } else {
          addExpert(payload).then(() => {
            this.$modal.msgSuccess('新增成功')
            this.open = false
            this.getList()
          })
        }
      })
    },
    /** 删除 */
    handleDelete(row) {
      let ids = this.ids
      let curNames = [];
      if (row) {
        ids = row.id || this.ids;
        curNames.push(row.expertName)
      } else if (this.expertNames.length > 0) {
        curNames.push(...this.expertNames)
      }
      const quotedNames = curNames.map(item => `“${item}”`);
      const resNames = quotedNames.join('、');
      if (!ids || (Array.isArray(ids) && !ids.length)) return
      this.$modal.confirm('是否确认删除专家名称为 "' + resNames + '" 的数据项？').then(() => {
        return delExpert(ids)
      }).then(() => {
        this.getList()
        this.$modal.msgSuccess('删除成功')
      }).catch(() => {})
    },
    /** 取消 */
    cancel() {
      this.open = false
    },
    /** 加载专长字典 */
    loadSpecialtyDict() {
      this.specialtyLoading = true
      getSpecialtyDict().then(response => {
        this.specialtyOptions = response.data || []
        this.specialtyLoading = false
      }).catch(() => {
        this.specialtyLoading = false
      })
    },
    /** 启用专家 */
    handleActivate(row) {
      const id = row.id
      activateExpert(id).then(() => {
        this.$modal.msgSuccess('启用成功')
        this.getList()
      })
    },
    /** 停用专家 */
    handleDeactivate(row) {
      const id = row.id
      deactivateExpert(id).then(() => {
        this.$modal.msgSuccess('停用成功')
        this.getList()
      })
    },
    /** 黑名单 */
    handleBlacklist(row) {
      const id = row.id
      this.$modal.confirm('确定将专家 "' + row.expertName + '" 加入黑名单吗？').then(() => {
        return blacklistExpert(id)
      }).then(() => {
        this.$modal.msgSuccess('已加入黑名单')
        this.getList()
      }).catch(() => {})
    },
    /** 解除黑名单 */
    handleUnblacklist(row) {
      const id = row.id
      this.$modal.confirm('确定解除专家 "' + row.expertName + '" 的黑名单吗？解除后将恢复为停用状态。').then(() => {
        return unblacklistExpert(id)
      }).then(() => {
        this.$modal.msgSuccess('已解除黑名单')
        this.getList()
      }).catch(() => {})
    },
    /** 打开评分弹窗 */
    openRatingDialog(row) {
      this.ratingForm = {
        id: row.id,
        rating: row.rating || 5
      }
      this.ratingDialogVisible = true
    },
    /** 提交评分 */
    submitRating() {
      if (!this.ratingForm.id) return
      const rating = this.ratingForm.rating ? Math.round(this.ratingForm.rating) : 0
      if (rating < 1 || rating > 5) {
        this.$message.error('评分范围需在1-5之间')
        return
      }
      rateExpert(this.ratingForm.id, { rating }).then(() => {
        this.$modal.msgSuccess('评分成功')
        this.ratingDialogVisible = false
        this.getList()
      })
    },
    /** 新增联系方式行 */
    addContactRow() {
      if (this.contactList.length >= 10) {
        this.$message.warning('最多添加10条联系方式')
        return
      }
      this.contactList.push({ type: 'phone', label: '', value: '' })
    },
    /** 移除联系方式行 */
    removeContactRow(index) {
      if (this.contactList.length === 1) {
        this.contactList[0].value = ''
        this.contactList[0].label = ''
        return
      }
      this.contactList.splice(index, 1)
    },
    /** 序列化联系方式 */
    serializeContacts() {
      return this.contactList
        .filter(item => item && item.value)
        .map(item => ({
          type: item.type || 'other',
          label: item.label,
          value: item.value
        }))
    },
    openLocationPicker() {
      this.locationPickerTarget = {
        longitude: this.form.longitude,
        latitude: this.form.latitude,
        locationName: this.form.locationName || this.form.address
      }
      this.locationPickerVisible = true
    },
    handleLocationConfirm({ lng, lat, address }) {
      this.form.longitude = lng
      this.form.latitude = lat
      this.form.locationName = address
      if (!this.form.address) {
        this.form.address = address
      }
      this.locationPickerVisible = false
      this.locationPickerTarget = null
    },
    /** 获取专长领域中文标签 */
    getSpecialtyLabel(value) {
      if (!value) return value
      const option = this.specialtyOptions.find(item => (item.dictValue || item.value) === value)
      return option ? (option.dictLabel || option.label) : value
    },
    /** 联系方式类型文案 */
    contactTypeLabel(type) {
      const opt = this.contactTypeOptions.find(item => item.value === type)
      return opt ? opt.label : '其他'
    },
    /** 评分展示 */
    renderRating(rating) {
      if (!rating) return '未评分'
      const stars = '★★★★★☆☆☆☆☆'
      const value = Math.max(1, Math.min(5, Math.round(rating)))
      return stars.slice(0, value) + ` (${value})`
    },
    /** 远程搜索系统账号 */
    searchSysUsers(query) {
      this.userLoading = true
      const params = {
        userName: query,
        status: '0',
        pageNum: 1,
        pageSize: 20
      }
      listUser(params).then(response => {
        const rows = response.rows || []
        rows.forEach(user => {
          const option = this.buildUserOption(user)
          if (option) {
            this.upsertUserOption(option)
          }
        })
        this.userLoading = false
      }).catch(() => {
        this.userLoading = false
      })
    },
    buildUserOption(user) {
      if (!user) return null
      const name = user.nickName || user.userName || '未命名'
      const account = user.userName || user.loginName || ''
      return {
        value: String(user.userId),
        label: account ? `${name}（${account}）` : `${name}`,
        raw: user
      }
    },
    upsertUserOption(option) {
      if (!option || option.value == null) return
      const exists = this.userOptions.some(opt => String(opt.value) === String(option.value))
      if (!exists) {
        this.userOptions.push(option)
      }
    },
    ensureUserOption(userId) {
      if (!userId) return
      const exists = this.userOptions.some(opt => String(opt.value) === String(userId))
      if (!exists) {
        this.fetchUserById(userId)
      }
    },
    fetchUserById(userId) {
      getUser(userId).then(res => {
        const data = res.data
        if (data) {
          const option = this.buildUserOption({ ...data, userId: data.userId || userId })
          this.upsertUserOption(option)
        }
      })
    },
    formatSysUserDisplay(data) {
      if (!data || !data.sysUserId) {
        return '未关联'
      }
      const opt = this.userOptions.find(item => String(item.value) === String(data.sysUserId))
      return opt ? opt.label : `ID：${data.sysUserId}`
    }
  }
}
</script>

<style scoped>
.mr4 {
  margin-right: 4px;
  margin-bottom: 2px;
}

.rating-text {
  white-space: nowrap;
}

.contact-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.address-with-location {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.location-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: #909399;
}

.location-status.is-empty {
  color: #F56C6C;
}

.contact-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.contact-item {
  font-size: 13px;
}

.text-placeholder {
  color: #c0c4cc;
}

.detail-body {
  padding: 0 10px;
}

.detail-label {
  width: 120px;
}

.detail-empty {
  padding: 40px;
  text-align: center;
  color: #909399;
}

.rating-body {
  display: flex;
  justify-content: center;
  padding: 20px 0;
}

.el-dropdown-link {
  cursor: pointer;
  color: #409eff;
  margin: 0 6px;
}
</style>