/* AI_CHANGELOG
| 日期 | Prompt | 变更 |
|------|--------|------|
| 2026-03-23 | 角色路由+页面权限守卫 | onShow 添加 checkPageAccess 权限守卫 |
*/
import { checkPageAccess } from '../../utils/auth-guard'
import type { TaskDetail, Note } from '../../utils/mock-data'
import { fetchTaskDetail, fetchTaskByMember, createNote, deleteNote } from '../../services/api'
import { sortByTimestamp } from '../../utils/sort'
import { formatRelativeTime } from '../../utils/time'
import { formatStorageLevel } from '../../utils/storage-level'

/** 维客线索项 */
interface RetentionClue {
  tag: string
  tagColor: 'primary' | 'success' | 'purple' | 'error'
  emoji: string
  text: string
  source: string
  desc?: string
  expanded?: boolean
}

/** 服务记录项 */
interface ServiceRecord {
  table: string
  type: string
  typeClass: 'basic' | 'vip' | 'tip' | 'recharge' | 'incentive'
  /** 卡片类型：course=普通课，recharge=充值提成 */
  recordType?: 'course' | 'recharge'
  duration: number       // 折算后课时（小时，number）
  durationRaw?: number   // 折算前课时（小时，number，可选）
  income: number         // 收入（元，整数）
  /** 是否预估金额 */
  isEstimate?: boolean
  drinks: string
  date: string
}

/** 服务汇总 */
interface ServiceSummary {
  totalHours: number
  totalIncome: number
  avgIncome: number
}

Page({
  data: {
    pageState: 'loading' as 'loading' | 'empty' | 'normal' | 'error',
    detail: null as TaskDetail | null,
    sortedNotes: [] as Note[],
    noteModalVisible: false,

    // --- 维客线索 ---
    retentionClues: [
      { tag: '', tagColor: 'primary', emoji: '', text: '', source: '', expanded: false },
      { tag: '', tagColor: 'success', emoji: '', text: '', source: '', desc: '', expanded: false },
      { tag: '', tagColor: 'error', emoji: '', text: '', source: '', desc: '', expanded: false },
    ] as RetentionClue[],

    // --- 话术参考 ---
    talkingPoints: [
      '',
      '',
      '',
    ] as string[],
    copiedIndex: -1,

    // --- 近期服务记录 ---
    serviceSummary: { totalHours: 0, totalIncome: 0, avgIncome: 0 } as ServiceSummary,
    serviceRecords: [
      { table: '', type: '', typeClass: 'basic', duration: 0, durationRaw: 0, income: 0, isEstimate: false, drinks: '', date: '' },
      { table: '', type: '', typeClass: 'vip', duration: 0, durationRaw: 0, income: 0, isEstimate: false, drinks: '', date: '' },
      { table: '', type: '', typeClass: 'recharge', recordType: 'recharge', duration: 0, durationRaw: 0, income: 0, isEstimate: false, drinks: '', date: '' },
    ] as ServiceRecord[],

    // --- 放弃弹窗 ---
    abandonModalVisible: false,

    // --- 手机号显示 ---
    phoneVisible: false,

    // --- 储值等级 ---
    storageLevel: '',

    // --- 关系等级相关 ---
    relationLevel: 'poor' as 'poor' | 'normal' | 'good' | 'excellent',
    relationLevelText: '',
    relationColor: '',

    // --- Banner 背景（根据任务类型动态切换）---
    bannerBgSvg: '/assets/images/banner-bg-red-aurora.svg',

    // --- 调试面板 ---
    showDebugPanel: false,
    debugTaskType: 'high_priority_recall',
    debugHeartScore: 8.5,
    debugShowExpandBtn: true,  // 调试：备注弹窗是否显示展开/收起按钮

    // --- AI 配色 ---
    aiColor: 'indigo' as 'red' | 'orange' | 'yellow' | 'blue' | 'indigo' | 'purple',
  },

  onLoad(options: { id?: string; memberId?: string }) {
    const id = options?.id || ''
    const memberId = options?.memberId || ''
    // 随机 AI 配色
    const aiColors = ['red', 'orange', 'yellow', 'blue', 'indigo', 'purple'] as const
    const aiColor = aiColors[Math.floor(Math.random() * aiColors.length)]
    this.setData({ aiColor })
    if (id) {
      this.loadData(id)
    } else if (memberId) {
      // CHANGE 2026-03-25 | 绩效页跳转：无 task_id 时按 member_id 查询最高优先级任务
      this.loadByMember(memberId)
    } else {
      this.setData({ pageState: 'empty' })
    }
  },

  onShow() {
    // 权限守卫：检查登录状态、账号禁用、角色权限
    checkPageAccess('pages/task-detail/task-detail')
  },

  async loadData(id: string) {
    this.setData({ pageState: 'loading' })
    wx.showLoading({ title: '加载中...', mask: true })
    try {
      const detail = await fetchTaskDetail(id)
      if (!detail) {
        this.setData({ pageState: 'empty' })
        return
      }
      
      // 根据任务类型设置 Banner 背景
      let bannerBgSvg = '/assets/images/banner-bg-red-aurora.svg'
      if (detail.taskType === 'high_priority_recall') {
        bannerBgSvg = '/assets/images/banner-bg-red-aurora.svg'
      } else if (detail.taskType === 'priority_recall') {
        bannerBgSvg = '/assets/images/banner-bg-orange-aurora.svg'
      } else if (detail.taskType === 'relationship_building') {
        bannerBgSvg = '/assets/images/banner-bg-pink-aurora.svg'
      } else if (detail.taskType === 'follow_up_visit') {
        bannerBgSvg = '/assets/images/banner-bg-teal-aurora.svg'
      }
      
      // 附加 timeLabel 字段
      const notes = detail.notes || []
      const notesWithLabel = notes.map((n: Note) => ({
        ...n,
        timeLabel: formatRelativeTime(n.createdAt),
      }))
      const sorted = sortByTimestamp(notesWithLabel) as (Note & { timeLabel: string })[]
      // G4: 根据 balance 计算储值等级
      const storageLevel = formatStorageLevel(detail.balance)

      this.updateRelationshipDisplay(detail.heartScore)
      this.setData({ 
        pageState: 'normal', 
        detail, 
        sortedNotes: sorted,
        debugHeartScore: detail.heartScore,
        bannerBgSvg,
        storageLevel,
        // 从 detail 中提取嵌套模块数据到 data 顶层，供 WXML 直接绑定
        retentionClues: (detail.retentionClues || []) as RetentionClue[],
        talkingPoints: detail.talkingPoints || [],
        serviceSummary: detail.serviceSummary || { totalHours: 0, totalIncome: 0, avgIncome: 0 },
        // CHANGE 2026-03-27 | 清洗 serviceRecords：null 值转为组件期望的默认值
        // 小程序组件 Number/String property 收到 null 时行为不确定，需显式转换
        serviceRecords: (detail.serviceRecords || []).map((r: any) => ({
          ...r,
          durationRaw: r.durationRaw ?? 0,
          drinks: r.drinks ?? '',
        })),
      })
    } catch (_e) {
      this.setData({ pageState: 'error' })
    } finally {
      wx.hideLoading()
    }
  },

  /** 按 member_id 查询最高优先级任务，再加载详情 */
  async loadByMember(memberId: string) {
    // CHANGE 2026-03-25 | 修复：fetchTaskByMember 已返回完整详情，
    // 直接用返回的 id 走 loadData 标准流程，必须 await 避免 finally 竞态
    try {
      const detail = await fetchTaskByMember(memberId)
      if (!detail || !detail.id) {
        this.setData({ pageState: 'empty' })
        return
      }
      await this.loadData(String(detail.id))
    } catch (_e) {
      this.setData({ pageState: 'empty' })
    }
  },

  /** 更新关系等级显示 */
  updateRelationshipDisplay(score: number) {
    let level: 'poor' | 'normal' | 'good' | 'excellent' = 'poor'
    let text = '待发展'
    let color = '#64748b'  // 蓝灰色，区别于蓝色爱心

    if (score > 8.5) {
      level = 'excellent'
      text = '很好'
      color = '#e91e63'  // 深粉色，区别于粉红爱心
    } else if (score >= 6) {
      level = 'good'
      text = '良好'
      color = '#ea580c'  // 深橙色，区别于橙色爱心
    } else if (score >= 3.5) {
      level = 'normal'
      text = '一般'
      color = '#eab308'  // 金黄色，区别于黄色爱心
    }

    this.setData({
      relationLevel: level,
      relationLevelText: text,
      relationColor: color,
    })
  },

  /** 返回 */
  onBack() {
    wx.navigateBack()
  },

  /** 重试 */
  onRetry() {
    const id = this.data.detail?.id || ''
    this.loadData(id)
  },

  /** 查看/隐藏手机号 */
  onTogglePhone() {
    this.setData({ phoneVisible: !this.data.phoneVisible })
  },

  /** 复制手机号 */
  onCopyPhone() {
    const phone = this.data.detail?.customerPhone || ''
    if (!phone) {
      wx.showToast({ title: '暂无手机号', icon: 'none' })
      return
    }
    wx.setClipboardData({
      data: phone,
      success: () => {
        wx.showToast({ title: '手机号码已复制', icon: 'none' })
      },
    })
  },

  /** 展开/收起维客线索描述 */
  onToggleClue(e: WechatMiniprogram.BaseEvent) {
    const idx = e.currentTarget.dataset.index as number
    const key = `retentionClues[${idx}].expanded`
    const current = this.data.retentionClues[idx]?.expanded || false
    this.setData({ [key]: !current })
  },

  /** 复制话术 */
  onCopySpeech(e: WechatMiniprogram.BaseEvent) {
    const idx = e.currentTarget.dataset.index as number
    const text = this.data.talkingPoints[idx]
    if (!text) return
    wx.setClipboardData({
      data: text,
      success: () => {
        this.setData({ copiedIndex: idx })
        setTimeout(() => this.setData({ copiedIndex: -1 }), 2000)
      },
    })
  },

  /** 打开备注弹窗 */
  onAddNote() {
    this.setData({ noteModalVisible: true })
  },

  /** 备注弹窗确认 */
  async onNoteConfirm(e: WechatMiniprogram.CustomEvent) {
    const { content, serviceScore, returnScore } = e.detail
    const detail = this.data.detail
    if (!detail) return

    this.setData({ noteModalVisible: false })
    wx.showLoading({ title: '保存中...', mask: true })

    try {
      // CHANGE 2026-03-27 | 联调：调真实后端 API 创建备注
      const result = await createNote({
        targetId: detail.customerId ?? Number(detail.id),
        content,
        taskId: detail.id ? Number(detail.id) : undefined,
        ratingServiceWillingness: serviceScore > 0 ? serviceScore : undefined,
        ratingRevisitLikelihood: returnScore > 0 ? returnScore : undefined,
      })
      wx.hideLoading()
      wx.showToast({ title: '备注已保存', icon: 'success' })

      // 用后端返回的数据构建 Note 对象，追加到列表
      const newNote: Note = {
        id: String(result.id),
        content: result.content || content,
        tagType: result.type || 'normal',
        tagLabel: result.type === 'follow_up' ? '回访' : '普通',
        createdAt: result.createdAt || new Date().toLocaleString('zh-CN', { hour12: false }),
        score: result.aiScore || undefined,
      }
      this.setData({ sortedNotes: [{ ...newNote, timeLabel: '刚刚' }, ...this.data.sortedNotes] })

      // CHANGE 2026-03-27 | AI 评分轮询：后台异步等待 aiScore 返回后自动更新星星
      if (!result.aiScore) {
        this._pollAiScore(String(result.id), 0)
      }
    } catch (err) {
      wx.hideLoading()
      console.error('[task-detail] createNote failed:', err)
      wx.showToast({ title: '保存失败', icon: 'none' })
    }
  },

  /** CHANGE 2026-03-27 | AI 评分轮询：每 4 秒查一次，最多 5 次（20 秒） */
  _pollAiScore(noteId: string, attempt: number) {
    if (attempt >= 5) return
    setTimeout(async () => {
      try {
        const token = wx.getStorageSync('token')
        const detail = this.data.detail
        if (!detail || !token) return
        // 查 task_detail 接口获取最新备注列表
        const taskDetail = await fetchTaskDetail(String(detail.id))
        if (!taskDetail?.notes) { this._pollAiScore(noteId, attempt + 1); return }
        const found = taskDetail.notes.find((n: any) => String(n.id) === noteId)
        if ((found as any)?.aiScore || found?.score) {
          // 更新 sortedNotes 中对应备注的 score
          const updated = this.data.sortedNotes.map(n =>
            String(n.id) === noteId ? { ...n, score: (found as any).aiScore || found!.score } : n
          )
          this.setData({ sortedNotes: updated })
        } else {
          this._pollAiScore(noteId, attempt + 1)
        }
      } catch {
        this._pollAiScore(noteId, attempt + 1)
      }
    }, 4000)
  },

  /** 备注弹窗取消 */
  onNoteCancel() {
    this.setData({ noteModalVisible: false })
  },

  /** 删除备注 */
  onDeleteNote(e: WechatMiniprogram.BaseEvent) {
    const noteId = e.currentTarget.dataset.id as string
    wx.showModal({
      title: '删除备注',
      content: '确定要删除这条备注吗？删除后无法恢复。',
      confirmColor: '#e34d59',
      success: async (res) => {
        if (res.confirm) {
          try {
            // CHANGE 2026-03-27 | 联调：调真实后端 API 删除备注
            await deleteNote(Number(noteId))
            const notes = this.data.sortedNotes.filter((n) => String(n.id) !== noteId)
            this.setData({ sortedNotes: notes })
            wx.showToast({ title: '已删除', icon: 'success' })
          } catch (err) {
            console.error('[task-detail] deleteNote failed:', err)
            wx.showToast({ title: '删除失败', icon: 'none' })
          }
        }
      },
    })
  },

  /** 放弃/取消放弃 */
  onAbandon() {
    // 如果已放弃，直接取消放弃（不需要二次确认）
    if (this.data.detail?.status === 'abandoned') {
      this.cancelAbandon()
      return
    }
    // 否则打开放弃弹窗
    this.setData({ abandonModalVisible: true })
  },

  /** 取消放弃 - 直接修改状态 */
  cancelAbandon() {
    wx.showLoading({ title: '处理中...' })
    setTimeout(() => {
      wx.hideLoading()
      // 更新状态为 pending
      this.setData({ 'detail.status': 'pending' })
      wx.showToast({ title: '已取消放弃', icon: 'success' })
    }, 500)
  },

  /** 放弃 — 确认 */
  onAbandonConfirm(_e: WechatMiniprogram.CustomEvent<{ reason: string }>) {
    this.setData({ abandonModalVisible: false })
    wx.showLoading({ title: '处理中...' })
    setTimeout(() => {
      wx.hideLoading()
      // 更新状态为 abandoned
      this.setData({ 'detail.status': 'abandoned' })
      wx.showToast({ title: '已放弃该客户的维护', icon: 'none' })
    }, 500)
  },

  /** 放弃 — 取消 */
  onAbandonCancel() {
    this.setData({ abandonModalVisible: false })
  },

  /** 问问助手 */
  onAskAssistant() {
    // CHANGE 2026-03-20 | T12.2: 从 task-detail 进入 chat 应传 taskId（非 customerId），
    // 使 chat 页面使用 contextType=task 入口，同一 taskId 始终复用同一对话
    const taskId = this.data.detail?.id || ''
    wx.navigateTo({
      url: `/pages/chat/chat?taskId=${taskId}`,
      fail: () => wx.showToast({ title: '页面跳转失败', icon: 'none' }),
    })
  },

  /** 查看全部服务记录 */
  onViewAllRecords() {
    // CHANGE 2026-03-20 | T12.2: 使用后端返回的 customerId 而非 task id
    const customerId = (this.data.detail as any)?.customerId || this.data.detail?.id || ''
    wx.navigateTo({
      url: `/pages/customer-service-records/customer-service-records?customerId=${customerId}`,
      fail: () => wx.showToast({ title: '页面跳转失败', icon: 'none' }),
    })
  },

  /** noop — 阻止弹窗背景点击冒泡 */
  noop() {},

  /** 切换调试面板 */
  toggleDebugPanel() {
    this.setData({ showDebugPanel: !this.data.showDebugPanel })
  },

  /** 调试 - 切换任务类型 */
  onDebugTaskType(e: WechatMiniprogram.BaseEvent) {
    const type = e.currentTarget.dataset.type as string
    const typeMap: Record<string, string> = {
      high_priority: '高优先召回',
      priority_recall: '优先召回',
      relationship: '关系构建',
      callback: '客户回访',
    }
    
    // 根据任务类型设置 Banner 背景
    let bannerBgSvg = '/assets/images/banner-bg-red-aurora.svg'
    if (type === 'high_priority_recall') {
      bannerBgSvg = '/assets/images/banner-bg-red-aurora.svg'
    } else if (type === 'priority_recall') {
      bannerBgSvg = '/assets/images/banner-bg-orange-aurora.svg'
    } else if (type === 'relationship_building') {
      bannerBgSvg = '/assets/images/banner-bg-pink-aurora.svg'
    } else if (type === 'follow_up_visit') {
      bannerBgSvg = '/assets/images/banner-bg-teal-aurora.svg'
    }
    
    this.setData({
      debugTaskType: type,
      'detail.taskTypeLabel': typeMap[type] || '高优先召回',
      bannerBgSvg,
    })
  },

  /** 调试 - 调整关系数值 */
  onDebugHeartScore(e: WechatMiniprogram.SliderChange) {
    const score = e.detail.value
    this.setData({
      debugHeartScore: score,
      'detail.heartScore': score,
    })
    this.updateRelationshipDisplay(score)
  },

  /** 调试 - 切换备注弹窗展开按钮 */
  onDebugToggleExpandBtn(e: WechatMiniprogram.BaseEvent) {
    const value = e.currentTarget.dataset.value as boolean
    this.setData({ debugShowExpandBtn: value })
  },
})
