<template>
  <div class="sales-timeline-with-task-list">
    <div class="timeline-title-section" style="display: flex; align-items: center; gap: 10px; justify-content: space-between;">
      <div style="display: flex; align-items: center; gap: 10px;">
              <h2 style="font-size: 18px;margin: 0;">销售时间线</h2>
        <span style="font-size: 14px;">客户转化全流程跟踪</span>
      </div>
  <div>
    <button @click="handleUnassignedRecordingsClick" class="unassigned-recordings-btn" style="margin-right: 10px;">尚未归属录音</button>
    <button @click="handleAllRecordingsClick" class="unassigned-recordings-btn">全部录音</button>
  </div>
    </div>
         
    <div class="sales-timeline">
      <div class="timeline-container">
        <div class="timeline-line"></div>
        <div 
          v-for="(stage, index) in stages" 
          :key="stage.id"
          class="timeline-stage"
          :class="{ 'active': stage.count > 0, 'selected': selectedStage === stage.name }"
          @click="selectStage(stage.name)"
        >
          <div class="stage-marker">
            <div class="marker-circle">
              <span class="stage-number">{{ index + 1 }}</span>
            </div>
            <div class="marker-line" v-if="index < stages.length - 1"></div>
          </div>
          <div class="stage-content">
            <h3 class="stage-title">{{ stage.displayName || stage.name }}</h3>
            <div class="stage-stats">
              <span class="stage-count">{{ stage.name === '全部' ? customersCount : stage.count }}</span>
              <span class="stage-label">位</span>
            </div>
            <div class="stage-unName">
              <span class="stage-unName" v-if="stage.unName">{{ stage.unName }}</span>
            </div>
            <div v-if="stage.name !== '全部'" class="stage-percentage">{{ getPercentage(stage.count, stage.id, stage.name) }}%</div>
          </div>
        </div>
      </div>
    </div>

    <!-- 课1-4子时间轴 -->
    <div v-if="selectedStage === '课1-4'" class="course-sub-timeline">
      <div class="sub-timeline-container">
        <!-- 课1子时间轴 -->
        <div class="course-timeline">
          <div class="course-header">
            <span class="course-title">课1</span>
            <span class="course-conversion">转化率: {{ getCourseConversionRate(1) }}%</span>
          </div>
          <div class="mini-timeline">
            <div class="mini-stage" :class="{ active: getCourseStageCount(1, '课1') > 0 }" @click="selectCourseStage(1, '课1')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">课1</span>
                <span class="mini-count">{{ getCourseStageCount(1, '课1') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(1, '付定金') > 0 }" @click="selectCourseStage(1, '付定金')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">付定金</span>
                <span class="mini-count">{{ getCourseStageCount(1, '付定金') }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 课2子时间轴 -->
        <div class="course-timeline">
          <div class="course-header">
            <span class="course-title">课2</span>
          </div>
          <div class="mini-timeline">
            <div class="mini-stage" :class="{ active: getCourseStageCount(2, '课2') > 0 }" @click="selectCourseStage(2, '课2')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">课2</span>
                <span class="mini-count">{{ getCourseStageCount(2, '课2') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(2, '点击未支付') > 0 }" @click="selectCourseStage(2, '点击未支付')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">点击未付</span>
                <span class="mini-count">{{ getCourseStageCount(2, '点击未支付') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(2, '付定金') > 0 }" @click="selectCourseStage(2, '付定金')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">付定金</span>
                <span class="mini-count">{{ getCourseStageCount(2, '付定金') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(2, '定金转化') > 0 }" @click="selectCourseStage(2, '定金转化')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">定金转化</span>
                <span class="mini-count">{{ getCourseStageCount(2, '定金转化') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(2, '成交') > 0 }" @click="selectCourseStage(2, '成交')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">成交</span>
                <span class="mini-count">{{ getCourseStageCount(2, '成交') }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 课3子时间轴 -->
        <div class="course-timeline">
          <div class="course-header">
            <span class="course-title">课3</span>
          </div>
          <div class="mini-timeline">
            <div class="mini-stage" :class="{ active: getCourseStageCount(3, '课3') > 0 }" @click="selectCourseStage(3, '课3')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">课3</span>
                <span class="mini-count">{{ getCourseStageCount(3, '课3') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(3, '点击未支付') > 0 }" @click="selectCourseStage(3, '点击未支付')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">点击未付</span>
                <span class="mini-count">{{ getCourseStageCount(3, '点击未支付') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(3, '付定金') > 0 }" @click="selectCourseStage(3, '付定金')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">付定金</span>
                <span class="mini-count">{{ getCourseStageCount(3, '付定金') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(3, '定金转化') > 0 }" @click="selectCourseStage(3, '定金转化')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">定金转化</span>
                <span class="mini-count">{{ getCourseStageCount(3, '定金转化') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(3, '成交') > 0 }" @click="selectCourseStage(3, '成交')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">成交</span>
                <span class="mini-count">{{ getCourseStageCount(3, '成交') }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 课4子时间轴 -->
        <div class="course-timeline">
          <div class="course-header">
            <span class="course-title">课4</span>
          </div>
          <div class="mini-timeline">
            <div class="mini-stage" :class="{ active: getCourseStageCount(4, '课4') > 0 }" @click="selectCourseStage(4, '课4')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">课4</span>
                <span class="mini-count">{{ getCourseStageCount(4, '课4') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(4, '点击未支付') > 0 }" @click="selectCourseStage(4, '点击未支付')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">点击未付</span>
                <span class="mini-count">{{ getCourseStageCount(4, '点击未支付') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(4, '付定金') > 0 }" @click="selectCourseStage(4, '付定金')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">付定金</span>
                <span class="mini-count">{{ getCourseStageCount(4, '付定金') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(4, '定金转化') > 0 }" @click="selectCourseStage(4, '定金转化')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">定金转化</span>
                <span class="mini-count">{{ getCourseStageCount(4, '定金转化') }}</span>
              </div>
            </div>
            <div class="mini-stage" :class="{ active: getCourseStageCount(4, '成交') > 0 }" @click="selectCourseStage(4, '成交')">
              <div class="mini-marker"></div>
              <div class="mini-content">
                <span class="mini-title">成交</span>
                <span class="mini-count">{{ getCourseStageCount(4, '成交') }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>    

    <div class="task-body">
      <div class="actionable-list">
        <div class="items-grid">
          <div 
            v-for="item in contacts" 
            :key="item.id" 
            :id="`contact-item-${item.id}`"
            class="action-item"
            :class="[getHealthClass(item.health), { 'active': item.id === selectedContactId }]"
            @click="selectContact(item.id)">
            <div class="item-content">
              <!-- 头像区域 -->
              <div class="avatar-section">
                <div class="avatar">
                  <img :src="item.avatar || '/default-avatar.svg'" :alt="item.name" class="avatar-img" />
                </div>
              </div>
              
              <!-- 信息区域 -->
              <div class="info-section">
                <div class="item-header">
                  <div class="item-name-group">
                    <span class="item-name" :title="item.name">{{ item.name }}</span>
                  </div>
                  <span class="item-time">{{ item.time }}</span>
                </div>
                <div class="item-footer">
                  <div class="profession-education">
                    <span class="profession">{{ item.profession||'未知' }}</span>
                    <span class="education">{{ item.education||'未知' }}</span>
                    <span class="course-attendance">
                      {{ getAttendedLessons(item.class_situation,item.class_num) }}
                    </span>
                    <span class="course-type" v-if="item.type">{{ item.type }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 到课详情区域 -->
    <div v-if="selectedContactId && selectedContactDetails && (['课1-4', '课1', '课2', '课3', '课4'].includes(selectedStage))" class="course-details">
      <div class="course-details-header">
        <h4>{{ selectedContactDetails.name }} - 到课详情</h4>
      </div>
      <div class="course-details-content">
        <div v-if="!selectedContactDetails.class_situation || Object.keys(selectedContactDetails.class_situation).length === 0" class="no-data">
         未到课
        </div>
        <div v-else class="course-lessons">
          <div 
            v-for="(lessonData, lessonNum) in selectedContactDetails.class_situation" 
            :key="lessonNum"
            class="lesson-item"
          >
            <div class="lesson-header">
              <span class="lesson-number">第{{ lessonNum }}节课</span>
            </div>
            <div class="lesson-details">
              <div class="detail-item">
                <span class="detail-label">听课时长:</span>
                <span class="detail-value">{{ Math.round((lessonData.live_maximum_length_time || 0) / 60) }}分钟</span>
              </div>
              <div class="detail-item">
                <span class="detail-label">是否看回放:</span>
                <span class="detail-value">{{ lessonData.playback_maximum_length_time ? '是' : '否' }}</span>
              </div>
              <div class="detail-item" v-if="lessonData.playback_maximum_length_time">
                <span class="detail-label">回放时长:</span>
                <span class="detail-value">{{ Math.round((lessonData.playback_maximum_length_time || 0) / 60) }}分钟</span>
              </div>
                 <div class="detail-item" v-if="lessonData.speak_message">
                <span class="detail-label">直播发言:</span>
                <span class="detail-value clickable" @click="showSpeakMessages(lessonData.speak_message)">{{ lessonData.speak_message.length || 0 }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 发言内容弹窗 -->
    <div v-if="showModal" class="modal-overlay" @click="closeModal">
      <div class="modal-content" @click.stop>
        <div class="modal-header">
          <h3>直播发言内容</h3>
          <button class="close-btn" @click="closeModal">×</button>
        </div>
        <div class="modal-body">
          <div v-if="!modalMessages || modalMessages.length === 0" class="no-messages">
            暂无发言内容
          </div>
          <div v-else class="messages-list">
            <div v-for="(message, index) in modalMessages" :key="index" class="message-item">
              <span class="message-number">{{ index + 1 }}.</span>
              <span class="message-content">{{ message }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 无归属录音弹窗 -->
    <div v-if="showUnassignedRecordingsModal" class="modal-overlay" @click="showUnassignedRecordingsModal = false">
      <div class="modal-content recordings-modal" @click.stop>
        <div class="modal-header">
          <h3>尚未归属录音</h3>
          <button class="close-btn" @click="showUnassignedRecordingsModal = false">×</button>
        </div>
        <div class="modal-body">
          <!-- 新增的Tab栏 -->
          <div class="modal-tabs">
            <button
              v-for="category in recordingCategories"
              :key="category"
              class="tab-btn"
              :class="{ 'active': selectedCategory === category }"
              @click="selectedCategory = category"
            >
              {{ category }} ({{ categorizedRecordings[category]?.length || 0 }})
            </button>
          </div>

          <div v-if="!filteredRecordings || filteredRecordings.length === 0" class="no-messages">
            该分类下暂无录音
          </div>
          <div v-else class="recordings-list">
            <div class="recording-item" v-for="recording in filteredRecordings" :key="recording.id">
              <div class="recording-info">
                <div class="recording-header">
                  <span class="recording-name" :title="recording.name">{{ recording.name }}</span>
                  <span class="recording-score">分数: {{ recording.score }}</span>
                </div>
                <span class="recording-time">{{ recording.time }}</span>
                <div class="recording-details" style="display: flex; justify-content: space-between;">
                  <span class="recording-duration">时长: {{ recording.duration }}</span>
                  <span class="recording-type">{{ recording.type }}</span>
                </div>
              </div>
              <div class="recording-actions">
                <button class="report-link" @click="viewReport(recording)">查看报告</button>
                <a :href="recording.downloadUrl" class="download-link" download>下载</a>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 报告弹窗 -->
    <div v-if="showReportModal" class="modal-overlay" @click="showReportModal = false">
      <div class="modal-content report-modal" @click.stop>
        <div class="modal-header">
          <h3>录音报告</h3>
          <button class="report-btn" @click="printReport">一键复制</button>
          <button class="close-btn" @click="showReportModal = false">×</button>
        </div>
        <div class="modal-body">
          <div class="report-content">
            <div class="report-field">
              <label>详细信息:</label>
              <div class="report-details" v-html="reportData.detailsHtml"></div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { computed, ref, onMounted } from 'vue';
import { useRouter } from 'vue-router'; // 引入 useRouter
import axios from 'axios';
import { useUserStore } from "@/stores/user";
import MarkdownIt from 'markdown-it';

const md = new MarkdownIt();
const router = useRouter(); // 实例化 useRouter

// 弹窗相关的响应式数据
const showModal = ref(false);
const modalMessages = ref([]);

// --- 无归属录音弹窗相关状态 ---
const showUnassignedRecordingsModal = ref(false);
const categorizedRecordings = ref({}); // **修改**: 用于存储分类后的录音
const recordingCategories = ref([]); // **新增**: 存储所有分类名称 (用于生成Tab)
const selectedCategory = ref(null); // **新增**: 存储当前选中的分类

// **新增**: 计算属性，根据选中的分类返回对应的录音列表
const filteredRecordings = computed(() => {
  if (!selectedCategory.value || !categorizedRecordings.value[selectedCategory.value]) {
    return [];
  }
  return categorizedRecordings.value[selectedCategory.value];
});

// 报告弹窗相关数据
const showReportModal = ref(false);
const reportData = ref({});


// --- 新增：获取通用请求参数的函数 ---
const getRequestParams = () => {
  const params = {}
  // 只从路由参数获取
  const routeUserLevel = router.currentRoute.value.query.user_level || router.currentRoute.value.params.user_level
  const routeUserName = router.currentRoute.value.query.user_name || router.currentRoute.value.params.user_name
  // 如果路由有参数，使用路由参数
  if (routeUserLevel) {
    params.user_level = routeUserLevel.toString()
  }
  if (routeUserName) {
    params.user_name = routeUserName
  }
  return params
}

// --- 修改：处理无归属录音按钮点击事件 ---
const handleUnassignedRecordingsClick = async () => {
  try {
    const userStore = useUserStore();
    const routeParams = getRequestParams(); // 获取路由参数

    // 优先使用路由参数，其次是 Pinia store 中的用户信息，最后是备用值
    const user_name = routeParams.user_name || userStore.userInfo?.username || 'example_user';
    
    const response = await axios.post('https://mldash.nycjy.cn/api/v1/sales_timeline/get_sale_unassigned_call_info', {
      user_name: user_name
    });
    
    console.log('API Response:', response.data.data);

    // --- 数据处理逻辑，以支持分类 ---
    const apiData = response.data.data;
    const tempCategorizedData = {}; // 临时对象
    let uniqueId = 0; 

    for (const category in apiData) {
      if (Object.prototype.hasOwnProperty.call(apiData, category)) {
        const categoryData = apiData[category];
        tempCategorizedData[category] = []; // 为每个分类创建一个空数组
        
        if (categoryData && Array.isArray(categoryData.records)) {
          categoryData.records.forEach(record => {
            tempCategorizedData[category].push({ // 将记录添加到对应的分类数组中
              id: uniqueId++,
              name: `录音 ${uniqueId}`,
              time: new Date(record.record_create_time).toLocaleString('zh-CN'),
              type: record.record_tag,
              downloadUrl: record.record_file_addr,
              duration: record.call_duration ? `${record.call_duration} 分钟` : '未知',
              score: record.score || '暂无',
              details: record.report_content || '暂无详细报告内容。'
            });
          });
        }
      }
    }

    // 更新状态
    categorizedRecordings.value = tempCategorizedData;
    recordingCategories.value = Object.keys(tempCategorizedData);
    // 默认选中第一个Tab
    if (recordingCategories.value.length > 0) {
      selectedCategory.value = recordingCategories.value[0];
    } else {
      selectedCategory.value = null;
    }
    
    showUnassignedRecordingsModal.value = true;
  } catch (error) {
    console.error('API请求失败:', error);
    alert('获取录音列表失败，请稍后再试。');
  }
};

// --- 新增：处理全部录音按钮点击事件 ---
const handleAllRecordingsClick = async () => {
  try {
    const userStore = useUserStore();
    const routeParams = getRequestParams(); // 获取路由参数

    // 优先使用路由参数，其次是 Pinia store 中的用户信息，最后是备用值
    const user_name = routeParams.user_name || userStore.userInfo?.username || 'example_user';
    
    const response = await axios.post('https://mldash.nycjy.cn/api/v1/sales_timeline/get_sale_all_call_info', {
      user_name: user_name
    });
    
    console.log('API Response:', response.data.data);

    // --- 数据处理逻辑，以支持分类 ---
    const apiData = response.data.data;
    const tempCategorizedData = {}; // 临时对象
    let uniqueId = 0; 

    for (const category in apiData) {
      if (Object.prototype.hasOwnProperty.call(apiData, category)) {
        const categoryData = apiData[category];
        tempCategorizedData[category] = []; // 为每个分类创建一个空数组
        
        if (categoryData && Array.isArray(categoryData.records)) {
          categoryData.records.forEach(record => {
            tempCategorizedData[category].push({ // 将记录添加到对应的分类数组中
              id: uniqueId++,
              name: record.customer_name || `录音 ${uniqueId}`,
              time: new Date(record.record_create_time).toLocaleString('zh-CN'),
              type: record.record_tag,
              downloadUrl: record.record_file_addr,
              duration: record.call_duration ? `${record.call_duration} 分钟` : '未知',
              score: record.score || '暂无',
              details: record.report_content || '暂无详细报告内容。'
            });
          });
        }
      }
    }

    // 更新状态
    categorizedRecordings.value = tempCategorizedData;
    recordingCategories.value = Object.keys(tempCategorizedData);
    // 默认选中第一个Tab
    if (recordingCategories.value.length > 0) {
      selectedCategory.value = recordingCategories.value[0];
    } else {
      selectedCategory.value = null;
    }
    
    showUnassignedRecordingsModal.value = true;
  } catch (error) {
    console.error('API请求失败:', error);
    alert('获取录音列表失败，请稍后再试。');
  }
};

// 查看报告函数 (无需修改)
const viewReport = (recording) => {
  reportData.value = { 
    details: recording.details,
    detailsHtml: md.render(recording.details || '暂无详细报告内容。')
  };
  showReportModal.value = true;
};

const printReport = () => {
  const content = reportData.value.details;
  if (!content) {
    alert('没有可复制的内容');
    return;
  }
  
  // 尝试使用 Clipboard API
  if (navigator.clipboard && window.isSecureContext) {
    navigator.clipboard.writeText(content).then(() => {
      alert('报告内容已复制到剪贴板');
    }).catch(err => {
      console.error('复制失败:', err);
      // 降级到传统方法
      fallbackCopyTextToClipboard(content);
    });
  } else {
    // 降级到传统方法
    fallbackCopyTextToClipboard(content);
  }
};

function fallbackCopyTextToClipboard(text) {
  const textArea = document.createElement("textarea");
  textArea.value = text;
  textArea.style.position = "fixed";  //avoid scrolling to bottom
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();
  
  try {
    const successful = document.execCommand('copy');
    if (successful) {
      alert('报告内容已复制到剪贴板');
    } else {
      alert('复制失败，请手动复制');
    }
  } catch (err) {
    console.error('Fallback: Oops, unable to copy', err);
    alert('复制失败，请手动复制');
  }
  
  document.body.removeChild(textArea);
}

const props = defineProps({
  data: {
    type: Object,
    default: () => ({})
  },
  selectedStage: {
    type: String,
    default: 'all'
  },
  contacts: {
    type: Array,
    required: true
  },
  selectedContactId: {
    type: Number,
    default: null
  },
  courseCustomers: {
    type: Object,
    default: () => ({})
  },
  customersList: {
    type: Array,
    default: () => []
  },
  customersCount: {
    type: Number,
    default: 0
  },
  payMoneyCustomersList: {
    type: Array,
    default: () => []
  },
  payMoneyCustomersCount: {
    type: Number,
    default: 0
  }
});

const emit = defineEmits(['stage-select', 'select-contact', 'sub-stage-select']);

const totalCustomers = computed(() => {
  if (props.customersList?.length > 0) return props.customersList.length;
  if (props.data['全部']) return props.data['全部'];
  const baseStages = [
    props.data['未加微'] || 0, props.data['已加微'] || 0, props.data['已入群'] || 0,
    props.data['已填表单'] || 0, props.data['课1-4'] || 0, props.data['点击未支付'] || 0,
    props.data['付定金'] || 0, props.data['定价转化'] || 0, props.data['成交'] || 0
  ];
  return Math.max(...baseStages, 1);
});

const getAttendedLessons = (classSituation, classNum) => {
  if (classNum && Array.isArray(classNum) && classNum.length > 0) {
    const filtered = classNum.filter(n => n !== -1);
    return filtered.length > 0 ? filtered.sort((a, b) => a - b).join(' ') : '未到课';
  }
  if (!classSituation) return '未到课';
  if (Array.isArray(classSituation)) {
    const filtered = classSituation.filter(i => i !== -1);
    return filtered.length > 0 ? filtered.join(' ') : '未到课';
  }
  if (typeof classSituation === 'object') {
    const lessons = Object.keys(classSituation).map(k => parseInt(k)).filter(n => !isNaN(n) && n !== -1).sort((a, b) => a - b);
    return lessons.length > 0 ? lessons.join(' ') : '未到课';
  }
  return '未到课';
};

// **修改 getStageCount 函数**
const getStageCount = (stageType) => {
  
  if (stageType === '成交') {
    return props.payMoneyCustomersCount || (props.payMoneyCustomersList?.length || 0);
  }
  if (stageType === '课1-4' && props.courseCustomers?.['课1-4']) {
    return props.courseCustomers['课1-4'].length;
  }
  if (['点击未支付', '付定金', '定金转化'].includes(stageType)) {
    if (props.courseCustomers?.['课1-4']) {
      return props.courseCustomers['课1-4'].filter(customer => customer.type === stageType).length;
    }
    return 0;
  }

  const allCustomers = props.customersList || [];
  // 筛选掉 '待加微' 的客户列表，只有这批客户才需要关注 '待填表单' 和 '待到课'
  const nonPendingWechatCustomers = allCustomers.filter(c => c.type !== '待加微');

  if (stageType === '待填表单') {
    // 对非 '待加微' 的客户进行筛选
    return nonPendingWechatCustomers.filter(customer => (customer.customer_occupation === '未知' || !customer.customer_occupation) || (customer.customer_child_education === '未知' || !customer.customer_child_education)).length;
  }
  
  if (stageType === '待到课') {
    // 对非 '待加微' 的客户进行筛选，并使用 getAttendedLessons
    return nonPendingWechatCustomers.filter(customer => getAttendedLessons(customer.class_situation, customer.class_num) === '未到课').length;
  }
  
  // 对于其他普通阶段（待加微、待入群、待联系），使用全部客户列表
  if (allCustomers.length > 0) {
    return allCustomers.filter(customer => customer.type === stageType).length;
  }
  return props.data[stageType] || 0;
};

const stages = computed(() => {
  const totalCount = props.customersList?.length || 0;
  return [
    { id: 0, name: '全部', displayName: '全部', count: totalCount },
    { id: 1, name: '待加微', displayName: '待加微', count: getStageCount('待加微') },
    { id: 2, name: '待填表单', displayName: '待填表单', count: getStageCount('待填表单') },
    { id: 3, name: '待入群', displayName: '待入群', count: getStageCount('待入群') },
    { id: 4, name: '待联系', displayName: '待联系', count: getStageCount('待联系') },
    { id: 5, name: '待到课', displayName: '待到课', count: getStageCount('待到课') },
    { id: 6, name: '课1-4', displayName: '课1-4', count: getStageCount('课1-4') },
    { id: 7, name: '点击未支付', displayName: '点击未付', count: getStageCount('点击未支付') },
    { id: 8, name: '付定金', displayName: '付定金', count: getStageCount('付定金') },
    { id: 9, name: '定金转化', displayName: '定金转化', count: getStageCount('定金转化') },
    { id: 10, name: '成交', displayName: '成交', count: getStageCount('成交') }
  ];
});

const getPercentage = (count, stageId, stageName) => {
  if (totalCustomers.value === 0) return 0;
  if (stageName === '待填表单' || (stageId >= 1 && stageId <= 5)) {
    return Math.round((totalCustomers.value - count) / totalCustomers.value * 100);
  }
  if (stageId > 5 && stageId <= 13) {
    return Math.round((count / totalCustomers.value) * 100);
  }
  return Math.round((totalCustomers.value - count) / totalCustomers.value * 100);
};

// **修改 selectStage 函数**
const selectStage = (stageName) => {
  let filteredCustomers = [];
  if (stageName === '全部') {
    filteredCustomers = props.customersList || [];
  } else if (stageName === '课1-4' && props.courseCustomers?.['课1-4']) {
    emit('stage-select', stageName, { isCourseStage: true, courseData: props.courseCustomers['课1-4'], filteredCustomers: props.courseCustomers['课1-4'] });
    return;
  } else if (stageName === '成交') {
    if (props.payMoneyCustomersList && props.payMoneyCustomersList.length > 0) {
      filteredCustomers = props.payMoneyCustomersList.map(c => ({ ...c, type: '成交' }));
    }
  } else if (['点击未支付', '付定金', '定金转化'].includes(stageName)) {
    if (props.courseCustomers?.['课1-4']) {
      filteredCustomers = props.courseCustomers['课1-4'].filter(c => c.type === stageName);
    }
  } else if (stageName === '待填表单') {
    // 筛选掉 '待加微' 的客户列表
    const customersToFilter = props.customersList.filter(c => c.type !== '待加微') || [];
    filteredCustomers = customersToFilter.filter(c => (c.customer_occupation === '未知' || !c.customer_occupation) || (c.customer_child_education === '未知' || !c.customer_child_education));
  } else if (stageName === '待到课') {
    // 筛选掉 '待加微' 的客户列表
    const customersToFilter = props.customersList.filter(c => c.type !== '待加微') || [];
    filteredCustomers = customersToFilter.filter(c => getAttendedLessons(c.class_situation, c.class_num) === '未到课');
  } else {
    filteredCustomers = props.customersList.filter(c => c.type === stageName);
  }
  emit('stage-select', stageName, { filteredCustomers, stageType: stageName, customerCount: filteredCustomers.length });
};

const selectedContactDetails = computed(() => {
  if (!props.selectedContactId) return null;
  return props.contacts.find(contact => contact.id === props.selectedContactId);
});

const selectContact = (id) => emit('select-contact', id);
const showSpeakMessages = (messages) => {
  modalMessages.value = messages || [];
  showModal.value = true;
};
const closeModal = () => {
  showModal.value = false;
  modalMessages.value = [];
};

const getCourseStageCount = (courseNumber, stageType) => {
  if (!props.customersList && !props.courseCustomers) return 0;
  let filteredCustomers = [];
  if (stageType === `课${courseNumber}`) {
    filteredCustomers = props.customersList.filter(c => (c.class_num?.includes(courseNumber)) || (c.class_situation && c.class_situation.hasOwnProperty(courseNumber.toString())));
  } else if (props.courseCustomers?.['课1-4']) {
    filteredCustomers = props.courseCustomers['课1-4'].filter(c => {
      let hasPaymentInCourse = c.time_and_camp_stage?.some(r => r.camp_stage === `课${courseNumber}` && r.pay_status === stageType);
      if (!hasPaymentInCourse) {
        hasPaymentInCourse = c.class_num?.includes(courseNumber) && c.type === stageType;
      }
      return hasPaymentInCourse;
    });
  }
  return filteredCustomers.length;
};

const getCourseConversionRate = (courseNumber) => {
  const courseStageCount = getCourseStageCount(courseNumber, `课${courseNumber}`);
  const depositCount = getCourseStageCount(courseNumber, '付定金');
  if (courseStageCount === 0) return 0;
  return Math.round((depositCount / courseStageCount) * 100);
};

const getHealthClass = (health) => {
  if (!health && health !== 0) return '';
  const healthValue = parseFloat(health);
  if (healthValue >= 80) return 'health-good';
  if (healthValue >= 60) return 'health-normal';
  if (healthValue >= 40) return 'health-warning';
  return 'health-danger';
};

const selectCourseStage = (courseNumber, stageType) => {
  let filteredCustomers = [];
  if (stageType === `课${courseNumber}`) {
    filteredCustomers = props.customersList.filter(c => (c.class_num?.includes(courseNumber)) || (c.class_situation && c.class_situation.hasOwnProperty(courseNumber.toString())));
  } else if (props.courseCustomers?.['课1-4']) {
    filteredCustomers = props.courseCustomers['课1-4'].filter(c => {
      let hasPaymentInCourse = c.time_and_camp_stage?.some(r => r.camp_stage === `课${courseNumber}` && r.pay_status === stageType);
      if (!hasPaymentInCourse) {
        hasPaymentInCourse = c.class_num?.includes(courseNumber) && c.type === stageType;
      }
      return hasPaymentInCourse;
    });
  }
  emit('sub-stage-select', {
    filteredCustomers,
    stageType: `课${courseNumber}-${stageType}`,
    customerCount: filteredCustomers.length,
    courseNumber,
    originalStageType: stageType,
    keepSubTimeline: true
  });
};
</script>

<style lang="scss" scoped>

// Color Variables
$slate-50: #f8fafc;
$slate-100: #f1f5f9;
$slate-200: #e2e8f0;
$slate-300: #cbd5e1;
$slate-400: #94a3b8;
$slate-500: #64748b;
$slate-600: #475569;
$slate-700: #334155;
$slate-800: #1e293b;
$white: #ffffff;
$primary: #3b82f6;
$success: #22c55e;
$warning: #f59e0b;
$danger: #ef4444;
$indigo: #4f46e5;

.sales-timeline-with-task-list { display: flex; flex-direction: column; gap: 1rem; }
.sales-timeline { padding: 1.5rem; background: $white; border-radius: 1rem; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); }
.timeline-container { position: relative; display: flex; justify-content: space-between; align-items: flex-start; overflow-x: auto; padding: 2rem 1rem 1rem 1rem; }
.timeline-line { position: absolute; top: 4rem; left: 2rem; right: 2rem; height: 3px; background: linear-gradient(to right, $primary, $success); border-radius: 2px; }
.timeline-stage { position: relative; display: flex; flex-direction: column; align-items: center; gap: 1rem; flex: 1; min-width: 120px; cursor: pointer; transition: all 0.3s ease; border-radius: 8px; padding: 0.5rem 8px; &:hover { background-color: rgba(59, 130, 246, 0.05); transform: translateY(-2px); .marker-circle { border-color: $primary; transform: scale(1.1); } } &.selected { background-color: rgba(59, 130, 246, 0.1); box-shadow: 0 2px 8px rgba(59, 130, 246, 0.2); .marker-circle { border-color: $primary; background: $primary; transform: scale(1.2); .stage-number { color: $white; } } } &.active { .marker-circle { background: linear-gradient(135deg, $primary, $success); color: $white; transform: scale(1.1); box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3); } .stage-content { .stage-title { color: $slate-800; } .stage-count { color: $primary; font-weight: 700; } } } }
.stage-marker { position: relative; z-index: 3; .marker-circle { width: 4rem; height: 4rem; border-radius: 50%; background: $slate-200; border: 3px solid $white; display: flex; align-items: center; justify-content: center; transition: all 0.3s ease; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); .stage-number { font-size: 1.125rem; font-weight: 700; color: $slate-600; } } }
.stage-content { text-align: center; width: 100%; .stage-title { font-size: 1rem; font-weight: 500; color: $slate-700; margin: 0 0 0.75rem 0; } .stage-stats { display: flex; align-items: baseline; justify-content: center; gap: 0.5rem; margin-bottom: 0.5rem; .stage-count { font-size: 1.5rem; font-weight: 700; color: $slate-600; line-height: 1; } .stage-label { font-size: 0.75rem; color: $slate-500; } } .stage-percentage { font-size: 0.75rem; color: $slate-400; background: $slate-100; padding: 0.25rem 0.75rem; border-radius: 1rem; display: inline-block; } }
.course-details { background: $white; border-radius: 0.75rem; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); margin-top: 1rem; .course-details-header { background: linear-gradient(135deg, #f8fafc, #e2e8f0); padding: 0.75rem 1rem; border-bottom: 1px solid $slate-200; h4 { margin: 0; font-size: 0.875rem; font-weight: 600; color: $slate-700; } } .course-details-content { padding: 1rem; max-height: 200px; overflow-y: auto; .no-data { text-align: center; color: $slate-500; padding: 1rem 0; } .course-lessons { display: flex; flex-direction: row; gap: 0.75rem; .lesson-item { background: $slate-50; border-radius: 0.5rem; padding: 0.75rem; .lesson-header .lesson-number { font-weight: 600; } .lesson-details { display: flex; flex-wrap: wrap; gap: 1rem; .detail-item .detail-label { color: $slate-500; } .detail-item .detail-value { font-weight: 600; } } } } } }
.task-body { padding: 1rem; max-height: 50vh; background: $white; border-radius: 1rem; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); overflow-y: auto; }
.actionable-list { display: flex; flex-direction: column; }
.items-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 250px)); gap: 0.45rem; justify-content: center; }
.action-item { background-color: $white; padding: 0.25rem; border-radius: 0.5rem; border: 1px solid $slate-200; cursor: pointer; transition: all 0.2s ease-in-out; display: flex; &:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.05); } &.active { background-color: #eef2ff; border-color: $indigo; } .item-content { display: flex; align-items: flex-start; gap: 0.75rem; width: 100%; } .avatar-section .avatar { width: 2.5rem; height: 2.5rem; border-radius: 50%; overflow: hidden; background-color: $slate-200; .avatar-img { width: 100%; height: 100%; object-fit: cover; } } .info-section { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.5rem; } .item-header { display: flex; justify-content: space-between; align-items: flex-start; } .item-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .item-time { font-size: 0.75rem; color: $slate-500; flex-shrink: 0; } .profession-education { display: flex; align-items: center; gap: 0.2rem; flex-wrap: wrap; .profession, .education, .course-type, .course-attendance { font-size: 0.75rem; padding: 0.1rem 0.5rem; border-radius: 0.3rem; font-weight: 500; } .profession { background-color: #e0f2fe; color: #0277bd; } .education { background-color: #f3e5f5; color: #7b1fa2; } .course-type { background-color: #e8f5e8; color: #2e7d32; } .course-attendance { background: linear-gradient(135deg, #e3f2fd, #bbdefb); color: #1565c0; border: 1px solid #90caf9; } } }
.unassigned-recordings-btn { background-color: $primary; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; transition: background-color 0.3s ease; &:hover { background-color: darken($primary, 10%); } }
.modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 1000; backdrop-filter: blur(2px); }
.modal-content { background: $white; border-radius: 12px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); width: 90%; max-width: 500px; max-height: 70vh; overflow: hidden; display: flex; flex-direction: column; animation: modalFadeIn 0.3s ease-out; }
.recordings-modal { max-width: 800px; /* 增大弹窗宽度以容纳多列 */ }
@keyframes modalFadeIn { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } }
.modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-bottom: 1px solid $slate-200; h3 { margin: 0; font-size: 1.25rem; font-weight: 600; } }
.close-btn { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: $slate-500; transition: all 0.2s ease; &:hover { background-color: $slate-200; color: $slate-700; } }
.modal-body { padding: 20px; overflow-y: auto; flex: 1; }
.no-messages { text-align: center; color: $slate-500; padding: 2rem 0; }
.recordings-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.recording-item { display: flex; flex-direction: column; justify-content: space-between; padding: 12px 16px; background-color: $slate-50; border-radius: 8px; transition: all 0.2s ease; &:hover { background-color: $slate-100; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); } }
.recording-info { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.recording-header { display: flex; justify-content: space-between; align-items: center; }
.recording-name { 
  font-weight: 500; 
  color: $slate-800; 
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: calc(100% - 80px);
}
.recording-time { font-size: 0.8rem; color: $slate-600; }
.recording-type { font-size: 0.75rem; color: $slate-500; background-color: $slate-200; padding: 2px 8px; border-radius: 12px; display: inline-block; width: fit-content; }
.recording-score { font-size: 0.8rem; color: $warning; font-weight: 600; }
.recording-duration { font-size: 0.8rem; color: $slate-600; }
.recording-actions { display: flex; gap: 8px; margin-top: 8px; }
.report-link, .download-link { color: white; border: none; padding: 6px 10px; border-radius: 4px; font-size: 0.85rem; cursor: pointer; transition: background-color 0.2s ease; text-decoration: none; text-align: center; }
.report-link { background-color: $success; &:hover { background-color: darken($success, 10%); } }
.download-link { background-color: $primary; &:hover { background-color: darken($primary, 10%); } }
.report-btn {
  background-color: $success;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s ease;
  margin-left: auto;
  
  &:hover {
    background-color: darken($success, 10%);
  }
  
  &:active {
    background-color: darken($success, 20%);
  }
}
.report-modal { max-width: 600px; }
.report-content { display: flex; flex-direction: column; gap: 12px; }
.report-field label {
  font-weight: 600;
}

.report-details {
  color: $slate-700;
  padding: 12px;
  background-color: $slate-50;
  border-radius: 4px;
  max-height: 500px;
  overflow-y: auto;
}

/* Markdown内容样式 */
.report-details h1,
.report-details h2,
.report-details h3 {
  margin-top: 16px;
  margin-bottom: 8px;
  color: $slate-800;
}

.report-details h1 {
  font-size: 1.5rem;
  border-bottom: 1px solid $slate-200;
  padding-bottom: 8px;
}

.report-details h2 {
  font-size: 1.3rem;
  border-bottom: 1px solid $slate-200;
  padding-bottom: 6px;
}

.report-details h3 {
  font-size: 1.1rem;
}

.report-details p {
  margin-bottom: 8px;
  line-height: 1.5;
}

.report-details ul,
.report-details ol {
  padding-left: 20px;
  margin-bottom: 8px;
}

.report-details li {
  margin-bottom: 4px;
}

.report-details code {
  background-color: $slate-100;
  padding: 2px 4px;
  border-radius: 3px;
  font-family: monospace;
}

.report-details pre {
  background-color: $slate-100;
  padding: 12px;
  border-radius: 4px;
  overflow-x: auto;
  margin-bottom: 12px;
}

.report-details pre code {
  background-color: transparent;
  padding: 0;
}

.report-details blockquote {
  border-left: 4px solid $slate-300;
  padding-left: 12px;
  margin-left: 0;
  color: $slate-600;
}

.report-details table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 12px;
}

.report-details th,
.report-details td {
  border: 1px solid $slate-300;
  padding: 8px;
  text-align: left;
}

.report-details th {
  background-color: $slate-100;
  font-weight: bold;
} 
.clickable { cursor: pointer; color: #1976d2; text-decoration: underline; &:hover { color: #1565c0; } }
.messages-list { display: flex; flex-direction: column; gap: 12px; .message-item { display: flex; gap: 8px; padding: 12px; background-color: #f9fafb; border-left: 3px solid $primary; } .message-number { font-weight: 600; color: $primary; } }
.course-sub-timeline { margin: 16px 0; padding: 12px; background-color: #f8fafc; border-radius: 8px; border: 1px solid #e2e8f0; }
.sub-timeline-container { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 8px; }
.course-timeline { background: white; border-radius: 6px; padding: 8px 12px; border: 1px solid #e5e7eb; }
.course-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.course-title { font-weight: 600; }
.course-conversion { font-size: 12px; color: $slate-500; background-color: $slate-100; padding: 2px 6px; border-radius: 4px; }
.mini-timeline { display: flex; align-items: flex-start; gap: 4px; position: relative; padding-top: 6px; &::before { content: ''; position: absolute; top: 12px; left: 6px; right: 6px; height: 2px; background-color: $slate-200; z-index: 1; } }
.mini-stage { display: flex; flex-direction: column; align-items: center; position: relative; z-index: 2; flex: 1; min-width: 0; .mini-marker { width: 12px; height: 12px; border-radius: 50%; background-color: $slate-200; border: 2px solid white; transition: all 0.3s ease; margin-bottom: 4px; } &.active .mini-marker { background-color: $primary; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2); } .mini-content { display: flex; flex-direction: column; align-items: center; } .mini-title { font-size: 11px; color: $slate-500; } &.active .mini-title { color: $slate-800; font-weight: 600; } .mini-count { font-size: 12px; font-weight: 600; color: $slate-500; background-color: $slate-100; padding: 1px 4px; border-radius: 3px; } &.active .mini-count { background-color: #dbeafe; color: #1d4ed8; } }

/* --- 新增：Tab栏样式 --- */
.modal-tabs {
  display: flex;
  gap: 8px;
  border-bottom: 1px solid $slate-200;
  margin-bottom: 16px;
  padding-bottom: 8px;
  overflow-x: auto; /* 在移动端允许横向滚动 */
}

.tab-btn {
  padding: 8px 16px;
  background-color: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  color: $slate-600;
  transition: all 0.3s ease;
  white-space: nowrap; /* 防止Tab文字换行 */

  &:hover {
    background-color: $slate-100;
    color: $slate-800;
  }

  &.active {
    color: $primary;
    border-bottom-color: $primary;
    font-weight: 600;
  }
}
</style>