<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { todayStr } from '@/utils'
import api from '@/api/index'
import { compressImage } from '@/utils/image'
import ImagePreview from '@/components/ImagePreview.vue'
import EditLogPanel from '@/components/EditLogPanel.vue'
import { useAuthStore } from '@/stores/auth'

const auth = useAuthStore()
const activeTab = ref('visits')
const loading = ref(false)
const allManagers = ref<any[]>([])

// Date range filter
const dateFrom = ref('')
const dateTo = ref('')
const searchText = ref('')
const pageSize = ref(25)

const visits = ref<any[]>([])
const workPlans = ref<any[]>([])
const miniBusiness = ref<any[]>([])
const dailyNotes = ref<any[]>([])
const keyVisits = ref<any[]>([])

// Pagination per tab
const page = ref<Record<string, number>>({ visits: 1, notes: 1, plans: 1, mini: 1, key: 1 })
const total = ref<Record<string, number>>({ visits: 0, notes: 0, plans: 0, mini: 0, key: 0 })

function getDateRange() {
  return { from: dateFrom.value, to: dateTo.value }
}
const customers = ref<any[]>([])
const allUsers = ref<any[]>([])
const plannedVisitors = ref<string[]>([])
const dialogTimeRange = ref<any>(null)
const previewImageUrl = ref('')
const uploading = ref(false)
const previewDialogVisible = ref(false)
const photoUrls = ref<Record<string, string>>({})

const dialogVisible = ref(false)
const dialogMode = ref<'create' | 'edit'>('create')
const dialogType = ref('')
const form = ref<any>({})

const categories = ['行政事务', '合同整理', '发票处理', '内部会议', '培训学习', '其他']

const statusPick = ref<Record<string, string>>({})

const planStatuses = ['计划中', '已完成', '已取消']
const miniStatuses = ['跟进中', '已签约', '已流失']
const keyStatuses = ['未开始', '进行中', '已完成']

onMounted(async () => {
  await Promise.all([loadAll(), loadCustomers(), loadUsers()])
  if (auth.isDirector || auth.isLeader) {
    api.get('/users/', { params: { role: 'manager' } }).then(r => { allManagers.value = r.data }).catch(() => {})
  }
})

async function loadUsers() {
  try {
    const res = await api.get('/users/')
    allUsers.value = res.data || []
  } catch (_) {}
}

function typeLabel(t: string) {
  const labels: Record<string, string> = { visit: '拜访记录', note: '今日纪要', plan: '工作计划', mini: '小微商机', key: '要客拜访' }
  return labels[t] || ''
}

const customerSearch = ref('')

async function loadCustomers(q?: string) {
  try {
    const params: any = { page_size: 100 }
    if (q) params.search = q
    const res = await api.get('/customers/', { params })
    customers.value = res.data.items || []
  } catch (_) {}
}

async function handleCustomerSearch(query: string) {
  customerSearch.value = query
  if (query) { await loadCustomers(query) }
  else { await loadCustomers() }
}

async function handleQuickCreate() {
  const name = customerSearch.value.trim()
  if (!name) { ElMessage.warning('请输入单位名称'); return }
  try {
    const res = await api.post('/customers/quick-create', null, { params: { name } })
    const newCust = res.data
    customers.value.unshift(newCust)
    form.value.customer_id = newCust.id
    customerSearch.value = ''
    ElMessage.success(`已创建客户：${name}`)
    await loadCustomers()
  } catch (e: any) {
    ElMessage.error('创建失败: ' + (e.response?.data?.detail || e.message))
  }
}

function buildParams(tabKey: string) {
  const { from, to } = getDateRange()
  const params: any = { page: page.value[tabKey] || 1, page_size: pageSize.value }
  if (from) { params.date_from = from; params.date_to = to }
  if (searchText.value) params.search = searchText.value
  return params
}

async function loadAll() {
  loading.value = true
  try {
    const [v, d] = await Promise.all([
      api.get('/visits/', { params: buildParams('visits') }),
      api.get('/daily-notes/', { params: buildParams('notes') }),
    ])
    visits.value = Array.isArray(v.data) ? v.data : (v.data.items || [])
    dailyNotes.value = Array.isArray(d.data) ? d.data : (d.data.items || [])
    total.value.visits = v.data.total || visits.value.length
    total.value.notes = d.data.total || dailyNotes.value.length

    const [w, m, k] = await Promise.all([
      api.get('/work-plans/', { params: buildParams('plans') }),
      api.get('/mini-business/', { params: buildParams('mini') }),
      api.get('/key-visits/', { params: buildParams('key') }),
    ])
    workPlans.value = Array.isArray(w.data) ? w.data : (w.data.items || [])
    miniBusiness.value = Array.isArray(m.data) ? m.data : (m.data.items || [])
    keyVisits.value = Array.isArray(k.data) ? k.data : (k.data.items || [])
    total.value.plans = w.data.total || workPlans.value.length
    total.value.mini = m.data.total || miniBusiness.value.length
    total.value.key = k.data.total || keyVisits.value.length

    // Load photo previews for visits
    for (const visit of visits.value) {
      if (visit.photos?.length) {
        for (const key of visit.photos) {
          if (!photoUrls.value[key]) {
            try {
              const urlRes = await api.get('/upload/download-url', { params: { object_key: key } })
              photoUrls.value[key] = urlRes.data.download_url
            } catch (_) {}
          }
        }
      }
    }
  } catch (e: any) { ElMessage.error('加载失败') }
  finally { loading.value = false }
}

function onTabChange(tab: string) { activeTab.value = tab; loadAll() }
function onFilterChange() { Object.keys(page.value).forEach(k => page.value[k] = 1); loadAll() }
function onPageChange(tabKey: string, p: number) { page.value[tabKey] = p; loadAll() }
function onSizeChange() { Object.keys(page.value).forEach(k => page.value[k] = 1); loadAll() }

function openCreate(type: string) {
  dialogMode.value = 'create'; dialogType.value = type
  dialogTimeRange.value = null
  if (type === 'visit') form.value = { customer_id: '', visit_date: todayStr(), visit_method: '上门', time_range: '', visitor_name: '', visitor_phone: '', communication_content: '', customer_demand: '', companions: [], companion_names: [], manager_id: (auth.isDirector || auth.isLeader) ? '' : (auth.userId || '') }
  else if (type === 'note') form.value = { note_date: todayStr(), category: '其他', content: '', time_range: '', manager_id: (auth.isDirector || auth.isLeader) ? '' : (auth.userId || '') }
  else if (type === 'plan') form.value = { customer_id: '', plan_content: '', plan_date: todayStr(), status: '计划中', manager_id: (auth.isDirector || auth.isLeader) ? '' : (auth.userId || '') }
  else if (type === 'mini') form.value = { customer_id: '', product_type: '', amount: '', follow_up_detail: '', status: '跟进中', expected_revenue_date: '', manager_id: (auth.isDirector || auth.isLeader) ? '' : (auth.userId || '') }
  else if (type === 'key') { form.value = { customer_id: '', urgency_level: '一般', description: '', progress_status: '未开始', planned_date: '', planned_visitor: '', visit_target: '', manager_id: (auth.isDirector || auth.isLeader) ? '' : (auth.userId || '') }; plannedVisitors.value = [] }
  dialogVisible.value = true
}

function openEdit(type: string, item: any) {
  dialogMode.value = 'edit'; dialogType.value = type
  form.value = { ...item }
  if (item.customer_id && item.customer_name && !customers.value.find((c: any) => c.id === item.customer_id)) {
    customers.value.unshift({ id: item.customer_id, name: item.customer_name })
  }
  dialogTimeRange.value = null
  if ((type === 'visit' || type === 'note') && item.time_range && item.time_range.includes('-')) {
    const parts = item.time_range.split('-')
    dialogTimeRange.value = [parts[0], parts[1]]
  }
  if (type === 'key') {
    plannedVisitors.value = item.planned_visitor ? item.planned_visitor.split('、') : []
  }
  // Load photo URLs for visit editing
  if (type === 'visit' && item.photos?.length) {
    for (const key of item.photos) {
      if (!photoUrls.value[key]) {
        api.get('/upload/download-url', { params: { object_key: key } }).then(r => {
          photoUrls.value[key] = r.data.download_url
        }).catch(() => {})
      }
    }
  }
  dialogVisible.value = true
}

function previewPhoto(url: string) { previewImageUrl.value = url; previewDialogVisible.value = true }

async function handleDialogPhotoUpload(event: Event) {
  const target = event.target as HTMLInputElement
  if (!target.files?.length) return
  if ((form.value.photos || []).length >= 9) { ElMessage.warning('最多9张照片'); return }
  uploading.value = true
  for (const file of Array.from(target.files)) {
    if ((form.value.photos || []).length >= 9) break
    try {
      // Compress before upload to reduce storage & transfer
      const compressed = await compressImage(file, { maxPixels: 1920, quality: 0.8 })
      // Get presigned URL
      const presignRes = await api.post('/upload/presigned-url', null, { params: { filename: compressed.name, content_type: compressed.type || 'image/jpeg' } })
      // Upload directly to MinIO (not through our API)
      const axios = (await import('axios')).default
      await axios.put(presignRes.data.upload_url, compressed, { headers: { 'Content-Type': compressed.type || 'image/jpeg' } })
      const key = presignRes.data.object_key
      if (!form.value.photos) form.value.photos = []
      form.value.photos.push(key)
      form.value.photos = [...form.value.photos]
      // Load preview
      try {
        const urlRes = await api.get('/upload/download-url', { params: { object_key: key } })
        photoUrls.value[key] = urlRes.data.download_url
      } catch (_) {}
    } catch (e: any) {
      ElMessage.error('上传失败: ' + (e.response?.data?.detail || e.message))
    }
  }
  uploading.value = false
  target.value = ''
}

function removePhotoFromEdit(idx: number) {
  if (!form.value.photos) return
  const key = form.value.photos[idx]
  form.value.photos.splice(idx, 1)
  form.value.photos = [...form.value.photos]
  // Clean up preview URL
  if (photoUrls.value[key]) {
    delete photoUrls.value[key]
  }
}

function splitCompanions(values: string[]) {
  const uuidRe = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
  const sys: string[] = []; const ext: string[] = []
  for (const v of (values || [])) {
    if (uuidRe.test(v)) sys.push(v)
    else if (v.trim()) ext.push(v.trim())
  }
  return { companions: sys, companion_names: ext }
}

async function handleSave() {
  const t = dialogType.value; let d = { ...form.value }
  // Split companions for visit type
  if (t === 'visit' && d.companions) {
    const { companions, companion_names } = splitCompanions(d.companions)
    d = { ...d, companions, companion_names }
  }
  try {
    if (dialogMode.value === 'create') {
      switch (t) {
        case 'visit': await api.post('/visits/', d); break
        case 'note': await api.post('/daily-notes/', d); break
        case 'plan': await api.post('/work-plans/', d); break
        case 'mini': await api.post('/mini-business/', d); break
        case 'key': await api.post('/key-visits/', d); break
      }
    } else {
      switch (t) {
        case 'visit': await api.put(`/visits/${d.id}`, d); break
        case 'note': await api.put(`/daily-notes/${d.id}`, d); break
        case 'plan': await api.put(`/work-plans/${d.id}`, d); break
        case 'mini': await api.put(`/mini-business/${d.id}`, d); break
        case 'key': await api.put(`/key-visits/${d.id}`, d); break
      }
    }
    ElMessage.success(dialogMode.value === 'create' ? '已创建' : '已更新')
    dialogVisible.value = false
    await loadAll()
  } catch (e: any) { ElMessage.error('保存失败: ' + (e.response?.data?.detail || e.message)) }
}

async function handleDelete(type: string, id: string) {
  try {
    await ElMessageBox.confirm('确定删除？', '确认', { type: 'warning' })
    switch (type) {
      case 'visit': await api.delete(`/visits/${id}`); break
      case 'note': await api.delete(`/daily-notes/${id}`); break
      case 'plan': await api.delete(`/work-plans/${id}`); break
      case 'mini': await api.delete(`/mini-business/${id}`); break
      case 'key': await api.delete(`/key-visits/${id}`); break
    }
    ElMessage.success('已删除')
    await loadAll()
  } catch (e: any) { if (e !== 'cancel') ElMessage.error('删除失败') }
}

function onVisitorsChange(val: string[]) {
  form.value.planned_visitor = val.join('、')
}

function onDialogTimeChange(val: [string, string] | null) {
  form.value.time_range = val ? val.join('-') : ''
}

// Quick status change
async function quickStatusChange(type: string, row: any, newStatus: string) {
  try {
    await ElMessageBox.confirm(`确定将状态改为「${newStatus}」？`, '确认', { type: 'warning', confirmButtonText: '确定', cancelButtonText: '取消' })
    const payload: any = {}
    if (type === 'plan') payload.status = newStatus
    else if (type === 'mini') payload.status = newStatus
    else if (type === 'key') payload.progress_status = newStatus
    let url = ''
    if (type === 'plan') url = `/work-plans/${row.id}`
    else if (type === 'mini') url = `/mini-business/${row.id}`
    else if (type === 'key') url = `/key-visits/${row.id}`
    await api.put(url, payload)
    ElMessage.success('状态已更新')
    await loadAll()
  } catch (e: any) {
    if (e !== 'cancel') ElMessage.error('更新失败: ' + (e.response?.data?.detail || e.message))
    // Reset statusPick back to original on cancel/error
    delete statusPick.value[row.id]
  }
}

const visitsByDate = computed(() => {
  const g: Record<string, any[]> = {}
  for (const v of visits.value) { const d = v.visit_date; if (!g[d]) g[d] = []; g[d].push(v) }
  return Object.entries(g).sort((a, b) => b[0].localeCompare(a[0]))
})
const notesByDate = computed(() => {
  const g: Record<string, any[]> = {}
  for (const n of dailyNotes.value) { const d = n.note_date; if (!g[d]) g[d] = []; g[d].push(n) }
  return Object.entries(g).sort((a, b) => b[0].localeCompare(a[0]))
})
</script>

<template>
  <div class="workspace" v-loading="loading">
    <div class="page-head">
      <h2 class="page-title">我的工作数据</h2>
      <div class="page-rule"></div>
    </div>

    <!-- Filter Bar -->
    <div class="filter-bar">
      <div class="filter-row">
        <el-date-picker v-model="dateFrom" type="month" placeholder="开始月份" size="small" style="width:140px" value-format="YYYY-MM-DD" @change="onFilterChange" />
        <span style="color:var(--warm-gray);font-size:13px">至</span>
        <el-date-picker v-model="dateTo" type="month" placeholder="结束月份" size="small" style="width:140px" value-format="YYYY-MM-DD" @change="onFilterChange" />
        <el-button v-if="dateFrom || dateTo" size="small" @click="dateFrom='';dateTo='';onFilterChange()">清除</el-button>
        <el-input v-model="searchText" placeholder="搜索..." clearable size="small" style="width:180px" @keyup.enter="onFilterChange" @clear="onFilterChange" />
        <el-button type="primary" size="small" @click="openCreate(activeTab === 'notes' ? 'note' : activeTab === 'plans' ? 'plan' : activeTab === 'mini' ? 'mini' : activeTab === 'key' ? 'key' : 'visit')" style="margin-left:auto">+ 新建</el-button>
      </div>
    </div>

    <el-card>
      <el-tabs v-model="activeTab" @tab-change="onTabChange">
        <!-- ═══ 拜访记录 ═══ -->
        <el-tab-pane label="拜访记录" name="visits">
<div v-for="[date, items] in visitsByDate" :key="date" class="date-group">
            <h4 class="date-title">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right:4px; color: var(--gold)">
                <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line>
              </svg>
              {{ date }}
            </h4>
            <el-table :data="items" stripe size="small" v-column-resize>
              <el-table-column prop="customer_name" label="客户" width="130">
                <template #default="{ row }"><el-link type="primary" :underline="false" @click="openEdit('visit', row)">{{ row.customer_name }}</el-link></template>
              </el-table-column>
              <el-table-column prop="visit_method" label="方式" width="60" />
              <el-table-column prop="time_range" label="时间" width="100" />
              <el-table-column label="照片" width="60">
                <template #default="{ row }">
                  <span v-if="row.photos?.length">📷{{ row.photos.length }}</span>
                  <span v-else style="color:var(--c-text-muted)">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="communication_content" label="沟通内容" min-width="200" show-overflow-tooltip />
              <el-table-column label="操作" width="70">
                <template #default="{ row }">
                  <el-button size="small" type="danger" @click="handleDelete('visit', row.id)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
          <div v-if="!visits.length" class="empty">暂无数据</div>
        </el-tab-pane>

        <!-- ═══ 今日纪要 ═══ -->
        <el-tab-pane label="今日纪要" name="daily_notes">
          <div v-for="[date, items] in notesByDate" :key="date" class="date-group">
            <h4 class="date-title">
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right:4px; color: var(--gold)">
                <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line>
              </svg>
              {{ date }}
            </h4>
            <el-table :data="items" stripe size="small" v-column-resize>
              <el-table-column prop="category" label="分类" width="100"><template #default="{ row }"><el-tag size="small">{{ row.category }}</el-tag></template></el-table-column>
              <el-table-column prop="content" label="工作内容" min-width="250" show-overflow-tooltip>
                <template #default="{ row }"><el-link type="primary" :underline="false" @click="openEdit('note', row)">{{ row.content }}</el-link></template>
              </el-table-column>
              <el-table-column prop="time_range" label="时间" width="100" />
              <el-table-column label="操作" width="70">
                <template #default="{ row }">
                  <el-button size="small" type="danger" @click="handleDelete('note', row.id)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </div>
          <div v-if="!dailyNotes.length" class="empty">暂无数据</div>
        </el-tab-pane>

        <!-- ═══ 工作计划 ═══ -->
        <el-tab-pane label="工作计划" name="work_plans">
          <el-table :data="workPlans" stripe size="small" v-column-resize>
            <el-table-column prop="customer_name" label="客户" width="130">
              <template #default="{ row }"><el-link type="primary" :underline="false" @click="openEdit('plan', row)">{{ row.customer_name }}</el-link></template>
            </el-table-column>
            <el-table-column prop="plan_content" label="工作计划" min-width="200" show-overflow-tooltip />
            <el-table-column prop="plan_date" label="计划时间" width="110" />
            <el-table-column label="状态" width="120">
              <template #default="{ row }">
                <el-select
                  v-model="statusPick[row.id]"
                  size="small"
                  style="width:100%"
                  :placeholder="row.status"
                  @change="(v: string) => quickStatusChange('plan', row, v)"
                  @visible-change="(v: boolean) => { if (v) statusPick[row.id] = row.status }"
                >
                  <el-option v-for="s in planStatuses" :key="s" :label="s" :value="s" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="70">
              <template #default="{ row }">
                <el-button size="small" type="danger" @click="handleDelete('plan', row.id)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
          <div v-if="!workPlans.length" class="empty">暂无数据</div>
        </el-tab-pane>

        <!-- ═══ 小微商机 ═══ -->
        <el-tab-pane label="小微商机" name="mini_biz">
          <el-table :data="miniBusiness" stripe size="small" v-column-resize>
            <el-table-column prop="customer_name" label="客户" width="130">
              <template #default="{ row }"><el-link type="primary" :underline="false" @click="openEdit('mini', row)">{{ row.customer_name }}</el-link></template>
            </el-table-column>
            <el-table-column prop="product_type" label="产品类型" width="120" />
            <el-table-column prop="amount" label="金额" width="90" />
            <el-table-column prop="follow_up_detail" label="跟进内容" min-width="200" show-overflow-tooltip />
            <el-table-column label="状态" width="120">
              <template #default="{ row }">
                <el-select
                  v-model="statusPick[row.id]"
                  size="small"
                  style="width:100%"
                  :placeholder="row.status"
                  @change="(v: string) => quickStatusChange('mini', row, v)"
                  @visible-change="(v: boolean) => { if (v) statusPick[row.id] = row.status }"
                >
                  <el-option v-for="s in miniStatuses" :key="s" :label="s" :value="s" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column prop="expected_revenue_date" label="预计列收" width="110" />
            <el-table-column label="操作" width="70">
              <template #default="{ row }">
                <el-button size="small" type="danger" @click="handleDelete('mini', row.id)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
          <div v-if="!miniBusiness.length" class="empty">暂无数据</div>
        </el-tab-pane>

        <!-- ═══ 要客拜访 ═══ -->
        <el-tab-pane label="要客拜访" name="key_visits">
          <el-table :data="keyVisits" stripe size="small" v-column-resize>
            <el-table-column prop="customer_name" label="客户" width="130">
              <template #default="{ row }"><el-link type="primary" :underline="false" @click="openEdit('key', row)">{{ row.customer_name }}</el-link></template>
            </el-table-column>
            <el-table-column prop="urgency_level" label="重要度" width="80"><template #default="{ row }"><el-tag size="small" :type="row.urgency_level==='紧急'?'danger':row.urgency_level==='重要'?'warning':''">{{ row.urgency_level }}</el-tag></template></el-table-column>
            <el-table-column prop="description" label="描述" min-width="200" show-overflow-tooltip />
            <el-table-column label="进展" width="120">
              <template #default="{ row }">
                <el-select
                  v-model="statusPick[row.id]"
                  size="small"
                  style="width:100%"
                  :placeholder="row.progress_status"
                  @change="(v: string) => quickStatusChange('key', row, v)"
                  @visible-change="(v: boolean) => { if (v) statusPick[row.id] = row.progress_status }"
                >
                  <el-option v-for="s in keyStatuses" :key="s" :label="s" :value="s" />
                </el-select>
              </template>
            </el-table-column>
            <el-table-column prop="planned_date" label="计划时间" width="110" />
            <el-table-column prop="planned_visitor" label="拜访人" width="80" />
            <el-table-column prop="visit_target" label="拜访对象" width="100" />
            <el-table-column label="操作" width="70">
              <template #default="{ row }">
                <el-button size="small" type="danger" @click="handleDelete('key', row.id)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
          <div v-if="!keyVisits.length" class="empty">暂无数据</div>
        </el-tab-pane>
        <div style="margin-top:16px;display:flex;align-items:center;gap:12px">
          <el-pagination
            v-model:current-page="page[activeTab === 'notes' ? 'notes' : activeTab === 'plans' ? 'plans' : activeTab === 'mini' ? 'mini' : activeTab === 'key' ? 'key' : 'visits']"
            :page-size="pageSize"
            :total="total[activeTab === 'notes' ? 'notes' : activeTab === 'plans' ? 'plans' : activeTab === 'mini' ? 'mini' : activeTab === 'key' ? 'key' : 'visits']"
            :page-sizes="[25, 50, 100]"
            layout="total, sizes, prev, pager, next"
            small
            @current-change="(p: number) => onPageChange(activeTab === 'notes' ? 'notes' : activeTab === 'plans' ? 'plans' : activeTab === 'mini' ? 'mini' : activeTab === 'key' ? 'key' : 'visits', p)"
            @size-change="onSizeChange"
          />
        </div>
      </el-tabs>
    </el-card>

    <!-- Create/Edit Dialog -->
    <el-dialog v-model="dialogVisible" :title="(dialogMode === 'create' ? '新建' : '编辑') + ' ' + typeLabel(dialogType)" width="520px">
      <el-form label-position="top" v-if="form">
        <el-form-item v-if="['visit','plan','mini','key'].includes(dialogType)" label="客户单位 *">
          <el-select v-model="form.customer_id" filterable remote :remote-method="handleCustomerSearch" placeholder="搜索选择客户" style="width:100%">
            <el-option v-for="c in customers" :key="c.id" :label="c.name" :value="c.id" />
            <template #empty>
              <div v-if="customerSearch" class="select-empty-create">
                <p style="color:var(--warm-gray);font-size:13px;margin:0 0 8px">未找到「{{ customerSearch }}」</p>
                <button type="button" class="quick-create-btn" @click.stop="handleQuickCreate">+ 新建客户「{{ customerSearch }}」</button>
              </div>
            </template>
          </el-select>
        </el-form-item>
        <el-form-item v-if="(auth.isDirector || auth.isLeader) && ['visit','plan','mini','key','note'].includes(dialogType)" label="客户经理">
          <el-select v-model="form.manager_id" filterable placeholder="选择客户经理" style="width:100%">
            <el-option v-for="m in allManagers" :key="m.id" :label="m.name" :value="m.id" />
          </el-select>
        </el-form-item>
        <el-form-item v-if="dialogType === 'visit'" label="日期"><el-date-picker v-model="form.visit_date" type="date" style="width:100%" /></el-form-item>
        <el-form-item v-if="dialogType === 'note'" label="日期"><el-date-picker v-model="form.note_date" type="date" style="width:100%" /></el-form-item>
        <el-form-item v-if="dialogType === 'plan'" label="计划拜访时间"><el-date-picker v-model="form.plan_date" type="date" style="width:100%" /></el-form-item>
        <template v-if="dialogType === 'visit'">
          <el-form-item label="拜访方式">
            <div class="method-grid">
              <el-button v-for="m in ['上门','电话','微信','出差']" :key="m" size="small" :type="form.visit_method===m?'primary':''" @click="form.visit_method=m">{{ m }}</el-button>
            </div>
          </el-form-item>
          <el-form-item label="时间范围">
            <el-time-picker v-model="dialogTimeRange" is-range format="HH:mm" value-format="HH:mm" range-separator="至" start-placeholder="开始" end-placeholder="结束" style="width:100%" @change="onDialogTimeChange" />
          </el-form-item>
          <el-form-item label="拜访人姓名"><el-input v-model="form.visitor_name" placeholder="实际拜访人姓名" /></el-form-item>
          <el-form-item label="拜访人电话"><el-input v-model="form.visitor_phone" placeholder="联系电话（可选）" /></el-form-item>
          <el-form-item label="相关人员">
            <el-select v-model="form.companions" multiple filterable allow-create default-first-option placeholder="选择或输入姓名（可多选）" style="width:100%">
              <el-option v-for="u in allUsers" :key="u.id" :label="u.name" :value="u.id" />
            </el-select>
          </el-form-item>
          <el-form-item label="沟通内容"><el-input v-model="form.communication_content" type="textarea" :rows="3" /></el-form-item>
          <el-form-item label="客户需求"><el-input v-model="form.customer_demand" type="textarea" :rows="2" /></el-form-item>
          <el-form-item v-if="dialogMode === 'edit' && form.photos?.length" label="照片">
            <div style="display:flex;gap:8px;flex-wrap:wrap">
              <div v-for="(key, idx) in form.photos" :key="key" style="position:relative">
                <img :src="photoUrls[key]" style="width:80px;height:80px;object-fit:cover;border:1px solid var(--warm-border);cursor:pointer" v-if="photoUrls[key]" @click.stop="previewPhoto(photoUrls[key])" />
                <span v-else style="width:80px;height:80px;display:flex;align-items:center;justify-content:center;background:var(--paper);border:1px solid var(--warm-border);font-size:11px;color:var(--warm-gray)">加载中...</span>
                <button type="button" style="position:absolute;top:-6px;right:-6px;background:var(--vermilion);color:#fff;border:none;width:18px;height:18px;font-size:12px;cursor:pointer;line-height:1;border-radius:50%" @click="removePhotoFromEdit(idx)" title="删除照片">×</button>
              </div>
            </div>
            <div style="margin-top:4px;font-size:11px;color:var(--warm-gray)">点击 × 移除照片，点击「保存」提交更改</div>
          </el-form-item>
          <el-form-item v-if="dialogType === 'visit'" label="添加照片">
            <label style="cursor:pointer;display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border:1px dashed var(--warm-border);color:var(--warm-gray);font-size:13px">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
              {{ uploading ? '上传中...' : '上传照片（最多9张）' }}
              <input type="file" accept="image/*" multiple style="display:none" @change="handleDialogPhotoUpload" />
            </label>
          </el-form-item>
        </template>
        <template v-if="dialogType === 'note'">
          <el-form-item label="分类"><div style="display:flex;flex-wrap:wrap;gap:6px"><el-button v-for="c in categories" :key="c" :type="form.category===c?'primary':''" size="small" @click="form.category=c">{{ c }}</el-button></div></el-form-item>
          <el-form-item label="时间范围">
            <el-time-picker v-model="dialogTimeRange" is-range format="HH:mm" value-format="HH:mm" range-separator="至" start-placeholder="开始" end-placeholder="结束" style="width:100%" @change="onDialogTimeChange" />
          </el-form-item>
          <el-form-item label="工作内容"><el-input v-model="form.content" type="textarea" :rows="4" /></el-form-item>
        </template>
        <template v-if="dialogType === 'plan'">
          <el-form-item label="工作计划"><el-input v-model="form.plan_content" type="textarea" :rows="4" /></el-form-item>
          <el-form-item label="状态"><el-select v-model="form.status"><el-option label="计划中" value="计划中" /><el-option label="已完成" value="已完成" /><el-option label="已取消" value="已取消" /></el-select></el-form-item>
        </template>
        <template v-if="dialogType === 'mini'">
          <el-form-item label="产品类型"><el-input v-model="form.product_type" /></el-form-item>
          <el-form-item label="金额"><el-input v-model="form.amount" /></el-form-item>
          <el-form-item label="跟进内容"><el-input v-model="form.follow_up_detail" type="textarea" :rows="4" /></el-form-item>
          <el-form-item label="状态"><el-select v-model="form.status"><el-option label="跟进中" value="跟进中" /><el-option label="已签约" value="已签约" /><el-option label="已流失" value="已流失" /></el-select></el-form-item>
          <el-form-item label="预计列收时间"><el-date-picker v-model="form.expected_revenue_date" type="month" placeholder="选择月份" style="width:100%" value-format="YYYY-MM" /></el-form-item>
        </template>
        <template v-if="dialogType === 'key'">
          <el-form-item label="紧急重要度">
            <div class="method-grid">
              <el-button v-for="u in ['一般','重要','紧急']" :key="u" size="small" :type="form.urgency_level===u ? (u==='紧急'?'danger':u==='重要'?'warning':'') : ''" @click="form.urgency_level=u">{{ u }}</el-button>
            </div>
          </el-form-item>
          <el-form-item label="内容描述"><el-input v-model="form.description" type="textarea" :rows="4" /></el-form-item>
          <el-form-item label="进展状态"><el-select v-model="form.progress_status"><el-option label="未开始" value="未开始" /><el-option label="进行中" value="进行中" /><el-option label="已完成" value="已完成" /></el-select></el-form-item>
          <el-form-item label="计划拜访时间"><el-date-picker v-model="form.planned_date" type="date" placeholder="选择日期" style="width:100%" value-format="YYYY-MM-DD" /></el-form-item>
          <el-form-item label="计划拜访人（可多选）">
            <el-select v-model="plannedVisitors" multiple filterable allow-create default-first-option placeholder="选择或输入姓名（可多选）" style="width:100%" @change="onVisitorsChange">
              <el-option v-for="u in allUsers" :key="u.id" :label="u.name + (u.role==='director'?' (支局长)':u.role==='leader'?' (分管领导)':'')" :value="u.name" />
            </el-select>
          </el-form-item>
          <el-form-item label="拜访对象"><el-input v-model="form.visit_target" /></el-form-item>
        </template>
      </el-form>
      <EditLogPanel v-if="dialogMode === 'edit'" :edit-log="form.edit_log || []" />
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSave">保存</el-button>
      </template>
    </el-dialog>

    <ImagePreview v-model="previewDialogVisible" :image-url="previewImageUrl" />
  </div>
</template>

<style scoped>
.page-head { margin-bottom: 20px; }
.page-title { margin: 0; font-family: var(--font-heading); font-size: 22px; font-weight: 400; color: var(--ink); letter-spacing: 0.06em; }
.page-rule { width: 32px; height: 3px; background: var(--gold); margin-top: 12px; }
.date-group { margin-bottom: 20px; }
.date-title { display: flex; align-items: center; margin: 12px 0 8px; font-family: var(--font-heading); font-size: 14px; color: var(--ink); letter-spacing: 0.04em; }
.empty { text-align: center; color: var(--c-text-muted); padding: 40px 0; font-family: var(--font-body); }
.quick-create-btn { display: inline-flex; align-items: center; gap: 4px; background: none; border: 1px dashed var(--gold); padding: 6px 12px; color: var(--gold-dark); font-family: var(--font-body); font-size: 12px; cursor: pointer; transition: all 0.2s; }
.quick-create-btn:hover { border-color: var(--vermilion); color: var(--vermilion); background: rgba(184,71,46,0.03); }
.select-empty-create { padding: 8px 12px; text-align: center; }
.required-star { color: var(--vermilion); font-weight: 700; }
</style>
