<template>
  <el-dialog
    title="添加参与方"
    :visible.sync="dialogVisible"
    width="700px"
    :close-on-click-modal="false"
    append-to-body
    modal-append-to-body
    @close="handleClose"
  >
    <div class="add-participant-dialog">
      <!-- Tabs -->
      <el-tabs v-model="activeTab" @tab-click="handleTabChange">
        <el-tab-pane label="队伍成员" name="teamMembers">
          <div class="tab-content">
            <div class="search-bar">
              <el-input
                v-model="teamMemberSearch"
                placeholder="搜索队伍或成员姓名"
                prefix-icon="el-icon-search"
                clearable
              />
            </div>
            <div class="team-selector" v-if="teams.length > 0">
              <el-select
                v-model="selectedTeamId"
                placeholder="选择队伍（可选）"
                clearable
                filterable
                @change="handleTeamChange"
                style="width: 100%; margin-bottom: 12px;"
              >
                <el-option
                  v-for="team in teams"
                  :key="team.id"
                  :label="team.teamName"
                  :value="team.id"
                />
              </el-select>
            </div>
            <div class="participant-list">
              <el-table
                :data="filteredTeamMembers"
                border
                size="small"
                max-height="400px"
                @selection-change="handleTeamMemberSelectionChange"
                :row-class-name="getTeamMemberRowClassName"
              >
                <el-table-column type="selection" width="55" :selectable="isTeamMemberSelectable" />
                <el-table-column prop="memberName" label="姓名" width="120">
                  <template slot-scope="scope">
                    {{ scope.row.memberName || scope.row.name || '-' }}
                  </template>
                </el-table-column>
                <el-table-column prop="teamName" label="所属队伍" width="150" />
                <el-table-column prop="position" label="角色" width="100">
                  <template slot-scope="scope">
                    {{ scope.row.position || scope.row.role || '-' }}
                  </template>
                </el-table-column>
                <el-table-column prop="teamLocation" label="位置" min-width="150">
                  <template slot-scope="scope">
                    {{ scope.row.teamLocation || '-' }}
                  </template>
                </el-table-column>
                <el-table-column prop="distance" label="距离" width="100" v-if="eventLocation">
                  <template slot-scope="scope">
                    {{ getDistanceToEvent(scope.row) }}
                  </template>
                </el-table-column>
                <el-table-column prop="phone" label="联系方式" min-width="120">
                  <template slot-scope="scope">
                    {{ scope.row.phone || scope.row.telephone || scope.row.contact || '-' }}
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </el-tab-pane>
        
        <el-tab-pane label="专家" name="experts">
          <div class="tab-content">
            <div class="search-bar">
              <el-input
                v-model="expertSearch"
                placeholder="搜索专家姓名或专长"
                prefix-icon="el-icon-search"
                clearable
              />
            </div>
            <div class="participant-list">
              <el-table
                :data="filteredExperts"
                border
                size="small"
                max-height="400px"
                @selection-change="handleExpertSelectionChange"
                :row-class-name="getExpertRowClassName"
              >
                <el-table-column type="selection" width="55" :selectable="isExpertSelectable" />
                <el-table-column prop="expertName" label="姓名" width="120">
                  <template slot-scope="scope">
                    {{ scope.row.expertName || scope.row.name || '-' }}
                  </template>
                </el-table-column>
                <el-table-column prop="role" label="角色" width="100">
                  <template slot-scope="scope">
                    专家
                  </template>
                </el-table-column>
                <el-table-column prop="distance" label="距离" width="100" v-if="eventLocation">
                  <template slot-scope="scope">
                    {{ getExpertDistanceToEvent(scope.row) }}
                  </template>
                </el-table-column>
                <el-table-column prop="specialty" label="专长" min-width="150">
                  <template slot-scope="scope">
                    <el-tag
                      v-for="(spec, idx) in getExpertSpecialties(scope.row)"
                      :key="idx"
                      size="mini"
                      style="margin-right: 4px;"
                    >
                      {{ spec }}
                    </el-tag>
                  </template>
                </el-table-column>
                <el-table-column prop="contact" label="联系方式" min-width="120">
                  <template slot-scope="scope">
                    {{ getExpertContact(scope.row) }}
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
      
      <div class="selection-summary" v-if="selectedCount > 0">
        已选择: <strong>{{ selectedCount }}</strong> 人
      </div>
    </div>
    
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取消</el-button>
      <el-button
        type="primary"
        :disabled="selectedCount === 0"
        :loading="submitting"
        @click="handleSubmit"
      >
        确定添加
      </el-button>
    </div>
  </el-dialog>
</template>

<script>
import { listTeam, listTeamMember, getTeamMember } from '@/api/resource/team'
import { listExpert, getExpert } from '@/api/resource/expert'
import { addDispatchParticipants, getDispatchTask } from '@/api/emergency/dispatchTask'
import { getEvent } from '@/api/emergency/event'

export default {
  name: 'AddParticipantDialog',
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    taskId: {
      type: [Number, String],
      required: true
    },
    existingParticipants: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      activeTab: 'teamMembers',
      // Team members
      teams: [],
      teamMembers: [],
      filteredTeamMembers: [],
      selectedTeamId: null,
      teamMemberSearch: '',
      selectedTeamMembers: [],
      // Experts
      experts: [],
      filteredExperts: [],
      expertSearch: '',
      selectedExperts: [],
      // Loading states
      loadingTeams: false,
      loadingTeamMembers: false,
      loadingExperts: false,
      submitting: false,
      // Event location for distance calculation
      eventLocation: null
    }
  },
  computed: {
    selectedCount() {
      return this.selectedTeamMembers.length + this.selectedExperts.length
    },
    dialogVisible: {
      get() {
        return this.visible
      },
      set(value) {
        this.$emit('update:visible', value)
      }
    }
  },
  watch: {
    visible(newVal) {
      if (newVal) {
        this.reset()
        this.loadData()
      }
    },
    teamMemberSearch() {
      this.filterTeamMembers()
    },
    expertSearch() {
      this.filterExperts()
    }
  },
  methods: {
    reset() {
      this.activeTab = 'teamMembers'
      this.selectedTeamId = null
      this.teamMemberSearch = ''
      this.expertSearch = ''
      this.selectedTeamMembers = []
      this.selectedExperts = []
      this.teams = []
      this.teamMembers = []
      this.experts = []
      this.eventLocation = null
    },
    async loadData() {
      // Load event location first for distance calculation
      await this.loadEventLocation()
      // Load teams first, then team members (which depends on teams)
      await this.loadTeams()
      await Promise.all([
        this.loadTeamMembers(),  // Now teams is guaranteed to be loaded
        this.loadExperts()
      ])
    },
    async loadEventLocation() {
      if (!this.taskId) return
      try {
        const taskRes = await getDispatchTask(this.taskId)
        if (taskRes && taskRes.code === 200 && taskRes.data && taskRes.data.eventId) {
          const eventRes = await getEvent(taskRes.data.eventId)
          if (eventRes && eventRes.code === 200 && eventRes.data) {
            const event = eventRes.data
            if (event.latitude && event.longitude) {
              this.eventLocation = {
                lat: parseFloat(event.latitude),
                lng: parseFloat(event.longitude)
              }
            }
          }
        }
      } catch (error) {
        console.warn('加载事件位置失败，无法计算距离:', error)
      }
    },
    async loadTeams() {
      this.loadingTeams = true
      try {
        const res = await listTeam({ pageNum: 1, pageSize: 1000 })
        if (res && res.code === 200) {
          this.teams = res.rows || []
        }
      } catch (error) {
        console.error('加载队伍列表失败:', error)
        this.$message.error('加载队伍列表失败')
      } finally {
        this.loadingTeams = false
      }
    },
    async loadTeamMembers() {
      this.loadingTeamMembers = true
      try {
        // Load all team members from all teams
        const allMembers = []
        for (const team of this.teams) {
          try {
            const res = await listTeamMember(team.id, { pageNum: 1, pageSize: 100 })
            if (res && res.code === 200 && res.rows) {
              res.rows.forEach(member => {
                allMembers.push({
                  ...member,
                  teamId: team.id,
                  teamName: team.teamName,
                  teamLocation: team.locationName || team.contactAddress || '-',
                  teamLatitude: team.latitude ? parseFloat(team.latitude) : null,
                  teamLongitude: team.longitude ? parseFloat(team.longitude) : null
                })
              })
            }
          } catch (error) {
            console.warn(`加载队伍 ${team.teamName} 成员失败:`, error)
          }
        }
        this.teamMembers = allMembers
        this.filteredTeamMembers = this.filterTeamMembers(allMembers)
      } catch (error) {
        console.error('加载队伍成员失败:', error)
        this.$message.error('加载队伍成员失败')
      } finally {
        this.loadingTeamMembers = false
      }
    },
    async loadExperts() {
      this.loadingExperts = true
      try {
        const res = await listExpert({ pageNum: 1, pageSize: 1000 })
        if (res && res.code === 200) {
          this.experts = res.rows || []
          this.filteredExperts = this.filterExperts(this.experts)
        }
      } catch (error) {
        console.error('加载专家列表失败:', error)
        this.$message.error('加载专家列表失败')
      } finally {
        this.loadingExperts = false
      }
    },
    handleTabChange() {
      // Reset selections when switching tabs
      this.selectedTeamMembers = []
      this.selectedExperts = []
    },
    handleTeamChange() {
      this.filterTeamMembers()
    },
    filterTeamMembers(members = null) {
      const source = members || this.teamMembers
      let filtered = source
      
      // Filter by selected team
      if (this.selectedTeamId) {
        filtered = filtered.filter(m => m.teamId === this.selectedTeamId)
      }
      
      // Filter by search
      if (this.teamMemberSearch) {
        const search = this.teamMemberSearch.toLowerCase()
        filtered = filtered.filter(m => {
          const name = (m.memberName || m.name || '').toLowerCase()
          const teamName = (m.teamName || '').toLowerCase()
          return name.includes(search) || teamName.includes(search)
        })
      }
      
      // Mark existing participants as disabled
      filtered = filtered.map(member => {
        const exists = this.existingParticipants.some(
          p => p.personId === member.id && p.teamId === member.teamId
        )
        return {
          ...member,
          disabled: exists
        }
      })
      
      this.filteredTeamMembers = filtered
      return filtered
    },
    filterExperts(experts = null) {
      const source = experts || this.experts
      let filtered = source
      
      // Filter by search
      if (this.expertSearch) {
        const search = this.expertSearch.toLowerCase()
        filtered = filtered.filter(e => {
          const name = (e.expertName || e.name || '').toLowerCase()
          const specialties = this.getExpertSpecialties(e).join(' ').toLowerCase()
          return name.includes(search) || specialties.includes(search)
        })
      }
      
      // Mark existing participants as disabled
      filtered = filtered.map(expert => {
        const exists = this.existingParticipants.some(
          p => p.personId === expert.id && !p.teamId
        )
        return {
          ...expert,
          disabled: exists
        }
      })
      
      this.filteredExperts = filtered
      return filtered
    },
    isTeamMemberSelectable(row) {
      return !row.disabled
    },
    isExpertSelectable(row) {
      return !row.disabled
    },
    getTeamMemberRowClassName({ row }) {
      return row.disabled ? 'disabled-row' : ''
    },
    getExpertRowClassName({ row }) {
      return row.disabled ? 'disabled-row' : ''
    },
    handleTeamMemberSelectionChange(selection) {
      // Filter out disabled items
      this.selectedTeamMembers = selection.filter(item => !item.disabled)
    },
    handleExpertSelectionChange(selection) {
      // Filter out disabled items
      this.selectedExperts = selection.filter(item => !item.disabled)
    },
    getExpertSpecialties(expert) {
      if (!expert.specialties) return []
      try {
        return typeof expert.specialties === 'string'
          ? JSON.parse(expert.specialties)
          : expert.specialties
      } catch {
        return []
      }
    },
    getExpertContact(expert) {
      if (!expert.contacts) return '-'
      try {
        const contacts = typeof expert.contacts === 'string'
          ? JSON.parse(expert.contacts)
          : expert.contacts
        if (Array.isArray(contacts) && contacts.length > 0) {
          return contacts[0].phone || contacts[0].telephone || '-'
        }
      } catch {
        return expert.phone || expert.telephone || '-'
      }
      return expert.phone || expert.telephone || '-'
    },
    calculateDistance(lat1, lon1, lat2, lon2) {
      if (!lat1 || !lon1 || !lat2 || !lon2) return null
      
      const R = 6371 // Earth's radius in km
      const dLat = (lat2 - lat1) * Math.PI / 180
      const dLon = (lon2 - lon1) * Math.PI / 180
      const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
                Math.sin(dLon / 2) * Math.sin(dLon / 2)
      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
      return R * c
    },
    getDistanceToEvent(member) {
      if (!this.eventLocation || !member.teamLatitude || !member.teamLongitude) {
        return '-'
      }
      const distance = this.calculateDistance(
        member.teamLatitude,
        member.teamLongitude,
        this.eventLocation.lat,
        this.eventLocation.lng
      )
      if (distance === null) return '-'
      
      if (distance < 1) {
        return `${(distance * 1000).toFixed(0)}m`
      } else {
        return `${distance.toFixed(1)}km`
      }
    },
    getExpertDistanceToEvent(expert) {
      if (!this.eventLocation || !expert.latitude || !expert.longitude) {
        return '-'
      }
      const distance = this.calculateDistance(
        parseFloat(expert.latitude),
        parseFloat(expert.longitude),
        this.eventLocation.lat,
        this.eventLocation.lng
      )
      if (distance === null) return '-'
      
      if (distance < 1) {
        return `${(distance * 1000).toFixed(0)}m`
      } else {
        return `${distance.toFixed(1)}km`
      }
    },
    async buildParticipantSnapshot(person, type) {
      // Fetch full details to create snapshot
      let fullDetails = person
      
      if (type === 'teamMember') {
        try {
          const res = await getTeamMember(person.teamId, person.id)
          if (res && res.code === 200) {
            fullDetails = res.data || person
            // Preserve team coordinates from the member object
            if (person.teamLatitude !== undefined) {
              fullDetails.teamLatitude = person.teamLatitude
            }
            if (person.teamLongitude !== undefined) {
              fullDetails.teamLongitude = person.teamLongitude
            }
            if (person.teamName) {
              fullDetails.teamName = person.teamName
            }
          }
        } catch (error) {
          console.warn('获取成员详情失败，使用已有数据:', error)
        }
      } else if (type === 'expert') {
        try {
          const res = await getExpert(person.id)
          if (res && res.code === 200) {
            fullDetails = res.data || person
          }
        } catch (error) {
          console.warn('获取专家详情失败，使用已有数据:', error)
        }
      }
      
      // Build snapshot JSON
      const snapshot = {
        name: type === 'teamMember' 
          ? (fullDetails.memberName || fullDetails.name || '-')
          : (fullDetails.expertName || fullDetails.name || fullDetails.personName || '-'),
        phone: fullDetails.phone || fullDetails.telephone || fullDetails.contact || '-',
        unit: type === 'teamMember' ? fullDetails.teamName : (fullDetails.unit || fullDetails.organization || '-'),
        role: type === 'teamMember'
          ? (fullDetails.position || fullDetails.role || '-')
          : '专家',
        position: type === 'teamMember'
          ? (fullDetails.position || fullDetails.role || '-')
          : '专家',
        specialty: type === 'expert' ? this.getExpertSpecialties(fullDetails) : (fullDetails.specialty || []),
        equipment: fullDetails.equipment || [],
        // Store team coordinates for distance calculation
        teamLatitude: type === 'teamMember' ? (fullDetails.teamLatitude || null) : null,
        teamLongitude: type === 'teamMember' ? (fullDetails.teamLongitude || null) : null,
        // Store expert coordinates for distance calculation
        expertLatitude: type === 'expert' ? (fullDetails.latitude ? parseFloat(fullDetails.latitude) : null) : null,
        expertLongitude: type === 'expert' ? (fullDetails.longitude ? parseFloat(fullDetails.longitude) : null) : null
      }
      
      return JSON.stringify(snapshot)
    },
    async handleSubmit() {
      if (this.selectedCount === 0) {
        this.$message.warning('请至少选择一个参与方')
        return
      }
      
      this.submitting = true
      try {
        const participants = []
        
        // Process team members
        for (const member of this.selectedTeamMembers) {
          const snapshot = await this.buildParticipantSnapshot(member, 'teamMember')
          participants.push({
            personId: member.id,
            teamId: member.teamId,
            personSnapshot: snapshot
          })
        }
        
        // Process experts
        for (const expert of this.selectedExperts) {
          const snapshot = await this.buildParticipantSnapshot(expert, 'expert')
          participants.push({
            personId: expert.id,
            teamId: null, // Experts don't have teamId
            personSnapshot: snapshot
          })
        }
        
        const res = await addDispatchParticipants(this.taskId, participants)
        if (res && res.code === 200) {
          this.$message.success(`已添加 ${participants.length} 名参与方`)
          this.$emit('success', participants)
          this.handleClose()
        } else {
          this.$message.error(res.msg || '添加参与方失败')
        }
      } catch (error) {
        console.error('添加参与方失败:', error)
        this.$message.error('添加参与方失败，请稍后重试')
      } finally {
        this.submitting = false
      }
    },
    handleClose() {
      this.$emit('update:visible', false)
      this.$emit('close')
    }
  }
}
</script>

<style lang="scss" scoped>
.add-participant-dialog {
  .tab-content {
    padding: 12px 0;
  }
  
  .search-bar {
    margin-bottom: 12px;
  }
  
  .team-selector {
    margin-bottom: 12px;
  }
  
  .participant-list {
    margin-top: 12px;
  }
  
  .selection-summary {
    margin-top: 16px;
    padding: 8px 12px;
    background: #f5f7fa;
    border-radius: 4px;
    text-align: right;
    font-size: 13px;
    color: #606266;
    
    strong {
      color: #409eff;
      font-weight: 600;
    }
  }
}

::v-deep .el-table {
  .disabled-row {
    color: #c0c4cc;
    background-color: #f5f7fa;
    cursor: not-allowed;
    
    .el-checkbox__input {
      cursor: not-allowed;
      opacity: 0.5;
    }
  }
}
</style>