import { computed, ref } from 'vue'

export default {
  name: 'TravelRequestDetailView',
  props: {
  request: {
    type: Object,
    default: () => ({})
  }
},
  emits: ['backToRequests', 'openAssistant'] ,
  setup(props, { emit }) {
    const expandedExpenseId = ref(null)
    const aiEntryOpen = ref(false)
    const aiDraft = ref('')
    const aiFileInput = ref(null)
    const aiEntrySeed = ref(2)
    const pendingAiExpense = ref(null)
    const uploadedAiFiles = ref([])
    const expenseItems = ref([
      {
        id: 'exp-1',
        time: '07-08',
        dayLabel: '第 1 天',
        name: '高铁票',
        category: '交通',
        desc: '上海虹桥 -> 杭州东',
        detail: '客户方案汇报前往现场',
        amount: '￥236.00',
        status: '规则通过',
        tone: 'ok',
        attachmentStatus: '2 份附件',
        attachmentHint: '车票 + 行程单',
        attachmentTone: 'ok',
        attachments: ['高铁票.pdf', '行程单.pdf'],
        riskLabel: '规则通过',
        riskText: '票据与行程匹配',
        riskTone: 'low'
      },
      {
        id: 'exp-2',
        time: '07-09',
        dayLabel: '第 2 天',
        name: '酒店住宿',
        category: '住宿',
        desc: '杭州西湖商务酒店',
        detail: '1 晚住宿，含早餐',
        amount: '￥1,180.00',
        status: '待补材料',
        tone: 'bad',
        attachmentStatus: '缺 1 份',
        attachmentHint: '缺少入住清单',
        attachmentTone: 'partial',
        attachments: ['酒店发票.jpg'],
        riskLabel: '待补材料',
        riskText: '需补酒店入住清单',
        riskTone: 'medium'
      },
      {
        id: 'exp-3',
        time: '07-10',
        dayLabel: '第 3 天',
        name: '出租车',
        category: '市内交通',
        desc: '客户公司往返酒店',
        detail: '含夜间打车 2 次',
        amount: '￥128.00',
        status: '需说明',
        tone: 'bad',
        attachmentStatus: '3 份附件',
        attachmentHint: '发票已上传',
        attachmentTone: 'ok',
        attachments: ['出租车发票1.jpg', '出租车发票2.jpg', '打车订单.png'],
        riskLabel: '超标说明',
        riskText: '1 笔夜间交通需补充说明',
        riskTone: 'medium'
      },
      {
        id: 'exp-4',
        time: '07-11',
        dayLabel: '第 4 天',
        name: '餐补',
        category: '补贴',
        desc: '差旅餐补',
        detail: '按 4 天标准自动计算',
        amount: '￥320.00',
        status: '规则通过',
        tone: 'ok',
        attachmentStatus: '系统生成',
        attachmentHint: '无需上传附件',
        attachmentTone: 'neutral',
        attachments: [],
        riskLabel: '规则通过',
        riskText: '补贴标准校验通过',
        riskTone: 'low'
      }
    ])

    const request = computed(() => ({
      id: props.request?.id ?? 'BR240712001',
      reason: props.request?.reason ?? '客户方案汇报',
      city: props.request?.city ?? '上海',
      period: props.request?.period ?? '07-08~07-11 (4天)',
      applyTime: props.request?.applyTime ?? '2024-07-07',
      amount: props.request?.amount ?? '￥3,680.00',
      node: props.request?.node ?? '财务审核',
      approval: props.request?.approval ?? '审批中',
      approvalTone: props.request?.approvalTone ?? 'info',
      travel: props.request?.travel ?? '已订酒店/机票',
      travelTone: props.request?.travelTone ?? 'low'
    }))

    const profile = {
      name: '张晓明',
      department: '财务管理员',
      avatar: '张'
    }

    const summaryItems = [
      { label: '出差城市', value: request.value.city, icon: 'mdi mdi-map-marker-path' },
      { label: '出差区间', value: request.value.period, icon: 'mdi mdi-clock-outline' },
      { label: '票据关联', value: '6 条明细 / 5 份材料', icon: 'mdi mdi-file-document-multiple-outline' },
      { label: '商旅状态', value: request.value.travel, icon: 'mdi mdi-airplane' },
      { label: '出差事由', value: request.value.reason, icon: 'mdi mdi-briefcase-outline' }
    ]

    const heroSummaryItems = computed(() => [
      { label: '单号', value: request.value.id, icon: 'mdi mdi-pound-box-outline' },
      { label: '申请类型', value: '差旅费申请/报销', icon: 'mdi mdi-tag-multiple' },
      ...summaryItems
    ])

    const currentProgressRingMotion = {
      initial: {
        scale: 1,
        opacity: 0.34,
      },
      enter: {
        scale: [1, 1.42, 1.78],
        opacity: [0.34, 0.16, 0],
        transition: {
          duration: 3.2,
          repeat: Infinity,
          repeatType: 'loop',
          repeatDelay: 0.85,
          ease: 'easeOut',
          times: [0, 0.5, 1],
        },
      },
    }

    const progressSteps = computed(() => {
      return [
        { index: 1, label: '提交申请', time: '07-11 08:46', done: true, active: true },
        { index: 2, label: '票据识别', time: '07-11 08:48', done: true, active: true },
        { index: 3, label: '费用归类', time: '07-11 08:49', done: true, active: true },
        { index: 4, label: '部门负责人审批', time: '07-11 11:28', done: true, active: true },
        { index: 5, label: '财务审批', time: '进行中', active: true, current: true },
        { index: 6, label: '归档入账', time: '待处理' }
      ]
    })

    const expenseTotal = computed(() => {
      const total = expenseItems.value.reduce((sum, item) => sum + parseCurrency(item.amount), 0)
      return formatCurrency(total)
    })
    const uploadedExpenseCount = computed(() => expenseItems.value.filter((item) => item.attachments.length).length)
    const canSendAiEntry = computed(() => Boolean(aiDraft.value.trim() || uploadedAiFiles.value.length))

    const detailNote = '本次出差用于客户方案汇报与现场沟通，需覆盖往返交通、住宿及市内交通费用。已完成主要票据上传，待补酒店入住清单后即可进入完整审批流程。'

    function toggleExpenseAttachments(id) {
      expandedExpenseId.value = expandedExpenseId.value === id ? null : id
    }

    function showExpenseRisk(item) {
      return Boolean(item.riskText)
    }

    function openAiEntry() {
      aiEntryOpen.value = false
      emit('openAssistant', {
        source: 'detail',
        prompt: '',
        request: request.value
      })
    }

    function closeAiEntry() {
      aiEntryOpen.value = false
      aiDraft.value = ''
      pendingAiExpense.value = null
      uploadedAiFiles.value = []
      if (aiFileInput.value) {
        aiFileInput.value.value = ''
      }
    }

    function parseCurrency(value) {
      return Number.parseFloat(String(value).replace(/[^\d.]/g, '')) || 0
    }

    function formatCurrency(value) {
      return `￥${value.toFixed(2)}`
    }

    function buildNextExpenseId() {
      aiEntrySeed.value += 1
      return `exp-ai-${aiEntrySeed.value}`
    }

    function inferExpenseCategory(text) {
      if (/高铁|火车|机票|航班|打车|出租车|地铁|公交|交通/.test(text)) return '交通'
      if (/酒店|住宿|房费/.test(text)) return '住宿'
      if (/餐|午饭|晚饭|早餐|餐补/.test(text)) return '餐饮'
      return '其他'
    }

    function inferExpenseName(text, category) {
      if (/高铁/.test(text)) return '高铁票'
      if (/机票|航班/.test(text)) return '机票'
      if (/出租车|打车/.test(text)) return '出租车'
      if (/酒店|住宿/.test(text)) return '酒店住宿'
      if (/餐补/.test(text)) return '餐补'
      if (/餐|午饭|晚饭|早餐/.test(text)) return '餐饮'
      return `${category}费用`
    }

    function inferAttachments(text, uploadedFiles = []) {
      if (uploadedFiles.length) {
        return {
          status: `${uploadedFiles.length} 份附件`,
          hint: uploadedFiles.map((file) => file.name).join(' + '),
          tone: 'ok',
          files: uploadedFiles.map((file) => file.name),
        }
      }

      if (/无需|免附件|系统生成/.test(text)) {
        return {
          status: '系统生成',
          hint: '无需上传附件',
          tone: 'neutral',
          files: [],
        }
      }

      const uploaded = /已上传|上传了|附上|附件/.test(text)
      const receipt = /发票/.test(text)
      const itinerary = /行程单/.test(text)
      const ticket = /车票|机票/.test(text)
      const hotelList = /入住清单/.test(text)
      const files = []

      if (receipt) files.push('发票.jpg')
      if (itinerary) files.push('行程单.pdf')
      if (ticket && !files.includes('票据.pdf')) files.push('票据.pdf')
      if (hotelList) files.push('入住清单.pdf')

      if (uploaded || files.length) {
        return {
          status: `${Math.max(files.length, 1)} 份附件`,
          hint: files.length ? files.join(' + ') : '已上传附件待识别',
          tone: 'ok',
          files: files.length ? files : ['附件1.jpg'],
        }
      }

      return {
        status: '缺 1 份',
        hint: '待补上传票据原件',
        tone: 'missing',
        files: [],
      }
    }

    function inferRisk(text, attachmentTone) {
      if (/夜间|超标|说明/.test(text)) {
        return {
          status: '需说明',
          tone: 'bad',
          riskLabel: '超标说明',
          riskText: '识别到特殊场景，建议补充费用说明',
          riskTone: 'medium',
        }
      }

      if (attachmentTone === 'missing' || attachmentTone === 'partial') {
        return {
          status: '待补材料',
          tone: 'bad',
          riskLabel: '待补材料',
          riskText: '附件不完整，需补齐后再提交审批',
          riskTone: 'medium',
        }
      }

      return {
        status: '规则通过',
        tone: 'ok',
        riskLabel: '规则通过',
        riskText: 'AI 识别通过，字段已结构化',
        riskTone: 'low',
      }
    }

    function extractDateLabel(text) {
      const match = text.match(/(\d{1,2})月(\d{1,2})日|(\d{1,2})[-/.](\d{1,2})/)
      if (!match) {
        return { time: '07-12', dayLabel: `第 ${expenseItems.value.length + 1} 天` }
      }

      const month = String(match[1] || match[3] || '07').padStart(2, '0')
      const day = String(match[2] || match[4] || '12').padStart(2, '0')
      return { time: `${month}-${day}`, dayLabel: `第 ${expenseItems.value.length + 1} 天` }
    }

    function extractAmount(text) {
      const match = text.match(/(\d+(?:\.\d{1,2})?)\s*元/)
      return formatCurrency(Number.parseFloat(match?.[1] || '0'))
    }

    function buildAiExpense(text) {
      const category = inferExpenseCategory(text)
      const name = inferExpenseName(text, category)
      const dateInfo = extractDateLabel(text)
      const attachments = inferAttachments(text, uploadedAiFiles.value)
      const risk = inferRisk(text, attachments.tone)

      return {
        id: buildNextExpenseId(),
        time: dateInfo.time,
        dayLabel: dateInfo.dayLabel,
        name,
        category,
        desc: text.slice(0, 24),
        detail: text,
        amount: extractAmount(text),
        status: risk.status,
        tone: risk.tone,
        attachmentStatus: attachments.status,
        attachmentHint: attachments.hint,
        attachmentTone: attachments.tone,
        attachments: attachments.files,
        riskLabel: risk.riskLabel,
        riskText: risk.riskText,
        riskTone: risk.riskTone,
      }
    }

    const aiMessages = ref([
      {
        id: 'ai-msg-1',
        role: 'assistant',
        text: '请直接描述费用场景、日期、金额和是否已上传票据，我会整理成费用明细。',
      },
    ])

    function sendAiEntry() {
      const text = aiDraft.value.trim() || `已上传 ${uploadedAiFiles.value.length} 份单据，请根据附件识别费用。`
      if (!text && !uploadedAiFiles.value.length) return

      aiMessages.value.push({
        id: `ai-msg-user-${Date.now()}`,
        role: 'user',
        text: uploadedAiFiles.value.length ? `${text}\n附件：${uploadedAiFiles.value.map((file) => file.name).join('、')}` : text,
      })

      pendingAiExpense.value = buildAiExpense(text)

      aiMessages.value.push({
        id: `ai-msg-assistant-${Date.now()}`,
        role: 'assistant',
        text: `已识别为 ${pendingAiExpense.value.name}，金额 ${pendingAiExpense.value.amount}，可直接加入费用明细。`,
      })

      aiDraft.value = ''
    }

    function regenerateAiEntry() {
      if (!pendingAiExpense.value) return
      const sourceText = pendingAiExpense.value.detail
      pendingAiExpense.value = buildAiExpense(sourceText.replace('待补上传票据原件', '已上传发票'))
      aiMessages.value.push({
        id: `ai-msg-regenerate-${Date.now()}`,
        role: 'assistant',
        text: '已重新整理识别结果，你可以继续确认后加入费用明细。',
      })
    }

    function applyAiExpense() {
      if (!pendingAiExpense.value) return
      expenseItems.value.push({ ...pendingAiExpense.value })
      expandedExpenseId.value = pendingAiExpense.value.id
      aiMessages.value.push({
        id: `ai-msg-apply-${Date.now()}`,
        role: 'assistant',
        text: '该费用条目已加入下方费用明细表。',
      })
      pendingAiExpense.value = null
      aiDraft.value = ''
      uploadedAiFiles.value = []
      if (aiFileInput.value) {
        aiFileInput.value.value = ''
      }
      aiEntryOpen.value = false
    }

    function triggerAiUpload() {
      aiFileInput.value?.click()
    }

    function handleAiFilesChange(event) {
      const files = Array.from(event.target.files ?? [])
      uploadedAiFiles.value = files
    }

    return {
      emit,
      expandedExpenseId,
      aiEntryOpen,
      aiDraft,
      aiFileInput,
      aiEntrySeed,
      pendingAiExpense,
      uploadedAiFiles,
      expenseItems,
      request,
      profile,
      summaryItems,
      heroSummaryItems,
      currentProgressRingMotion,
      progressSteps,
      expenseTotal,
      uploadedExpenseCount,
      canSendAiEntry,
      detailNote,
      toggleExpenseAttachments,
      showExpenseRisk,
      openAiEntry,
      closeAiEntry,
      aiMessages,
      sendAiEntry,
      regenerateAiEntry,
      applyAiExpense,
      triggerAiUpload,
      handleAiFilesChange
    }
  }
}

