﻿<template>
  <section class="workbench">
    <PanelHead
      v-if="showHeader"
      eyebrow="Personal Workspace"
      title="个人工作台"
      note="把今天要处理的待办、报销进度和制度更新集中到一个入口。"
    />

    <article class="panel assistant-hero">
      <div class="assistant-visual" aria-hidden="true">
        <span class="assistant-glow"></span>
        <img class="assistant-image" :src="robotAssistant" alt="" />
      </div>

      <div class="assistant-copy">
        <h3>嗨，{{ assistantGreetingName }}，描述您想做的事，AI 会直接帮您处理</h3>
        <p>我会自动识别您的意图，协助完成费用申请、报销、查询和制度问答等业务工作，耐心把事情推进到可执行的下一步。</p>

        <div class="assistant-input">
          <input
            ref="fileInputRef"
            class="assistant-file-input"
            type="file"
            multiple
            accept=".pdf,.jpg,.jpeg,.png,.webp,.doc,.docx,.xls,.xlsx"
            @change="handleWorkbenchFilesChange"
          />
          <textarea
            v-model="assistantDraft"
            rows="1"
            placeholder="例如：我昨天请客户吃饭花了 860 元，还打车去了客户公司"
            @keydown.enter.prevent="handleWorkbenchEnter"
          />
        </div>

        <div v-if="selectedFiles.length" class="assistant-file-strip">
          <span class="assistant-file-note">已带入 {{ selectedFiles.length }} 份附件</span>
          <span v-for="file in selectedFiles" :key="file.name" class="assistant-file-chip">{{ file.name }}</span>
          <button type="button" class="assistant-file-clear" @click="clearSelectedFiles">清空</button>
        </div>

        <div class="assistant-tools">
          <button type="button" class="ghost-action" :disabled="Boolean(pendingAction)" @click="triggerFileUpload">
            <i class="mdi mdi-upload-outline"></i>
            <span>上传票据</span>
          </button>
          <button
            type="button"
            class="hero-action"
            :disabled="Boolean(pendingAction)"
            @click="handleExpenseConversationAction"
          >
            <i :class="pendingAction === 'expense' ? 'mdi mdi-loading mdi-spin' : expenseActionIcon"></i>
            <span>{{ pendingAction === 'expense' ? '处理中...' : expenseActionLabel }}</span>
          </button>
        </div>
      </div>
    </article>

    <div class="workbench-grid">
      <article class="panel list-panel">
        <div class="section-head">
          <div class="title-with-badge">
            <h3>报销待办</h3>
            <span class="alert-badge">{{ todoAlertCount }}</span>
          </div>
          <button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
        </div>

        <div class="list-body">
          <div v-for="item in todoItems" :key="item.title" class="todo-row">
            <WorkbenchListIcon
              :icon-key="item.iconKey"
              :color="item.color"
              :accent="item.accent"
            />

            <div class="todo-copy">
              <strong>{{ item.title }}</strong>
              <p class="todo-advice">
                <span class="todo-advice-label">{{ item.tipLabel }}</span>
                <span class="todo-advice-text">{{ item.suggestion }}</span>
              </p>
            </div>

            <button type="button" class="row-action" @click="emit('open-assistant')">{{ item.action }}</button>
          </div>
        </div>
      </article>

      <article class="panel list-panel">
        <div class="section-head">
          <div class="title-with-badge">
            <h3>报销进度</h3>
            <span class="alert-badge">{{ progressAlertCount }}</span>
          </div>
          <button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
        </div>

        <div class="list-body">
          <div v-for="item in progressItems" :key="item.id" class="progress-row">
            <WorkbenchListIcon
              :icon-key="item.iconKey"
              :color="item.color"
              :accent="item.accent"
            />

            <div class="todo-copy progress-copy">
              <strong>{{ item.title }}</strong>
              <p>提交时间：{{ item.date }}</p>
            </div>

            <strong class="progress-amount">{{ item.amount }}</strong>
            <span class="progress-status" :class="item.tone">{{ item.status }}</span>
          </div>
        </div>
      </article>
    </div>

    <article class="panel policy-panel">
      <div class="section-head">
        <h3>最新报销制度</h3>
        <button type="button" class="link-action">查看全部 <i class="mdi mdi-chevron-right"></i></button>
      </div>

      <div class="policy-table">
        <div class="policy-head policy-row">
          <span class="policy-title-cell">制度名称</span>
          <span class="policy-summary-cell">摘要</span>
          <span class="policy-date-cell">发布日期</span>
        </div>

        <div v-for="item in policyItems" :key="item.name" class="policy-row">
          <strong class="policy-title-cell">{{ item.name }}</strong>
          <span class="policy-summary-cell">{{ item.summary }}</span>
          <span class="policy-date-cell">{{ item.date }}</span>
        </div>
      </div>
    </article>
  </section>

</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import PanelHead from '../shared/PanelHead.vue'
import WorkbenchListIcon from '../shared/WorkbenchListIcon.vue'
import robotAssistant from '../../assets/robot-helper.png'
import { useSystemState } from '../../composables/useSystemState.js'
import { useToast } from '../../composables/useToast.js'
import { clearUserConversations, fetchLatestConversation } from '../../services/orchestrator.js'
import {
  ASSISTANT_SESSION_SNAPSHOT_EVENT,
  hasAssistantSessionSnapshot
} from '../../utils/assistantSessionSnapshot.js'

const props = defineProps({
  showHeader: { type: Boolean, default: true },
  assistantModalOpen: { type: Boolean, default: false }
})

const emit = defineEmits(['open-assistant'])
const { currentUser } = useSystemState()
const { toast } = useToast()
const assistantDraft = ref('')
const fileInputRef = ref(null)
const selectedFiles = ref([])
const pendingAction = ref('')
const latestExpenseConversation = ref(null)
const hasLocalExpenseSnapshot = ref(false)
const MAX_ATTACHMENTS = 10
const SESSION_TYPE_EXPENSE = 'expense'
const SESSION_TYPE_KNOWLEDGE = 'knowledge'

const hasExpenseConversation = computed(() =>
  Boolean(latestExpenseConversation.value?.conversation_id || latestExpenseConversation.value?.conversationId)
    || hasLocalExpenseSnapshot.value
)
const expenseActionLabel = computed(() => (hasExpenseConversation.value ? '继续报销' : '新建报销'))
const expenseActionIcon = computed(() => (hasExpenseConversation.value ? 'mdi mdi-history' : 'mdi mdi-magnify-scan'))
const assistantGreetingName = computed(() => {
  const user = currentUser.value || {}
  return String(user.name || user.username || '同事').trim() || '同事'
})

function buildSelectedFileKey(file) {
  return [file?.name, file?.size, file?.lastModified, file?.type].join('__')
}

function mergeSelectedFiles(existingFiles, incomingFiles) {
  const nextFiles = []
  const seen = new Set()

  for (const file of existingFiles) {
    const key = buildSelectedFileKey(file)
    if (seen.has(key)) continue
    seen.add(key)
    nextFiles.push(file)
  }

  let overflowCount = 0

  for (const file of incomingFiles) {
    const key = buildSelectedFileKey(file)
    if (seen.has(key)) continue
    if (nextFiles.length >= MAX_ATTACHMENTS) {
      overflowCount += 1
      continue
    }
    seen.add(key)
    nextFiles.push(file)
  }

  return {
    files: nextFiles,
    overflowCount
  }
}

function resolveCurrentUserId() {
  const user = currentUser.value || {}
  return String(user.username || user.name || 'anonymous').trim() || 'anonymous'
}

function buildAssistantPayload() {
  return {
    prompt: assistantDraft.value.trim(),
    source: 'workbench',
    files: Array.from(selectedFiles.value)
  }
}

function clearSelectedFiles() {
  selectedFiles.value = []
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
  }
}

function resetWorkbenchDraft() {
  assistantDraft.value = ''
  clearSelectedFiles()
}

function emitAssistant(payload) {
  emit('open-assistant', payload)
  resetWorkbenchDraft()
}

async function loadLatestConversation() {
  const payload = await fetchLatestConversation(resolveCurrentUserId(), SESSION_TYPE_EXPENSE, {
    preferRecoverable: true
  })
  return payload?.found ? payload.conversation || null : null
}

function handleWorkbenchEnter(event) {
  if (event.isComposing) {
    return
  }

  handleExpenseConversationAction()
}

function triggerFileUpload() {
  fileInputRef.value?.click()
}

function handleWorkbenchFilesChange(event) {
  const mergeResult = mergeSelectedFiles(selectedFiles.value, Array.from(event.target.files ?? []))
  selectedFiles.value = mergeResult.files
  if (mergeResult.overflowCount > 0) {
    toast(`一次最多上传 ${MAX_ATTACHMENTS} 份附件，已保留前 ${MAX_ATTACHMENTS} 份。`)
  }
  if (fileInputRef.value) {
    fileInputRef.value.value = ''
  }
}

async function refreshLatestExpenseConversation() {
  refreshLocalExpenseSnapshot()
  try {
    latestExpenseConversation.value = await loadLatestConversation()
  } catch (error) {
    console.warn('Failed to refresh latest expense conversation:', error)
    latestExpenseConversation.value = null
  }
}

function refreshLocalExpenseSnapshot() {
  hasLocalExpenseSnapshot.value = hasAssistantSessionSnapshot(resolveCurrentUserId(), SESSION_TYPE_EXPENSE)
}

function handleAssistantSessionSnapshotChange(event) {
  const sessionType = String(event?.detail?.sessionType || '').trim()
  if (!sessionType || sessionType === SESSION_TYPE_EXPENSE) {
    refreshLocalExpenseSnapshot()
  }
}

async function clearKnowledgeHistoryBeforeExpense() {
  await clearUserConversations(resolveCurrentUserId(), SESSION_TYPE_KNOWLEDGE)
}

async function handleExpenseConversationAction() {
  if (pendingAction.value) {
    return
  }

  const nextPayload = buildAssistantPayload()
  const shouldOpenImmediately = Boolean(nextPayload.prompt || nextPayload.files.length)

  if (shouldOpenImmediately) {
    emitAssistant({
      ...nextPayload,
      conversation: null
    })
    void clearKnowledgeHistoryBeforeExpense().catch((error) => {
      console.warn('Failed to clear knowledge history before expense:', error)
    })
    return
  }

  pendingAction.value = 'expense'

  try {
    await clearKnowledgeHistoryBeforeExpense()
    const conversation = await loadLatestConversation()
    latestExpenseConversation.value = conversation
    emitAssistant({
      ...nextPayload,
      conversation
    })
  } catch (error) {
    console.warn('Failed to open expense conversation:', error)
    toast(error?.message || '打开报销会话失败，请稍后重试。')
  } finally {
    pendingAction.value = ''
  }
}

const todoItems = [
  {
    title: '业务招待报销建议补参与人员',
    tipLabel: 'AI 建议',
    suggestion: '补充客户单位、客户人数、我方陪同人员',
    action: '去补充',
    iconKey: 'hospitality',
    color: 'var(--theme-primary-active)',
    accent: 'var(--theme-primary-soft-strong)'
  },
  {
    title: '差旅报销单待提交',
    tipLabel: 'AI 建议',
    suggestion: '补齐出发交通，可直接生成报销单',
    action: '继续填写',
    iconKey: 'travelDraft',
    color: 'var(--success-hover)',
    accent: 'var(--success-line)'
  },
  {
    title: '有 5 张票据未关联报销单',
    tipLabel: 'AI 建议',
    suggestion: '其中 3 张疑似交通费，可合并生成交通报销',
    action: '去整理',
    iconKey: 'receipts',
    color: 'var(--chart-blue)',
    accent: 'var(--theme-primary-soft-strong)'
  }
]

const todoAlertCount = todoItems.length

const progressItems = [
  {
    id: 'travel',
    title: '差旅报销',
    amount: '¥3,280',
    date: '2026-05-03',
    status: '主管审批中',
    tone: 'success',
    iconKey: 'flight',
    color: 'var(--theme-primary-active)',
    accent: 'var(--theme-primary-soft-strong)'
  },
  {
    id: 'transport',
    title: '交通报销',
    amount: '¥126',
    date: '2026-05-02',
    status: '财务复核中',
    tone: 'info',
    iconKey: 'transport',
    color: 'var(--chart-blue)',
    accent: 'var(--theme-primary-soft-strong)'
  },
  {
    id: 'office',
    title: '办公采购',
    amount: '¥458',
    date: '2026-05-01',
    status: '已到账',
    tone: 'mint',
    iconKey: 'procurement',
    color: 'var(--success)',
    accent: 'var(--success-line)'
  }
]

const progressAlertCount = progressItems.filter((item) => item.status !== '已到账').length

const policyItems = [
  {
    name: '差旅报销管理办法（2026版）',
    summary: '更新住宿标准与交通等级规则',
    date: '2026-05-04'
  },
  {
    name: '业务招待费用报销规范',
    summary: '明确参与人员与事由填写要求',
    date: '2026-05-02'
  },
  {
    name: '交通费用报销细则',
    summary: '补充网约车与停车费报销说明',
    date: '2026-04-28'
  },
  {
    name: '票据与附件提交规范通知',
    summary: '统一附件命名与上传要求',
    date: '2026-04-25'
  }
]

onMounted(() => {
  refreshLocalExpenseSnapshot()
  refreshLatestExpenseConversation()
  window.addEventListener(ASSISTANT_SESSION_SNAPSHOT_EVENT, handleAssistantSessionSnapshotChange)
})

onBeforeUnmount(() => {
  window.removeEventListener(ASSISTANT_SESSION_SNAPSHOT_EVENT, handleAssistantSessionSnapshotChange)
})

watch(
  () => props.assistantModalOpen,
  (open, previous) => {
    if (previous && !open) {
      refreshLatestExpenseConversation()
    }
  }
)
</script>

<style scoped src="../../assets/styles/components/personal-workbench.css"></style>
