<template>
  <div class="sales-dashboard">    
    <!-- 页面加载状态 -->
    <Loading :visible="isPageLoading" text="正在加载数据..." />
        <!-- 顶部导航栏 -->
    <!-- 销售时间线区域 -->
    <section class="timeline-section">
      <div class="section-header">
        <!-- 动态顶栏：根据是否有路由参数显示不同内容 -->
        <!-- 路由跳转时的顶栏：面包屑 + 姓名 -->
        <div v-if="isRouteNavigation" class="route-header" style="display: flex; justify-content: space-between; align-items: center;">
          <div class="breadcrumb" style="display: flex; flex-direction: column;">
            <span class="breadcrumb-item" @click="goBack">团队管理 >{{ routeUserName }}</span>
            <span class="breadcrumb-item current"> 数据驾驶舱</span>
          </div>
          <div class="user-name">
            {{ routeUserName }}
          </div>
        </div>

        <!-- 自己登录时的顶栏：原有样式 -->
        <template v-else>
          <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
            <h1 class="app-title">销售驾驶舱</h1>
            <div
              class="quick-stats"
              style="display: flex; align-items: center; gap: 30px"
            >
            </div>
            <UserDropdown />
          </div>
        </template>
      </div>
      <div class="section-content">
        <!-- 销售时间线加载状态 -->
        <div v-if="isTimelineLoading" class="section-loading">
          <div class="loading-spinner"></div>
          <div class="loading-text">正在加载销售时间线...</div>
        </div>
        <!-- 销售时间线内容 -->
        <SalesTimelineWithTaskList 
          v-else
          :data="timelineData" 
          @stage-select="handleStageSelect" 
          :selected-stage="selectedStage"
          :contacts="filteredContacts"
          :selected-contact-id="selectedContactId"
          :course-customers="courseCustomers"
          :kpi-data="kpiData"
          :customers-list="customersList"
          :customers-count="customersCount"
          :pay-money-customers-list="payMoneyCustomersList"
          :pay-money-customers-count="payMoneyCustomersCount"
          @select-contact="selectContact" />
      </div>
    </section>
    
    <!-- 原始数据卡片区域 -->
    <section class="raw-data-section">
      <div class="section-header">
        <h2>原始数据</h2>
        <p class="section-subtitle">客户互动的原始记录和数据</p>
      </div>
      <div class="section-content">
        <RawDataCards 
          :selected-contact="selectedContact"
          :form-info="formInfo"
          :chat-info="chatRecords"
          :call-info="callRecords"
          @view-form-data="handleViewFormData"
          @view-chat-data="handleViewChatData"
          @view-call-data="handleViewCallData"
          @analyze-sop="handleAnalyzeSop" />
      </div>
    </section>
    
    <!-- 主要内容区域 -->
    <div class="main-layout">
      <!-- 主要工作区域 -->
      <main class="main-content">
        <!-- 客户详情区域 -->
        <section class="detail-section">
          <div class="section-header">
            <h2>客户详情</h2>
          </div>
          <div class="section-content">
            <CustomerDetail 
              ref="customerDetailRef"
              :selected-contact="selectedContact" 
              :form-info="formInfo"
              :chat-records="chatRecords"
              :call-records="callRecords" />
          </div>
        </section>
      </main>
    </div>
    <section class="analytics-section-full" style="width: 100%;">
      
      <div class="section-content">
        <!-- 数据分析区域加载状态 -->
        <div v-if="isKpiLoading || isStatisticsLoading || isUrgentProblemLoading" class="section-loading">
          <div class="loading-spinner"></div>
          <div class="loading-text">正在加载数据分析...</div>
        </div>
        <!-- 数据分析内容 -->
        <PersonalDashboard
          v-else
          :kpi-data="kpiData"
          :funnel-data="funnelData"
          :contact-time-data="goldContactTime"
          :statistics-data="statisticsData"
          :urgent-problem-data="urgentProblemData"
        />
      </div>
    </section>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, nextTick } from "vue";
import { useRouter } from "vue-router";
import { useUserStore } from "@/stores/user";
import CustomerDetail from "./components/CustomerDetail.vue";
import PersonalDashboard from "./components/PersonalDashboard.vue";
import SalesTimelineWithTaskList from "./components/SalesTimelineWithTaskList.vue";
import RawDataCards from "./components/RawDataCards.vue";
import UserDropdown from "@/components/UserDropdown.vue";
import Loading from "@/components/Loading.vue";
import {getCustomerAttendance,getTodayCall,getProblemDistribution,getTableFillingRate,getAverageResponseTime,
  getWeeklyActiveCommunicationRate,getTimeoutResponseRate,getCustomerCallInfo,getCustomerChatInfo,getCustomerFormInfo,
  getConversionRateAndAllocatedData,getCustomerAttendanceAfterClass4,getPayMoneyCustomers,getSalesFunnel,getGoldContactTime,getAvgCallTime} from "@/api/api.js"

// 缓存系统
const cache = new Map();
const CACHE_DURATION = 30 * 60 * 1000; // 30分钟缓存时长

// 生成缓存键
const getCacheKey = (apiName, params = {}) => {
  const sortedParams = Object.keys(params)
    .sort()
    .reduce((result, key) => {
      result[key] = params[key];
      return result;
    }, {});
  return `${apiName}_${JSON.stringify(sortedParams)}`;
};

// 检查缓存是否有效
const isValidCache = (cacheData) => {
  return cacheData && (Date.now() - cacheData.timestamp) < CACHE_DURATION;
};

// 设置缓存
const setCache = (key, data) => {
  cache.set(key, {
    data,
    timestamp: Date.now()
  });
};

// 获取缓存
const getCache = (key) => {
  const cacheData = cache.get(key);
  if (isValidCache(cacheData)) {
    return cacheData.data;
  }
  // 如果缓存过期，删除它
  if (cacheData) {
    cache.delete(key);
  }
  return null;
};

// 缓存包装器函数
const withCache = async (apiName, apiFunction, params = {}) => {
  const cacheKey = getCacheKey(apiName, params);
  const cachedData = getCache(cacheKey);
  
  if (cachedData) {
    console.log(`[缓存命中] ${apiName}:`, cachedData);
    return cachedData;
  }
  
  console.log(`[API调用] ${apiName}`);
  const result = await apiFunction(params);
  setCache(cacheKey, result);
  return result;
};

// 路由实例
const router = useRouter();

// 用户store
const userStore = useUserStore();

// 获取通用请求参数的函数
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 isRouteNavigation = computed(() => {
  const routeUserName = router.currentRoute.value.query.user_name || router.currentRoute.value.params.user_name
  return !!routeUserName
})

// 获取路由传递的用户名
const routeUserName = computed(() => {
  return router.currentRoute.value.query.user_name || router.currentRoute.value.params.user_name || ''
})

// 返回上一页
const goBack = () => {
  router.go(-1)
}
// STATE
const selectedContactId = ref(null);
const contextPanelRef = ref(null);
const customerDetailRef = ref(null);
const selectedStage = ref('全部'); // 选中的销售阶段

const isPageLoading = ref(true); // 页面整体加载状态
const isKpiLoading = ref(false); // KPI数据加载状态
const isStatisticsLoading = ref(false); // 统计数据加载状态
const isUrgentProblemLoading = ref(false); // 紧急问题数据加载状态
const isTimelineLoading = ref(false); // 时间线数据加载状态

// KPI数据
const kpiDataState = reactive({
  totalCalls: 85,
  successRate: 28,
  avgDuration: 125,
  conversionRate: 12,
  assignedData: 256,
  wechatAddRate: 68
});

// 统计指标数据
const statisticsData = reactive({
  customerCommunicationRate: 0,
  averageResponseTime: 0,
  timeoutResponseRate: 0,
  severeTimeoutRate: 0,
  formCompletionRate: 0
});

// 客户迫切解决的问题数据
const urgentProblemData = ref([]);

// 时间线数据
const timelineData = ref({});

// 客户列表数据
const customersList = ref([]);

// 客户总数
const customersCount = ref(0);

// 课程客户数据（课1-4）
const courseCustomers = ref({});

// 成交阶段客户数据
const payMoneyCustomersList = ref([]);
const payMoneyCustomersCount = ref(0);

// 表单信息
const formInfo = ref({});
// 通话记录
const callRecords = ref([]);
// 聊天记录
const chatRecords = ref([]);

// MOCK DATA (Should ideally come from a store or API)
const MOCK_DATA = reactive({
  contacts: [
    // 今日必须联系 (high priority) - 12个任务
    {
      id: 1,
      name: "王女士",
      time: "今日 10:00",
    }
  ],
  performance: {
    calls: { label: "呼叫量", value: 85, target: 100 },
    talkTime: { label: "通话时长(分)", value: 125, target: 180 },
    revenue: { label: "签单额(元)", value: 8500, target: 15000 },
  },
  personalKPIs: {
    winRate: { label: "赢率", value: 28, unit: "%" },
    avgDealSize: { label: "平均客单价", value: 12500, unit: "元" },
    salesCycle: { label: "销售周期", value: 45, unit: "天" },
  },
  personalFunnel: [200, 150, 90, 40, 12],
  commission: { confirmed: 4250, estimated: 7800, nextDealValue: 350 },
  contactTimeAnalysis: {
    labels: ["9-10点", "10-11点", "11-12点", "14-15点", "15-16点", "16-17点"],
    data: [65, 85, 80, 92, 75, 60],
    description: "基于历史通话数据统计的客户接听成功率",
  },
});
// 核心Kpi
async function getCoreKpi() {
  isKpiLoading.value = true
  try {
    const params = getRequestParams()
    const hasParams = params.user_name
    
    // 今日通话数据
    const res = await withCache('getTodayCall', () => getTodayCall(hasParams ? params : undefined), hasParams ? params : {})
    if (res.code === 200) {
      kpiDataState.totalCalls = res.data.today_call
    }
    
    // 转化率、分配数据量、加微率
    const conversionRes = await withCache('getConversionRateAndAllocatedData', () => getConversionRateAndAllocatedData(hasParams ? params : undefined), hasParams ? params : {})
    if (conversionRes.code === 200) {
      kpiDataState.conversionRate = conversionRes.data.conversion_rate || 0
      kpiDataState.assignedData = conversionRes.data.all_count || 0
      kpiDataState.wechatAddRate = conversionRes.data.plus_v_conversion_rate || 0
    }
    
    // 平均通话时长
    const avgCallTimeRes = await withCache('getAvgCallTime', () => getAvgCallTime(hasParams ? params : undefined), hasParams ? params : {})
    if (avgCallTimeRes.code === 200) {
      kpiDataState.avgDuration = avgCallTimeRes.data.call_time || 0
    }
  } catch (error) {
    console.error('获取核心KPI数据失败:', error)
  } finally {
    isKpiLoading.value = false
  }
}
// 获取统计数据
async function getStatisticsData() {
  isStatisticsLoading.value = true
  try {
    const params = getRequestParams()
    const hasParams = params.user_name
    
    // 获取表单填写率
    const fillingRateRes = await withCache('getTableFillingRate', () => getTableFillingRate(hasParams ? params : undefined), hasParams ? params : {})
    if (fillingRateRes.code === 200) {
      statisticsData.formCompletionRate = fillingRateRes.data.filling_rate
    }
    
    // 获取平均响应时间
    const avgResponseRes = await withCache('getAverageResponseTime', () => getAverageResponseTime(hasParams ? params : undefined), hasParams ? params : {})
    if (avgResponseRes.code === 200) {
      statisticsData.averageResponseTime = avgResponseRes.data.average_minutes
    }
    
    // 获取客户沟通率
    const communicationRes = await withCache('getWeeklyActiveCommunicationRate', () => getWeeklyActiveCommunicationRate(hasParams ? params : undefined), hasParams ? params : {})
    if (communicationRes.code === 200) {
      statisticsData.customerCommunicationRate = communicationRes.data.communication_rate
    }
    
    // 获取超时响应率
    const timeoutRes = await withCache('getTimeoutResponseRate', () => getTimeoutResponseRate(hasParams ? params : undefined), hasParams ? params : {})
    if (timeoutRes.code === 200) {
      statisticsData.timeoutResponseRate = timeoutRes.data.overtime_rate_600
      statisticsData.severeTimeoutRate = timeoutRes.data.overtime_rate_800
    }
  } catch (error) {
    console.error('获取统计数据失败:', error)
  } finally {
    isStatisticsLoading.value = false
  }
}
// 客户迫切解决的问题
async function getUrgentProblem() {
  isUrgentProblemLoading.value = true
  try {
    const params = getRequestParams()
    const hasParams = params.user_name
    
    const res = await withCache('getProblemDistribution', () => getProblemDistribution(hasParams ? params : undefined), hasParams ? params : {})
    if(res.code === 200) {
      // 将API返回的对象格式转换为数组格式
      const problemDistributionCount = res.data.problem_distribution_count
      urgentProblemData.value = Object.entries(problemDistributionCount).map(([name, value]) => ({ name, value }))
    }
  } catch (error) {
    console.error('获取紧急问题数据失败:', error)
  } finally {
    isUrgentProblemLoading.value = false
  }
}
// 时间线
async function getTimeline() {
  isTimelineLoading.value = true
  try {
    const params = getRequestParams()
    const hasParams = params.user_name
    // 前6个阶段
    const res = await withCache('getCustomerAttendance', () => getCustomerAttendance(hasParams ? params : undefined), hasParams ? params : {})
    if(res.code === 200) {
      // 处理时间线数据
      if (res.data.timeline) {
        timelineData.value = Object.entries(res.data.timeline).map(([name, count]) => ({
          name: name,
          value: parseInt(count) || 0
        }))
      }
      // 处理客户列表数据
      if (res.data.all_customers_list) {
        customersList.value = res.data.all_customers_list
      }
      // 处理客户总数
      if (res.data.all_customers_count) {
        customersCount.value = res.data.all_customers_count
      }
    }
    // 后4个阶段
    const classRes = await withCache('getCustomerAttendanceAfterClass4', () => getCustomerAttendanceAfterClass4(hasParams ? params : undefined), hasParams ? params : {})
    if(classRes.code === 200) {      
      // 处理课1-4阶段的客户数据
      if (classRes.data.class_customers_list) {
        console.log(8888999,courseCustomers.value)
        // 存储课1-4阶段的原始数据，根据pay_status设置正确的type
        courseCustomers.value['课1-4'] = classRes.data.class_customers_list.map(customer => {
          let customerType = ''; // 默认类型
          
          // 根据pay_status设置具体的type
          if (customer.pay_status === '点击未支付') {
            customerType = '点击未支付';
          } else if (customer.pay_status === '付定金') {
            customerType = '付定金';
          } else if (customer.pay_status === '定金转化' || customer.pay_status === '已转化') {
            customerType = '定金转化';
          }
          
          return {
            id: customer.customer_name,
            name: customer.customer_name,
            phone: customer.phone,
            profession: customer.customer_occupation,
            education: customer.customer_child_education,
            avatar: customer.weChat_avatar || '/default-avatar.svg',
            time: customer.messages_last_time,
            type: customerType, // 根据pay_status设置的type
            health: 75, // 默认健康度
            customer_name: customer.customer_name,
            customer_occupation: customer.customer_occupation,
            customer_child_education: customer.customer_child_education,
            scrm_user_main_code: customer.scrm_user_main_code,
            weChat_avatar: customer.weChat_avatar,
            class_situation: customer.class_situation,
            class_num: Object.keys(customer.class_situation || {}), // 添加class_num字段
            pay_status: customer.pay_status,
            records: []
          };
        })
        
        // 根据pay_status筛选后三个阶段的客户
        const allClassCustomers = classRes.data.class_customers_list
        
        // 点击未支付阶段 - 可以根据具体业务逻辑调整筛选条件
        const unpaidCustomers = allClassCustomers.filter(customer => 
          customer.pay_status === '未支付' || customer.pay_status === '点击未支付'
        )
        // 付定金阶段
        const depositCustomers = allClassCustomers.filter(customer => 
          customer.pay_status === '付定金'
        )
        // 定价转化阶段 - 可以根据具体业务逻辑调整筛选条件
        const conversionCustomers = allClassCustomers.filter(customer => 
          customer.pay_status === '定金转化' || customer.pay_status === '已转化'
        )
        
        // 将筛选后的客户添加到对应的customersList中
        const formatCustomerForList = (customer, type) => ({
          customer_name: customer.customer_name,
          phone: customer.phone,
          customer_occupation: customer.customer_occupation,
          customer_child_education: customer.customer_child_education,
          latest_message_time: customer.messages_last_time,
          customer_avatar_url: customer.weChat_avatar,
          type: type,
          class_num: Object.keys(customer.class_situation || {}),
          class_situation: customer.class_situation,
          scrm_user_main_code: customer.scrm_user_main_code,
          weChat_avatar: customer.weChat_avatar,
          pay_status: customer.pay_status
        })
        // 后三个阶段的客户数据已存储在courseCustomers['课1-4']中，不需要合并到customersList
      }
    }
    // 成交阶段
    const payRes = await withCache('getPayMoneyCustomers', () => getPayMoneyCustomers(hasParams ? params : undefined), hasParams ? params : {})
    if(payRes.code === 200) {
      // 处理成交阶段的客户数据
      if (payRes.data.pay_money_customers_list) {
        payMoneyCustomersList.value = payRes.data.pay_money_customers_list
      }
      // 处理成交阶段客户总数
      if (payRes.data.pay_money_customers_count) {
        payMoneyCustomersCount.value = payRes.data.pay_money_customers_count
      }
      // 成交阶段客户数据已存储在payMoneyCustomersList中，不需要合并到customersList
    }
  } catch (error) {
    console.error('获取时间线数据失败:', error)
  } finally {
    isTimelineLoading.value = false
  }
}
// 获取客户表单
async function getCustomerForm() {
  if (!selectedContact.value || !selectedContact.value.name) {
    console.warn('无法获取客户表单：客户信息不完整');
    return;
  }
  const routeParams = getRequestParams()
  const params = {
    user_name: routeParams.user_name || userStore.userInfo.username,
    customer_name: selectedContact.value.name,
  }
  try {
    const res = await withCache('getCustomerFormInfo', () => getCustomerFormInfo(params), params)
    if(res.code === 200) {
      formInfo.value = res.data
    }
  } catch (error) {
    // 静默处理错误
  }
}
// 聊天记录   
async function getCustomerChat() {
  if (!selectedContact.value || !selectedContact.value.name) {
    console.warn('无法获取客户聊天记录：客户信息不完整');
    return;
  }
  const routeParams = getRequestParams()
  const params = {
    user_name: routeParams.user_name || userStore.userInfo.username,
    customer_name: selectedContact.value.name,
  }
  try {
    const res = await withCache('getCustomerChatInfo', () => getCustomerChatInfo(params), params)
    if(res.code === 200) {
      chatRecords.value = res.data
      console.log('聊天数据获取成功:', res.data)
      console.log('chatRecords.value:', chatRecords.value)
    } else {
      console.log('聊天数据获取失败:', res)
    }
  } catch (error) {
    // 静默处理错误
  }
}
// 通话记录
async function getCustomerCall() {
  if (!selectedContact.value || !selectedContact.value.name) {
    console.warn('无法获取客户通话记录：客户信息不完整');
    return;
  }
  const routeParams = getRequestParams()
  const params = {
    user_name: routeParams.user_name || userStore.userInfo.username,
    customer_name: selectedContact.value.name,
  }
  try {
    const res = await withCache('getCustomerCallInfo', () => getCustomerCallInfo(params), params)
    if(res.code === 200) {
      callRecords.value = res.data
      console.log('Call Records Data from API:', res.data)
      console.log('callRecords.value after assignment:', callRecords.value)
      /**
       *     "data": {
        "user_name": "常琳",
        "customer_name": "191桐桐爸爸高一男（婧）",
        "record_file_addr_list": [
            "http://192.168.3.112:5000/api/record/download/杨振彦-20分钟通话-25-08-19_07-23-37-744009-835.mp3"
        ]
    }
       */
    }
  } catch (error) {
    // 静默处理错误
  }
}
// 为组件准备数据
const kpiData = computed(() => kpiDataState);
// COMPUTED PROPERTIES
const selectedContact = computed(() => {
  // 优先从API数据中查找
  if (formattedCustomersList.value.length > 0) {
    return formattedCustomersList.value.find((c) => c.id === selectedContactId.value) || null;
  }
  // 否则从MOCK数据中查找
  return MOCK_DATA.contacts.find((c) => c.id === selectedContactId.value) || null;
});

const funnelData = computed(() => {
  if (!SalesFunnel.value || !SalesFunnel.value.sale_funnel) {
    return {
      labels: ["线索总数", "有效沟通", "到课数据", "预付定金", "成功签单"],
      data: [0, 0, 0, 0, 0]
    };
  }
  
  const funnel = SalesFunnel.value.sale_funnel;
  return {
    labels: ["线索总数", "有效沟通", "到课数据", "预付定金", "成功签单"],
    data: [
      funnel.线索总数 || 0,
      funnel.有效沟通 || 0,
      funnel.到课数据 || 0,
      funnel.预付定金 || 0,
      funnel.成功签单 || 0
    ]
  };
});

const contactTimeData = computed(() => ({
  labels: MOCK_DATA.contactTimeAnalysis.labels,
  data: MOCK_DATA.contactTimeAnalysis.data,
}));

// 格式化客户列表数据
const formattedCustomersList = computed(() => {
  if (!customersList.value || customersList.value.length === 0) {
    return [];
  }
  
  return customersList.value.map(customer => ({
    id: customer.customer_name, // 使用客户姓名作为唯一标识
    name: customer.customer_name,
    phone: customer.phone,
    profession: customer.customer_occupation,
    education: customer.customer_child_education,
    lastMessageTime: customer.latest_message_time,
    avatarUrl: customer.customer_avatar_url,
    type: customer.type,
    class_num: customer.class_num, // 确保字段名一致
    // 添加一些默认值以兼容现有组件
    salesStage: customer.type || '待联系',
    priority: customer.type === '待联系' ? 'high' : 'normal',
    time: customer.latest_message_time || '未知'
  }));
});

// 根据选中阶段筛选联系人
const filteredContacts = computed(() => {
  // 优先使用当前筛选的客户数据（来自阶段选择）
  if (currentFilteredCustomers.value.length > 0) {
    return currentFilteredCustomers.value;
  }
  
  // 对于课1-4阶段，如果没有currentFilteredCustomers数据，返回空数组
  // 避免使用formattedCustomersList中type可能为undefined的数据
  if (selectedStage.value === '课1-4') {
    return [];
  }
  // 如果有API数据，使用API数据
  if (formattedCustomersList.value.length > 0) {
    if (selectedStage.value === 'all' || selectedStage.value === '全部') {
      return formattedCustomersList.value;
    }
    return formattedCustomersList.value.filter(contact => contact.salesStage === selectedStage.value);
  }
  
  // 否则使用MOCK数据
  if (selectedStage.value === 'all' || selectedStage.value === '全部') {
    return MOCK_DATA.contacts.filter(contact => contact.salesStage === '全部');
  }
  return MOCK_DATA.contacts.filter(contact => contact.salesStage === selectedStage.value);
});

// METHODS
const selectContact = (id) => {
  selectedContactId.value = id;
  // 当选中客户后，获取客户表单数据
  nextTick(async () => {
    if (selectedContact.value && selectedContact.value.name) {
      await getStatisticsData()
      await getCustomerForm();
      await getCustomerChat();
      await getCustomerCall();
    }
    contextPanelRef.value?.scrollIntoView({
      behavior: "smooth",
      block: "center",
    });
  });
};

// 存储当前筛选的客户数据
const currentFilteredCustomers = ref([]);

// 处理时间线阶段选择
const handleStageSelect = (stage, extraData = null) => {
  selectedStage.value = stage;
  
  // 如果传递了筛选后的客户数据，使用这些数据
  if (extraData && extraData.filteredCustomers) {

    
    // 将筛选后的客户数据转换为contacts格式
    const filteredContacts = extraData.filteredCustomers.map(customer => ({
      id: customer.customer_name || customer.id,
      name: customer.customer_name || customer.name,
      phone: customer.phone,
      profession: customer.customer_occupation || customer.profession,
      education: customer.customer_child_education || customer.education,
      lastMessageTime: customer.latest_message_time || customer.time,
      avatarUrl: customer.customer_avatar_url || customer.avatar,
      avatar: customer.customer_avatar_url || customer.avatar || '/default-avatar.svg',
      type: customer.type,
      classNum: customer.class_num,
      class_num: customer.class_num, // 确保字段名一致
      salesStage: customer.type || stage,
      priority: customer.type === '待联系' ? 'high' : 'normal',
      time: customer.latest_message_time || customer.time || '未知',
      health: customer.health || 75,
      // 保留原始数据
      customer_name: customer.customer_name,
      customer_occupation: customer.customer_occupation,
      customer_child_education: customer.customer_child_education,
      scrm_user_main_code: customer.scrm_user_main_code,
      weChat_avatar: customer.weChat_avatar,
      class_situation: customer.class_situation,
      records: customer.records
    }));
    
    // 更新当前筛选的客户数据
    currentFilteredCustomers.value = filteredContacts;
    

  } else if (extraData && extraData.isCourseStage) {
    // 处理课程阶段的数据（课1-4、课1、课2、课3、课4）

    
    const courseContacts = extraData.courseData.map(customer => ({
      id: customer.id,
      name: customer.name,
      time: customer.time,
      profession: customer.profession,
      education: customer.education,
      avatar: customer.avatar,
      type: customer.type || stage, // 使用当前选中的阶段作为type
      salesStage: customer.type || stage, // 使用customer.type或当前阶段作为salesStage
      health: customer.health,
      customer_name: customer.customer_name,
      customer_occupation: customer.customer_occupation,
      customer_child_education: customer.customer_child_education,
      scrm_user_main_code: customer.scrm_user_main_code,
      weChat_avatar: customer.weChat_avatar,
      class_situation: customer.class_situation,
      class_num: customer.class_num, // 添加class_num字段
      pay_status: customer.pay_status, // 添加pay_status字段
      records: customer.records
    }));
    
    currentFilteredCustomers.value = courseContacts;

  } else {
    // 如果没有额外数据，清空筛选结果，使用默认逻辑
    currentFilteredCustomers.value = [];
  }
};
const handleViewFormData = async (contact) => {
  // 获取客户表单数据
  await getCustomerForm();
  console.log('表单数据已加载:', formInfo.value);
};

const handleViewChatData = async (contact) => {
  console.log('查看聊天数据:', contact)
  await getCustomerChatInfo({
    customerId: selectedContact.value?.customerId || 1
  })
  console.log('聊天数据已更新:', chatRecords.value)
};

const handleViewCallData = (contact) => {
  // TODO: 实现通话录音查看逻辑
};

// 处理SOP分析事件
const handleAnalyzeSop = (analyzeData) => {
  console.log('收到SOP分析请求:', analyzeData);
  if (customerDetailRef.value && analyzeData.content) {
    customerDetailRef.value.startSopAnalysis(analyzeData.content);
  }
};
// 销售漏斗
const SalesFunnel = ref([])
async function CenterGetSalesFunnel() {
  const params = getRequestParams()
  const hasParams = params.user_name
  const res = await withCache('getSalesFunnel', () => getSalesFunnel(hasParams ? params : undefined), hasParams ? params : {})
  if(res.code === 200){
    SalesFunnel.value = res.data
    /**
     *     "data": {
        "user_name": "常琳",
        "user_level": 1,
        "sale_funnel": {
            "线索总数": 11,
            "有效沟通": 9,
            "到课数据": 8,
            "预付定金": 0,
            "成功签单": 0
        }
    }
     */
  }
}
// 黄金联络时间段
const goldContactTime = ref([])
async function CenterGetGoldContactTime() {
  const params = getRequestParams()
  const hasParams = params.user_name
  const res = await withCache('getGoldContactTime', () => getGoldContactTime(hasParams ? params : undefined), hasParams ? params : {})
  if(res.code === 200){
    goldContactTime.value = res.data
  }
}

// 缓存管理功能
// 清除所有缓存
function clearCache() {
  cache.clear()
  console.log('所有缓存已清除')
}

// 清除特定缓存
function clearSpecificCache(apiName, params = {}) {
  const key = getCacheKey(apiName, params)
  cache.delete(key)
  console.log(`已清除缓存: ${key}`)
}

// 获取缓存信息并清理过期缓存
function getCacheInfo() {
  const now = Date.now()
  const validCaches = []
  const expiredCaches = []
  
  for (const [key, data] of cache.entries()) {
    if (isValidCache(data)) {
      validCaches.push({
        key,
        timestamp: data.timestamp,
        age: Math.round((now - data.timestamp) / 1000) + 's'
      })
    } else {
      expiredCaches.push(key)
      cache.delete(key)
    }
  }
  
  console.log('有效缓存:', validCaches)
  console.log('已清理过期缓存:', expiredCaches)
  
  return {
    validCount: validCaches.length,
    expiredCount: expiredCaches.length,
    validCaches,
    expiredCaches
  }
}

// 强制刷新所有数据（清除缓存并重新调用所有API）
async function forceRefreshAllData() {
  console.log('开始强制刷新所有数据...')
  clearCache()
  
  // 重新调用所有API
  await Promise.all([
    getCoreKpi(),
    getStatisticsData(),
    getUrgentProblem(),
    getTimeline(),
    getCustomerPayMoney(),
    CenterGetSalesFunnel(),
    CenterGetGoldContactTime(),
    // 客户相关数据需要在选中客户后才能获取
    selectedContact.value ? getCustomerForm() : Promise.resolve(),
    selectedContact.value ? getCustomerChat() : Promise.resolve(),
    selectedContact.value ? getCustomerCall() : Promise.resolve()
  ])
  
  console.log('所有数据刷新完成')
}

// LIFECYCLE HOOKS
onMounted(async () => {
  try {
    // 输出缓存状态信息
    console.log('Sale页面缓存系统已初始化，缓存时长:', CACHE_DURATION / (1000 * 60), '分钟')
    
    isPageLoading.value = true
    await getCoreKpi()
    await CenterGetGoldContactTime()
    await CenterGetSalesFunnel()
    await getCustomerForm()
    await getCustomerChat()
    await getUrgentProblem()
    await getCustomerCall()
    await getTimeline()
    await getCustomerPayMoney()
    
    // 输出初始缓存信息
    getCacheInfo()
    
    // 开发环境下暴露缓存管理函数到全局对象，方便调试
    if (process.env.NODE_ENV === 'development') {
      window.saleCache = {
        clearCache,
        clearSpecificCache,
        getCacheInfo,
        forceRefreshAllData,
        cache
      }
      console.log('开发模式：缓存管理函数已暴露到 window.saleCache')
    }

    // 等待数据加载完成后选择默认客户
    await nextTick();
    
    // 优先从API数据中选择第一个客户
    if (formattedCustomersList.value.length > 0) {
      selectedContactId.value = formattedCustomersList.value[0].id;
    } else {
      // 否则选择MOCK数据中的第一个高优先级联系人
      const highPriorityContacts = MOCK_DATA.contacts.filter(
        (contact) => contact.priority === "high"
      );
      if (highPriorityContacts.length > 0) {
        selectedContactId.value = highPriorityContacts[0].id;
      }
    }
  } catch (error) {
    // 静默处理错误
  } finally {
    isPageLoading.value = false
  }
});
</script>

<style lang="scss" scoped>
body {
  margin: 0;
  padding: 0;
}
// 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;

// 响应式混合器
@mixin mobile {
  @media (max-width: 768px) {
    @content;
  }
}

@mixin tablet {
  @media (max-width: 1023px) and (min-width: 769px) {
    @content;
  }
}

@mixin desktop {
  @media (min-width: 1024px) {
    @content;
  }
}

.sales-dashboard {
  background: #ffffff;
  min-height: 100vh;
  color: $slate-800;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-size: 16px;
  line-height: 1.6;

  @include mobile {
    font-size: 14px;
    line-height: 1.5;
  }

  *, *::before, *::after {
    box-sizing: border-box;
  }
}
// 主要布局
.main-layout {
  width: 100vw;
  margin: 0 auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;

  @include desktop {
    gap: 1.5rem;
  }

  @include tablet {
    width: 90vw;
  }

  @include mobile {
    width: 95vw;
    padding: 0.75rem;
    gap: 0.75rem;
  }

  @media (max-width: 480px) {
    width: 98vw;
    padding: 0.5rem;
    gap: 0.5rem;
  }
}

// 智能任务清单（原左侧边栏，现在在上方）
.sidebar {
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(20px);
  border-radius: 1rem;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  overflow: hidden;
  height: fit-content;
  max-height: 400px;
  display: flex;
  flex-direction: column;

  @include desktop {
    max-height: 450px;
  }

  @include tablet {
    border-radius: 0.875rem;
    max-height: 420px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
  }

  @include mobile {
    border-radius: 0.75rem;
    max-height: calc(100vh - 120px);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
  }

  @media (max-width: 480px) {
    border-radius: 0.5rem;
    max-height: calc(100vh - 100px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
  }

  .sidebar-header {
    padding: 1.5rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    background: linear-gradient(
      135deg,
      rgba(102, 126, 234, 0.1),
      rgba(118, 75, 162, 0.1)
    );
    display: flex;
    align-items: center;
    justify-content: space-between;

    @include desktop {
      padding: 1.75rem;
    }

    @include mobile {
      padding: 1.25rem;
    }

    @media (max-width: 480px) {
      padding: 1rem;
    }

    h2 {
      margin: 0 0 0.5rem 0;
      font-size: 1.125rem;
      font-weight: 600;
      color: $slate-800;

      @include desktop {
        font-size: 1.25rem;
      }

      @include mobile {
        font-size: 1rem;
      }

      @media (max-width: 480px) {
        font-size: 0.9375rem;
      }
    }

    .task-summary {
      display: flex;
      align-items: baseline;
      gap: 0.25rem;

      .task-count {
        font-size: 1.5rem;
        font-weight: 700;
        color: #667eea;

        @include desktop {
          font-size: 1.75rem;
        }

        @include mobile {
          font-size: 1.375rem;
        }

        @media (max-width: 480px) {
          font-size: 1.25rem;
        }
      }

      .task-label {
        font-size: 0.875rem;
        color: $slate-500;

        @include desktop {
          font-size: 0.9375rem;
        }

        @include mobile {
          font-size: 0.8125rem;
        }
      }
    }
  }

  .sidebar-content {
    flex: 1;
    overflow-y: auto;
  }
}

// 主要内容区域
.main-content {
  display: flex;
  flex-direction: column;
  gap: 2rem;

  @include desktop {
    gap: 2.5rem;
  }

  @include mobile {
    gap: 1.5rem;
  }

  @media (max-width: 480px) {
    gap: 1rem;
  }

  .detail-section {
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: blur(20px);
    border-radius: 1rem;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
    overflow: hidden;

    @include tablet {
      border-radius: 0.875rem;
      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
    }

    @include mobile {
      border-radius: 0.75rem;
      box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
    }

    @media (max-width: 480px) {
      border-radius: 0.5rem;
      box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
    }

    .section-header {
      padding: 1.5rem;
      border-bottom: 1px solid rgba(0, 0, 0, 0.05);
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: linear-gradient(
        135deg,
        rgba(102, 126, 234, 0.05),
        rgba(118, 75, 162, 0.05)
      );

      @include desktop {
        padding: 1.75rem;
        flex-direction: row;
        align-items: center;
        gap: 2rem;
      }

      @include tablet {
        flex-direction: row;
        align-items: center;
        gap: 1.5rem;
      }

      @include mobile {
        padding: 1.25rem;
        flex-direction: column;
        gap: 1rem;
        align-items: flex-start;
      }

      @media (max-width: 480px) {
        padding: 1rem;
        gap: 0.75rem;
      }

      h2 {
        margin: 0;
        font-size: 1.125rem;
        font-weight: 600;
        color: $slate-800;

        @include desktop {
          font-size: 1.25rem;
        }

        @include mobile {
          font-size: 1rem;
        }

        @media (max-width: 480px) {
          font-size: 0.9375rem;
        }
      }

      .section-actions {
        display: flex;
        gap: 0.75rem;

        // PC端保持一致布局
        @media (min-width: 1024px) {
          gap: 1rem;
          flex-wrap: nowrap;
        }

        // 平板端适配
        @media (max-width: 1023px) and (min-width: 769px) {
          gap: 0.75rem;
          flex-wrap: nowrap;
        }

        // 移动端适配
        @media (max-width: 768px) {
          gap: 0.5rem;
          width: 100%;
          justify-content: flex-start;
          flex-wrap: nowrap;
        }

        // 小屏移动端适配
        @media (max-width: 480px) {
          gap: 0.375rem;
          flex-wrap: wrap;
        }

        .action-btn {
          padding: 0.5rem 1rem;
          border-radius: 0.5rem;
          font-size: 0.875rem;
          font-weight: 500;
          cursor: pointer;
          transition: all 0.2s;
          border: none;
          touch-action: manipulation;
          white-space: nowrap;

          // PC端保持一致布局
          @media (min-width: 1024px) {
            padding: 0.625rem 1.25rem;
            font-size: 0.875rem;
          }

          // 平板端适配
          @media (max-width: 1023px) and (min-width: 769px) {
            padding: 0.5rem 1rem;
            font-size: 0.875rem;
          }

          // 移动端适配
          @media (max-width: 768px) {
            padding: 0.375rem 0.75rem;
            font-size: 0.8125rem;
          }

          // 小屏移动端适配
          @media (max-width: 480px) {
            padding: 0.25rem 0.5rem;
            font-size: 0.75rem;
            min-width: 60px;
          }

          &.primary {
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;

            &:hover {
              transform: translateY(-1px);
              box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
            }
          }

          &.secondary {
            background: $white;
            color: $slate-700;
            border: 1px solid $slate-300;

            &:hover {
              background: $slate-50;
              border-color: $slate-400;
            }
          }
        }
      }

      .view-toggle {
        display: flex;
        background: $slate-100;
        border-radius: 0.5rem;
        padding: 0.25rem;

        .toggle-btn {
          padding: 0.5rem 1rem;
          border: none;
          background: transparent;
          color: $slate-600;
          font-size: 0.875rem;
          border-radius: 0.375rem;
          cursor: pointer;
          transition: all 0.2s;

          &.active {
            background: $white;
            color: $slate-800;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
          }

          &:hover:not(.active) {
            color: $slate-800;
          }
        }
      }
    }

    .section-content {
      padding: 0.5rem;

      @media (max-width: 768px) {
        padding: 1.25rem;
      }

      @media (max-width: 480px) {
        padding: 1rem;
      }
    }
  }

  .detail-section {
    flex: 0 0 auto;
  }
}

// 销售漏斗和时间线区域样式
.funnel-section,
.timeline-section,
.raw-data-section {
  grid-column: 1 / -1;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(20px);
  border-radius: 1rem;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  overflow: hidden;
  margin-bottom: 1.5rem;
  width: 100%;

  @include tablet {
    border-radius: 0.875rem;
    margin-bottom: 1.25rem;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
  }

  @include mobile {
    border-radius: 0.75rem;
    margin-bottom: 1rem;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
  }

  @media (max-width: 480px) {
    border-radius: 0.5rem;
    margin-bottom: 0.75rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
  }

  .section-header {
    padding: 1.5rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    background: linear-gradient(
      135deg,
      rgba(102, 126, 234, 0.05),
      rgba(118, 75, 162, 0.05)
    );

    @media (max-width: 768px) {
      padding: 1.25rem;
    }

    @media (max-width: 480px) {
      padding: 1rem;
    }

    h2 {
      margin: 0;
      font-size: 1.125rem;
      font-weight: 600;
      color: $slate-800;

      @media (max-width: 768px) {
        font-size: 1rem;
      }

      @media (max-width: 480px) {
        font-size: 0.9375rem;
      }
    }

    .section-subtitle {
      margin: 0.5rem 0 0 0;
      font-size: 0.875rem;
      color: $slate-600;
      font-weight: 400;

      @media (max-width: 768px) {
        font-size: 0.8125rem;
      }

      @media (max-width: 480px) {
        font-size: 0.75rem;
      }
    }
  }

  .section-content {
    padding: 1.5rem;

    @media (max-width: 768px) {
      padding: 1.25rem;
    }

    @media (max-width: 480px) {
      padding: 1rem;
    }
  }
}

// 独立的数据分析区域 - 跨越整个宽度
.analytics-section-full {
  grid-column: 1 / -1;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(20px);
  border-radius: 1rem;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  overflow: hidden;
  width: 100%;
  min-height: 400px;

  @include desktop {
    min-height: 150px;
  }

  @include tablet {
    min-height: 380px;
    border-radius: 0.875rem;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
  }

  @include mobile {
    border-radius: 0.75rem;
    min-height: 320px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
  }

  @media (max-width: 480px) {
    border-radius: 0.5rem;
    min-height: 280px;
    margin-top: 0.5rem;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
  }

  .section-header {
    padding: 1.5rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: linear-gradient(
      135deg,
      rgba(102, 126, 234, 0.05),
      rgba(118, 75, 162, 0.05)
    );
    
    // 路由导航顶栏样式
    .route-header {
      width: 100%;
      padding: 0 2rem;
      
      .breadcrumb {
        display: flex;
        align-items: center;
        gap: 0.5rem;
        
        .breadcrumb-item {
          color: $slate-600;
          font-size: 0.875rem;
          font-weight: 500;
          
          &:not(.current) {
            cursor: pointer;
            transition: color 0.2s;
            
            &:hover {
               color: $primary;
             }
          }
          
          &.current {
            color: $slate-800;
            font-weight: 600;
          }
        }
        
        .breadcrumb-separator {
          color: $slate-400;
          font-size: 0.875rem;
        }
      }
      
      .user-name {
        color: $slate-800;
        font-size: 1.125rem;
        font-weight: 600;
        padding: 0.5rem 1rem;
        background: rgba(255, 255, 255, 0.8);
        border-radius: 0.5rem;
        border: 1px solid rgba(0, 0, 0, 0.1);
      }
    }

    // PC端保持一致布局
    @media (min-width: 1024px) {
      padding: 1.75rem;
      flex-direction: row;
      align-items: center;
      gap: 2rem;
    }

    // 平板端适配
    @media (max-width: 1023px) and (min-width: 769px) {
      padding: 1.5rem;
      flex-direction: row;
      align-items: center;
      gap: 1.5rem;
    }

    // 移动端适配
    @media (max-width: 768px) {
      padding: 1.25rem;
      flex-direction: column;
      gap: 1rem;
      align-items: flex-start;
    }

    // 小屏移动端适配
    @media (max-width: 480px) {
      padding: 1rem;
      gap: 0.75rem;
    }

    h2 {
      margin: 0;
      font-size: 1.125rem;
      font-weight: 600;
      color: $slate-800;

      @media (max-width: 768px) {
        font-size: 1rem;
      }

      @media (max-width: 480px) {
        font-size: 0.9375rem;
      }
    }

    .view-toggle {
        display: flex;
        background: $slate-100;
        border-radius: 0.5rem;
        padding: 0.25rem;

        @include desktop {
          width: auto;
          flex-wrap: nowrap;
          justify-content: flex-start;
        }

        @include tablet {
          width: auto;
          flex-wrap: nowrap;
          justify-content: flex-start;
        }

        @include mobile {
          width: 100%;
          justify-content: space-between;
          flex-wrap: nowrap;
        }

        @media (max-width: 480px) {
          flex-wrap: wrap;
          gap: 0.25rem;
          justify-content: flex-start;
        }

      .toggle-btn {
          padding: 0.5rem 1rem;
          border: none;
          background: transparent;
          color: $slate-600;
          font-size: 0.875rem;
          border-radius: 0.375rem;
          cursor: pointer;
          transition: all 0.2s;
          touch-action: manipulation;
          white-space: nowrap;

          @include desktop {
            padding: 0.5rem 1.25rem;
            flex: none;
          }

          @include tablet {
            padding: 0.5rem 1rem;
            flex: none;
          }

          @include mobile {
            padding: 0.375rem 0.75rem;
            font-size: 0.8125rem;
            flex: 1;
          }

          @media (max-width: 480px) {
            padding: 0.25rem 0.5rem;
            font-size: 0.75rem;
            min-width: 60px;
            flex: none;
          }

        &.active {
          background: $white;
          color: $slate-800;
          box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        }

        &:hover:not(.active) {
          color: $slate-800;
        }
      }
    }
  }

  .section-content {
    padding: 1.5rem;

    @include desktop {
      padding: 1.75rem;
    }

    @include mobile {
      padding: 1.25rem;
    }

    @media (max-width: 480px) {
      padding: 1rem;
    }
  }

  // 局部加载状态样式
  .section-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 3rem;
    min-height: 200px;
    
    .loading-spinner {
      width: 40px;
      height: 40px;
      border: 3px solid #e2e8f0;
      border-top: 3px solid #3b82f6;
      border-radius: 50%;
      animation: spin 1s linear infinite;
      margin-bottom: 1rem;
    }
    
    .loading-text {
      color: #64748b;
      font-size: 0.9rem;
    }
  }

  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
}

</style>
