<template>
  <section class="digital-employee-list-panel digital-work-records">
    <Transition name="skill-view" mode="out-in">
      <!-- 列表视图 -->
      <EnterpriseListPage
        v-if="!selectedRunDetail"
        key="list"
        variant="digital-employee-list-panel digital-work-records-list-stage"
        :panel="false"
        :loading="loading && !runs.length"
        :error="errorMessage"
        :empty="!visibleRuns.length"
        :empty-state="workRecordsEmptyState"
        :show-pagination="!loading && !errorMessage && visibleRuns.length > 0"
        :current-page="currentPage"
        :page-size="pageSize"
        :show-page-size="false"
        :summary="paginationSummary"
        :total="filteredRuns.length"
        :total-pages="totalPages"
        loading-title="工作记录同步中"
        loading-message="正在读取数字员工近期执行记录"
        loading-icon="mdi mdi-clipboard-text-clock-outline"
        error-title="工作记录加载失败"
        @update:current-page="currentPage = $event"
      >
        <template #filters>
          <label class="list-search">
            <i class="mdi mdi-magnify"></i>
            <input
              v-model="listKeyword"
              type="search"
              placeholder="搜索摘要、Run ID..."
            />
          </label>

          <AuditPickerFilter
            id="module"
            title="选择工作模块"
            close-label="关闭选择"
            :active-filter-popover="activeFilterPopover"
            :label="activeModule === '全部' ? '工作模块' : activeModule"
            :options="modulePickerOptions"
            :selected-value="activeModule"
            @toggle="toggleFilterPopover"
            @close="closeFilterPopover"
            @select="selectModule"
          />

          <AuditPickerFilter
            id="status"
            title="选择执行状态"
            close-label="关闭选择"
            :active-filter-popover="activeFilterPopover"
            :label="activeStatus === '全部' ? '执行状态' : activeStatus"
            :options="statusPickerOptions"
            :selected-value="activeStatus"
            @toggle="toggleFilterPopover"
            @close="closeFilterPopover"
            @select="selectStatus"
          />
        </template>

        <template #actions>
          <button
            v-if="listKeyword || activeFilterTokens.length"
            class="ghost-filter-btn"
            type="button"
            @click="resetFilters"
          >
            <i class="mdi mdi-filter-remove-outline"></i>
            <span>清空筛选</span>
          </button>
          <AuditPickerFilter
            id="refreshInterval"
            title="选择刷新时间"
            close-label="关闭刷新时间选择"
            :active-filter-popover="activeFilterPopover"
            :label="`刷新时间 ${refreshIntervalLabel}`"
            :options="refreshIntervalPickerOptions"
            :selected-value="refreshInterval"
            @toggle="toggleFilterPopover"
            @close="closeFilterPopover"
            @select="changeRefreshInterval"
          />
          <button
            class="create-btn digital-refresh-action digital-refresh-now"
            type="button"
            :disabled="loading"
            aria-label="立即刷新工作记录"
            @click="loadWorkRecords(true)"
          >
            <i :class="loading ? 'mdi mdi-loading mdi-spin' : 'mdi mdi-refresh'"></i>
          </button>
        </template>

        <template #meta>
          <div v-if="activeFilterTokens.length" class="active-filter-strip">
            <span v-for="token in activeFilterTokens" :key="token" class="active-filter-chip">
              {{ token }}
            </span>
          </div>
        </template>

        <template #error>
          <i class="mdi mdi-alert-circle-outline"></i>
          <p>{{ errorMessage }}</p>
        </template>

        <template #table>
          <table class="digital-work-records-table">
            <colgroup>
              <col class="col-time">
              <col class="col-module">
              <col class="col-source">
              <col class="col-status">
              <col class="col-summary">
              <col class="col-trace">
            </colgroup>
            <thead>
              <tr>
                <th>执行时间</th>
                <th>工作模块</th>
                <th>触发来源</th>
                <th>状态</th>
                <th>摘要</th>
                <th>Run ID</th>
              </tr>
            </thead>
            <tbody>
              <tr
                v-for="run in visibleRuns"
                :key="run.run_id"
                class="work-record-row"
                tabindex="0"
                role="button"
                @click="openWorkRecordDetail(run)"
                @keydown.enter.prevent="openWorkRecordDetail(run)"
              >
                <td>{{ formatWorkRecordDateTime(run.started_at) }}</td>
                <td>{{ resolveWorkRecordModuleLabel(run) }}</td>
                <td>{{ resolveWorkRecordSourceLabel(run.source) }}</td>
                <td>
                  <span class="status-tag" :class="resolveWorkRecordStatusTone(run)">
                    {{ resolveWorkRecordStatusLabel(run) }}
                  </span>
                </td>
                <td class="work-record-summary-cell">
                  <strong>{{ resolveWorkRecordTitle(run) }}</strong>
                  <span>{{ formatWorkRecordSummary(run.result_summary) }}</span>
                  <em>{{ resolveWorkRecordSummaryMeta(run) }}</em>
                </td>
                <td class="work-record-trace-cell">{{ run.run_id }}</td>
              </tr>
            </tbody>
          </table>
        </template>
      </EnterpriseListPage>

      <EnterpriseDetailPage
        v-else
        key="detail"
        variant="work-record-detail-page"
        actions-class="work-record-detail-actions"
        :loading="detailLoading"
        :error="detailError"
        error-title="工作记录详情加载失败"
        loading-title="详情加载中"
        loading-message="正在读取该次工作记录的完整执行信息"
        loading-icon="mdi mdi-clipboard-text-search-outline"
        back-label="返回工作记录列表"
        @back="closeWorkRecordDetail"
      >
        <template #main>
          <EnterpriseDetailCard
            class="work-record-detail-card work-record-summary-card"
            title="基本信息"
            description="此次运行的执行周期、触发来源、标识信息与最终状态。"
          >
              <div class="json-risk-meta-grid">
                <div class="json-risk-meta-item">
                  <span class="json-risk-meta-label">Run ID</span>
                  <span class="json-risk-meta-value">{{ selectedRunDetail.run_id }}</span>
                </div>
                <div class="json-risk-meta-item">
                  <span class="json-risk-meta-label">工作模块</span>
                  <span class="json-risk-meta-value">{{ resolveWorkRecordModuleLabel(selectedRunDetail) }}</span>
                </div>
                <div class="json-risk-meta-item">
                  <span class="json-risk-meta-label">触发来源</span>
                  <span class="json-risk-meta-value">{{ resolveWorkRecordSourceLabel(selectedRunDetail.source) }}</span>
                </div>
                <div class="json-risk-meta-item">
                  <span class="json-risk-meta-label">开始时间</span>
                  <span class="json-risk-meta-value">{{ formatWorkRecordDateTime(selectedRunDetail.started_at) }}</span>
                </div>
                <div class="json-risk-meta-item">
                  <span class="json-risk-meta-label">结束时间</span>
                  <span class="json-risk-meta-value">{{ formatWorkRecordDateTime(selectedRunDetail.finished_at) }}</span>
                </div>
                <div class="json-risk-meta-item">
                  <span class="json-risk-meta-label">状态说明</span>
                  <span class="json-risk-meta-value">{{ resolveWorkRecordStatusNote(selectedRunDetail) || '-' }}</span>
                </div>
              </div>
          </EnterpriseDetailCard>

          <EnterpriseDetailCard
            class="work-record-detail-card work-record-summary-copy-card"
            title="执行摘要"
            description="本次数字员工工作流的执行内容与结果摘要。"
          >
            <template #actions>
                <span class="edit-badge">{{ resolveWorkRecordSummaryMeta(selectedRunDetail) }}</span>
            </template>
            <p class="json-risk-description-text work-record-summary-text">{{ selectedRunDetail.result_summary || '暂无执行摘要。' }}</p>
            <p v-if="selectedRunDetail.error_message" class="work-record-error-text">
                {{ selectedRunDetail.error_message }}
            </p>
          </EnterpriseDetailCard>

          <DigitalEmployeeRunProducts :run="selectedRunDetail" />
        </template>

        <template #side>
          <EnterpriseDetailCard
            class="work-record-detail-card"
            title="工具调用"
            description="此任务在执行期间调用的外部系统/工具细节与执行状态。"
          >
            <template #actions>
                <span class="edit-badge">{{ (selectedRunDetail.tool_calls || []).length }} 次调用</span>
            </template>
            <div v-if="(selectedRunDetail.tool_calls || []).length" class="work-record-tool-list">
                <article v-for="toolCall in selectedRunDetail.tool_calls" :key="toolCall.id" class="work-record-tool-item">
                  <strong>{{ toolCall.tool_name }}</strong>
                  <span>{{ toolCall.tool_type || 'tool' }} · {{ toolCall.status || 'unknown' }}</span>
                </article>
            </div>
            <div v-else class="work-record-inline-empty">当前暂无工具调用明细。</div>
          </EnterpriseDetailCard>

          <EnterpriseDetailCard
            class="work-record-detail-card"
            title="执行上下文"
            description="后台调度的运行时配置与状态信息（JSON 格式）。"
          >
            <pre class="work-record-code-block">{{ formatJson(selectedRunDetail.route_json) }}</pre>
          </EnterpriseDetailCard>
        </template>

        <template #actions>
          <button class="minor-action" type="button" :disabled="detailLoading" @click="reloadSelectedDetail">
            <i class="mdi mdi-refresh"></i>
            <span>{{ detailLoading ? '刷新中...' : '刷新详情' }}</span>
          </button>
        </template>
      </EnterpriseDetailPage>
    </Transition>
  </section>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'

import AuditPickerFilter from './AuditPickerFilter.vue'
import DigitalEmployeeRunProducts from './DigitalEmployeeRunProducts.vue'
import EnterpriseDetailCard from '../shared/EnterpriseDetailCard.vue'
import EnterpriseDetailPage from '../shared/EnterpriseDetailPage.vue'
import EnterpriseListPage from '../shared/EnterpriseListPage.vue'
import { fetchAgentRunDetail, fetchAgentRuns } from '../../services/agentAssets.js'
import { useToast } from '../../composables/useToast.js'
import {
  DEFAULT_REFRESH_INTERVAL_MS,
  REFRESH_INTERVAL_OPTIONS,
  formatRefreshInterval
} from '../../utils/refreshIntervalOptions.js'
import {
  formatWorkRecordDateTime,
  formatWorkRecordSummary,
  compactDigitalEmployeeWorkRecords,
  resolveWorkRecordModuleLabel,
  resolveWorkRecordSourceLabel,
  resolveWorkRecordStatusLabel,
  resolveWorkRecordStatusNote,
  resolveWorkRecordStatusTone,
  resolveWorkRecordSummaryMeta,
  resolveWorkRecordTitle
} from '../../views/scripts/digitalEmployeeWorkRecordsModel.js'

defineOptions({
  name: 'DigitalEmployeeWorkRecords'
})

const props = defineProps({
  focusRunId: { type: String, default: '' }
})
const emit = defineEmits(['summary-change', 'detail-open-change', 'detail-topbar-change'])

const { toast } = useToast()
const runs = ref([])
const loading = ref(false)
const errorMessage = ref('')
const detailOpen = ref(false)
const detailLoading = ref(false)
const detailError = ref('')
const selectedRunId = ref('')
const selectedRunDetail = ref(null)
const refreshInterval = ref(DEFAULT_REFRESH_INTERVAL_MS)

watch(detailOpen, (newVal) => {
  emit('detail-open-change', newVal)
}, { immediate: true })
let pollTimer = 0

const workRecordSummary = computed(() =>
  runs.value.reduce(
    (summary, run) => {
      summary.total += 1
      if (run.status === 'succeeded') {
        summary.succeeded += 1
      } else if (run.status === 'failed') {
        summary.failed += 1
      }
      return summary
    },
    { total: 0, succeeded: 0, failed: 0 }
  )
)
const workRecordDetailTopBar = computed(() => {
  const detail = selectedRunDetail.value
  if (!detail) return null

  const status = String(detail.status || '').toLowerCase()
  const statusColor =
    status === 'failed'
      ? '#ef4444'
      : status === 'succeeded'
        ? 'var(--success)'
        : '#3b82f6'

  return {
    view: {
      title: resolveWorkRecordTitle(detail),
      desc: `执行工作流：${resolveWorkRecordModuleLabel(detail)}`
    },
    kpis: [
      {
        label: '运行状态',
        value: resolveWorkRecordStatusLabel(detail),
        unit: '',
        meta: resolveWorkRecordStatusNote(detail) || '执行完毕',
        trend: status === 'failed' ? 'down' : 'up',
        color: statusColor
      }
    ]
  }
})

watch(
  workRecordDetailTopBar,
  (value) => {
    emit('detail-topbar-change', value)
  },
  { immediate: true, deep: true }
)

const listKeyword = ref('')
const activeModule = ref('全部')
const activeStatus = ref('全部')
const activeFilterPopover = ref('')
const workRecordsEmptyState = {
  eyebrow: '工作记录',
  title: '暂无匹配的工作记录',
  description: '当前没有符合搜索条件的数字员工工作记录。',
  icon: 'mdi mdi-clipboard-text-clock-outline',
  tone: 'theme',
  artLabel: 'RECORDS'
}

const modulePickerOptions = computed(() => {
  const set = new Set(runs.value.map((run) => resolveWorkRecordModuleLabel(run)))
  return [
    { label: '全部工作模块', value: '全部' },
    ...Array.from(set).map(m => ({ label: m, value: m }))
  ]
})

const statusPickerOptions = computed(() => {
  const set = new Set(runs.value.map((run) => resolveWorkRecordStatusLabel(run)))
  return [
    { label: '全部执行状态', value: '全部' },
    ...Array.from(set).map(s => ({ label: s, value: s }))
  ]
})
const refreshIntervalPickerOptions = REFRESH_INTERVAL_OPTIONS.map((option) => ({
  label: `每 ${option.label}`,
  value: option.value
}))
const refreshIntervalLabel = computed(() => formatRefreshInterval(refreshInterval.value))

const activeFilterTokens = computed(() => {
  const tokens = []
  if (activeModule.value !== '全部') {
    tokens.push(activeModule.value)
  }
  if (activeStatus.value !== '全部') {
    tokens.push(activeStatus.value)
  }
  return tokens
})

const filteredRuns = computed(() => {
  const keyword = listKeyword.value.trim().toLowerCase()
  return runs.value.filter((run) => {
    const moduleLabel = resolveWorkRecordModuleLabel(run)
    const statusLabel = resolveWorkRecordStatusLabel(run)
    const matchesKeyword = !keyword || [run.run_id, moduleLabel, statusLabel, run.result_summary].filter(Boolean).join(' ').toLowerCase().includes(keyword)
    const matchesModule = activeModule.value === '全部' || moduleLabel === activeModule.value
    const matchesStatus = activeStatus.value === '全部' || statusLabel === activeStatus.value
    return matchesKeyword && matchesModule && matchesStatus
  })
})

const currentPage = ref(1)
const pageSize = 20
const totalPages = computed(() => Math.max(1, Math.ceil(filteredRuns.value.length / pageSize)))

const visibleRuns = computed(() => {
  const start = (currentPage.value - 1) * pageSize
  return filteredRuns.value.slice(start, start + pageSize)
})

const paginationSummary = computed(() =>
  `共 ${filteredRuns.value.length} 条，目前第 ${currentPage.value} / ${totalPages.value} 页`
)

watch(
  () => [listKeyword.value, activeModule.value, activeStatus.value],
  () => {
    currentPage.value = 1
  }
)

watch(
  () => filteredRuns.value.length,
  () => {
    currentPage.value = Math.min(currentPage.value, totalPages.value)
    if (currentPage.value < 1) {
      currentPage.value = 1
    }
  },
  { immediate: true }
)

function toggleFilterPopover(id) {
  activeFilterPopover.value = activeFilterPopover.value === id ? '' : id
}

function closeFilterPopover() {
  activeFilterPopover.value = ''
}

function selectModule(val) {
  activeModule.value = val
  closeFilterPopover()
}

function selectStatus(val) {
  activeStatus.value = val
  closeFilterPopover()
}

function changeRefreshInterval(value) {
  refreshInterval.value = Number(value) || DEFAULT_REFRESH_INTERVAL_MS
  closeFilterPopover()
  startPolling()
}

function resetFilters() {
  listKeyword.value = ''
  activeModule.value = '全部'
  activeStatus.value = '全部'
  closeFilterPopover()
}

async function loadWorkRecords(showToast = false) {
  loading.value = true
  errorMessage.value = ''

  try {
    const payload = await fetchAgentRuns({ agent: 'hermes', limit: 100 })
    runs.value = Array.isArray(payload) ? compactDigitalEmployeeWorkRecords(payload) : []
    emit('summary-change', {
      total: workRecordSummary.value.total,
      succeeded: workRecordSummary.value.succeeded,
      failed: workRecordSummary.value.failed
    })
  } catch (error) {
    errorMessage.value = error?.message || '工作记录加载失败，请稍后重试。'
    if (showToast) {
      toast(errorMessage.value)
    }
  } finally {
    loading.value = false
  }
}

function formatJson(value) {
  try {
    return JSON.stringify(value || {}, null, 2)
  } catch {
    return String(value || '')
  }
}

async function loadWorkRecordDetail(runId) {
  detailLoading.value = true
  detailError.value = ''
  try {
    selectedRunDetail.value = await fetchAgentRunDetail(runId)
  } catch (error) {
    detailError.value = error?.message || '工作记录详情加载失败，请稍后重试。'
  } finally {
    detailLoading.value = false
  }
}

function openWorkRecordDetail(run) {
  const runId = String(run?.run_id || '').trim()
  if (!runId) {
    return
  }

  selectedRunId.value = runId
  selectedRunDetail.value = run
  detailOpen.value = true
  void loadWorkRecordDetail(runId)
}

async function openWorkRecordById(runId) {
  const normalizedRunId = String(runId || '').trim()
  if (!normalizedRunId) {
    return
  }

  selectedRunId.value = normalizedRunId
  selectedRunDetail.value = runs.value.find((run) => run.run_id === normalizedRunId) || {
    run_id: normalizedRunId,
    source: 'schedule',
    status: 'running',
    route_json: {},
    result_summary: '正在读取本次运行详情。'
  }
  detailOpen.value = true

  if (!runs.value.some((run) => run.run_id === normalizedRunId)) {
    await loadWorkRecords(false)
    const refreshedRun = runs.value.find((run) => run.run_id === normalizedRunId)
    if (refreshedRun && selectedRunId.value === normalizedRunId) {
      selectedRunDetail.value = refreshedRun
    }
  }

  if (selectedRunId.value === normalizedRunId) {
    await loadWorkRecordDetail(normalizedRunId)
  }
}

function reloadSelectedDetail() {
  if (!selectedRunId.value) {
    return
  }
  void loadWorkRecordDetail(selectedRunId.value)
}

function closeWorkRecordDetail() {
  detailOpen.value = false
  selectedRunDetail.value = null
  detailError.value = ''
}

watch(
  () => props.focusRunId,
  (runId) => {
    if (String(runId || '').trim()) {
      void openWorkRecordById(runId)
    }
  },
  { immediate: true }
)

function startPolling() {
  stopPolling()
  pollTimer = window.setInterval(() => {
    loadWorkRecords(false)
  }, refreshInterval.value)
}

function stopPolling() {
  if (pollTimer) {
    window.clearInterval(pollTimer)
    pollTimer = 0
  }
}

onMounted(() => {
  loadWorkRecords(false).catch(() => {})
  startPolling()
})

onBeforeUnmount(() => {
  stopPolling()
})
</script>

<style scoped src="../../assets/styles/views/audit-view.css"></style>
<style scoped src="../../assets/styles/views/audit-view-part2.css"></style>

<style scoped src="../../assets/styles/components/digital-employee-work-records.css"></style>
<style scoped src="../../assets/styles/components/digital-employee-work-records-overrides.css"></style>
