<template>
  <section class="digital-employees-view skill-center">
    <Transition name="skill-view" mode="out-in">
      <EnterpriseDetailPage
        v-if="selectedEmployee"
        key="detail"
        variant="skill-detail digital-employee-detail json-risk-skill-detail"
        actions-class="digital-employee-detail-actions"
        :error="detailError"
        error-title="数字员工详情加载失败"
        :loading="detailLoading && selectedEmployee.loading"
        loading-title="正在加载数字员工详情"
        loading-message="列表数据已就绪，正在补充 Skills 源文件和执行配置"
        loading-icon="mdi mdi-account-cog-outline"
        back-label="返回数字员工列表"
        @back="closeEmployeeDetail"
      >
        <AuditDigitalEmployeeDetail
          :selected-skill="selectedEmployee"
          :can-edit="canEditDigitalEmployeeSource"
          :detail-busy="detailBusy"
          :action-state="actionState"
          @save-source="saveDigitalEmployeeSource"
        />

        <template #actions>
            <button
              class="minor-action enable-action"
              :class="{ 'is-on': selectedEmployee.statusValue === 'active' }"
              type="button"
              :disabled="!canOperateDigitalEmployee || detailBusy"
              @click="toggleDigitalEmployeeRunning(selectedEmployee)"
            >
              <i :class="selectedEmployee.statusValue === 'active' ? 'mdi mdi-toggle-switch' : 'mdi mdi-toggle-switch-off-outline'"></i>
              <span>{{ selectedEmployee.statusValue === 'active' ? '停止运行' : '启用运行' }}</span>
            </button>
            <button
              class="minor-action"
              type="button"
              :disabled="!canOperateDigitalEmployee || detailBusy"
              @click="openDigitalEmployeeSchedule(selectedEmployee)"
            >
              <i class="mdi mdi-clock-edit-outline"></i>
              <span>定时设置</span>
            </button>
            <button
              class="minor-action success-action"
              type="button"
              :disabled="!canOperateDigitalEmployee || detailBusy"
              @click="runDigitalEmployeeNow(selectedEmployee)"
            >
              <i class="mdi mdi-play-circle-outline"></i>
              <span>{{ actionBusy(selectedEmployee.id, 'run-digital-now') ? '运行中...' : '立即运行' }}</span>
            </button>
        </template>
      </EnterpriseDetailPage>

      <article
        v-else
        key="list"
        class="skill-list digital-employees-list"
        :class="{ 'panel': !workRecordDetailOpen }"
      >
        <nav v-if="!workRecordDetailOpen" class="status-tabs" aria-label="数字员工页签">
          <button
            type="button"
            :class="{ active: activeSection === 'skills' }"
            @click="activeSection = 'skills'"
          >
            员工技能
          </button>
          <button
            type="button"
            :class="{ active: activeSection === 'workRecords' }"
            @click="activeSection = 'workRecords'"
          >
            工作记录
          </button>
        </nav>

        <template v-if="activeSection === 'skills'">
          <DigitalEmployeeListPanel
            v-model:keyword="keyword"
            :active-filter-popover="activeFilterPopover"
            :selected-status="selectedStatus"
            :selected-status-label="selectedStatusLabel"
            :status-options="statusOptions"
            :selected-skill-category="selectedSkillCategory"
            :selected-skill-category-label="selectedSkillCategoryLabel"
            :skill-category-options="skillCategoryOptions"
            :selected-enabled-state="selectedEnabledState"
            :selected-enabled-label="selectedEnabledLabel"
            :enabled-state-options="enabledStateOptions"
            :selected-execution-mode="selectedExecutionMode"
            :selected-execution-mode-label="selectedExecutionModeLabel"
            :execution-mode-options="executionModeOptions"
            :active-filter-tokens="activeFilterTokens"
            :loading="loading"
            :error-message="errorMessage"
            :visible-employees="visibleEmployees"
            @toggle-filter-popover="toggleFilterPopover"
            @close-filter-popover="closeFilterPopover"
            @select-filter="selectFilter"
            @reset-filters="resetFilters"
            @load-employees="loadEmployees"
            @open-employee-detail="openEmployeeDetail"
          />
        </template>

        <DigitalEmployeeWorkRecords
          v-else
          class="digital-work-records-section"
          :focus-run-id="workRecordFocusRunId"
          @summary-change="emit('summary-change', $event)"
          @detail-open-change="workRecordDetailOpen = $event"
          @detail-topbar-change="workRecordDetailTopBar = $event"
        />
      </article>
    </Transition>

    <DigitalEmployeeScheduleDialog
      v-model="scheduleForm"
      :open="scheduleEditorOpen"
      :target-name="scheduleTarget?.name || ''"
      :preview-label="schedulePreviewLabel"
      :error-message="scheduleEditorError"
      :busy="scheduleEditorBusy"
      :can-save="canOperateDigitalEmployee"
      @close="closeDigitalEmployeeSchedule"
      @save="saveDigitalEmployeeSchedule"
    />
  </section>
</template>

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

import AuditDigitalEmployeeDetail from '../components/audit/AuditDigitalEmployeeDetail.vue'
import DigitalEmployeeListPanel from '../components/audit/DigitalEmployeeListPanel.vue'
import DigitalEmployeeScheduleDialog from '../components/audit/DigitalEmployeeScheduleDialog.vue'
import DigitalEmployeeWorkRecords from '../components/audit/DigitalEmployeeWorkRecords.vue'
import EnterpriseDetailPage from '../components/shared/EnterpriseDetailPage.vue'
import { useSystemState } from '../composables/useSystemState.js'
import { useToast } from '../composables/useToast.js'
import {
  activateAgentAsset,
  createAgentAssetVersion,
  fetchAgentAssetDetail,
  fetchAgentAssets,
  updateAgentAsset
} from '../services/agentAssets.js'
import { runOrchestrator } from '../services/orchestrator.js'
import { isPlatformAdminUser } from '../utils/accessControl.js'
import {
  DIGITAL_EMPLOYEE_SKILL_CATEGORY_OPTIONS,
  formatDigitalEmployeeCron,
  isDigitalEmployeeAsset,
  shouldDisplayDigitalEmployeeAsset
} from './scripts/auditViewDigitalEmployeeModel.js'
import {
  buildDigitalEmployeeScheduleConfig,
  buildDigitalEmployeeScheduleCron,
  createDigitalEmployeeScheduleForm,
  resolveDigitalEmployeeScheduleValue
} from './scripts/digitalEmployeeScheduleModel.js'
import { incrementVersion } from './scripts/auditViewRuntimeModel.js'
import {
  DIGITAL_EMPLOYEE_EXECUTION_MODE_OPTIONS,
  buildDigitalEmployeeDetailTopBar,
  buildEmployeeDetail,
  buildEmployeeListItem,
  buildEmployeePlaceholder,
  filterDigitalEmployees,
  sortEmployees
} from './scripts/digitalEmployeesViewModel.js'
import {
  ENABLED_STATE_OPTIONS,
  normalizeText,
  STATUS_OPTIONS
} from './scripts/auditViewModel.js'

const { currentUser } = useSystemState()
const { toast } = useToast()
const emit = defineEmits(['summary-change', 'detail-open-change', 'detail-topbar-change'])

const employees = ref([])
const selectedEmployee = ref(null)
const selectedEmployeeId = ref('')
const activeSection = ref('skills')
const workRecordDetailOpen = ref(false)
const workRecordDetailTopBar = ref(null)
const workRecordFocusRunId = ref('')
const isDetailOpen = computed(() => Boolean(selectedEmployee.value) || (activeSection.value === 'workRecords' && workRecordDetailOpen.value))
const digitalEmployeeDetailTopBar = computed(() => {
  const employee = selectedEmployee.value
  if (employee) {
    return buildDigitalEmployeeDetailTopBar(employee)
  }

  if (activeSection.value === 'workRecords' && workRecordDetailOpen.value) {
    return workRecordDetailTopBar.value
  }

  return null
})

watch(isDetailOpen, (newVal) => {
  emit('detail-open-change', newVal)
}, { immediate: true })
watch(
  digitalEmployeeDetailTopBar,
  (value) => {
    emit('detail-topbar-change', value)
  },
  { immediate: true, deep: true }
)
const keyword = ref('')
const selectedStatus = ref('')
const selectedSkillCategory = ref('')
const selectedEnabledState = ref('')
const selectedExecutionMode = ref('')
const activeFilterPopover = ref('')
const loading = ref(false)
const detailLoading = ref(false)
const errorMessage = ref('')
const detailError = ref('')
const actionState = ref('')
const busyEmployeeId = ref('')
const scheduleEditorOpen = ref(false)
const scheduleTarget = ref(null)
const scheduleForm = ref(createDigitalEmployeeScheduleForm())
const scheduleEditorError = ref('')

const isAdmin = computed(() => isPlatformAdminUser(currentUser.value))
const detailBusy = computed(() => Boolean(detailLoading.value || actionState.value))
const canOperateDigitalEmployee = computed(() => isAdmin.value && Boolean(selectedEmployee.value))
const canEditDigitalEmployeeSource = computed(() => canOperateDigitalEmployee.value)
const scheduleEditorBusy = computed(() => actionState.value === 'save-digital-schedule')

const statusOptions = STATUS_OPTIONS
const enabledStateOptions = ENABLED_STATE_OPTIONS
const executionModeOptions = DIGITAL_EMPLOYEE_EXECUTION_MODE_OPTIONS
const skillCategoryOptions = [
  { value: '', label: '全部技能类型' },
  ...DIGITAL_EMPLOYEE_SKILL_CATEGORY_OPTIONS.map((value) => ({ value, label: value }))
]

const selectedStatusLabel = computed(() =>
  statusOptions.find((item) => item.value === selectedStatus.value)?.label || '全部状态'
)
const selectedSkillCategoryLabel = computed(() =>
  skillCategoryOptions.find((item) => item.value === selectedSkillCategory.value)?.label || '全部技能类型'
)
const selectedEnabledLabel = computed(() =>
  enabledStateOptions.find((item) => item.value === selectedEnabledState.value)?.label || '全部启动状态'
)
const selectedExecutionModeLabel = computed(() =>
  executionModeOptions.find((item) => item.value === selectedExecutionMode.value)?.label || '全部执行方式'
)
const activeFilterTokens = computed(() => {
  const tokens = []
  if (selectedStatus.value) {
    tokens.push(`资产状态：${selectedStatusLabel.value}`)
  }
  if (selectedSkillCategory.value) {
    tokens.push(`技能类型：${selectedSkillCategoryLabel.value}`)
  }
  if (selectedEnabledState.value) {
    tokens.push(`启动状态：${selectedEnabledLabel.value}`)
  }
  if (selectedExecutionMode.value) {
    tokens.push(`执行方式：${selectedExecutionModeLabel.value}`)
  }
  return tokens
})

const schedulePreviewLabel = computed(() => {
  try {
    return formatDigitalEmployeeCron(buildDigitalEmployeeScheduleCron(scheduleForm.value))
  } catch {
    return '表达式待确认'
  }
})

const visibleEmployees = computed(() => {
  return filterDigitalEmployees(employees.value, {
    keyword: keyword.value,
    selectedEnabledState: selectedEnabledState.value,
    selectedExecutionMode: selectedExecutionMode.value,
    selectedSkillCategory: selectedSkillCategory.value,
    selectedStatus: selectedStatus.value
  })
})

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

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

function selectFilter(type, value) {
  if (type === 'status') {
    selectedStatus.value = value
  }
  if (type === 'skillCategory') {
    selectedSkillCategory.value = value
  }
  if (type === 'enabled') {
    selectedEnabledState.value = value
  }
  if (type === 'executionMode') {
    selectedExecutionMode.value = value
  }
  closeFilterPopover()
}

function resetFilters() {
  keyword.value = ''
  selectedStatus.value = ''
  selectedSkillCategory.value = ''
  selectedEnabledState.value = ''
  selectedExecutionMode.value = ''
  closeFilterPopover()
}

function resolveActor() {
  const user = currentUser.value || {}
  return normalizeText(user.name) || normalizeText(user.username) || 'system'
}

async function loadEmployees() {
  loading.value = true
  errorMessage.value = ''

  try {
    const payload = await fetchAgentAssets({ assetType: 'task' })
    const items = Array.isArray(payload)
      ? payload
        .filter((asset) => isDigitalEmployeeAsset(asset) && shouldDisplayDigitalEmployeeAsset(asset))
        .map(buildEmployeeListItem)
      : []

    employees.value = sortEmployees(items)
  } catch (error) {
    errorMessage.value = error?.message || '数字员工数据加载失败，请稍后重试。'
    toast(errorMessage.value)
  } finally {
    loading.value = false
  }
}

async function loadEmployeeDetail(assetId, placeholder = null, options = {}) {
  if (!assetId) {
    return
  }

  selectedEmployeeId.value = assetId
  selectedEmployee.value = placeholder
    ? buildEmployeePlaceholder(placeholder)
    : selectedEmployee.value || { id: assetId, name: '数字员工', loading: true, digitalEmployee: {} }
  detailLoading.value = true
  detailError.value = ''

  try {
    const detail = await fetchAgentAssetDetail(assetId)
    selectedEmployee.value = buildEmployeeDetail(detail)
  } catch (error) {
    detailError.value = error?.message || '数字员工详情加载失败，请稍后重试。'
    if (!options.silent) {
      toast(detailError.value)
    }
  } finally {
    detailLoading.value = false
  }
}

function openEmployeeDetail(employee) {
  loadEmployeeDetail(employee.id, employee).catch(() => {})
}

function closeEmployeeDetail() {
  closeDigitalEmployeeSchedule()
  selectedEmployee.value = null
  selectedEmployeeId.value = ''
  detailError.value = ''
  detailLoading.value = false
}

async function refreshAfterMutation(assetId) {
  await loadEmployees()
  if (selectedEmployee.value && selectedEmployeeId.value === assetId) {
    const placeholder = employees.value.find((item) => item.id === assetId) || selectedEmployee.value
    await loadEmployeeDetail(assetId, placeholder, { silent: true })
  }
}

function actionBusy(assetId, action) {
  return busyEmployeeId.value === assetId && actionState.value === action
}

async function toggleDigitalEmployeeRunning(employee) {
  if (!employee || !canOperateDigitalEmployee.value || actionState.value) {
    return
  }

  const assetId = employee.id
  const shouldEnable = employee.statusValue !== 'active'
  actionState.value = 'toggle-digital-running'
  busyEmployeeId.value = assetId

  try {
    await (shouldEnable
      ? activateAgentAsset(assetId, { actor: resolveActor() })
      : updateAgentAsset(assetId, { status: 'disabled' }, { actor: resolveActor() }))
    await refreshAfterMutation(assetId)
    toast(shouldEnable ? '已启用运行。' : '已停止运行。')
  } catch (error) {
    toast(error?.message || '运行状态更新失败，请稍后重试。')
  } finally {
    actionState.value = ''
    busyEmployeeId.value = ''
  }
}

async function saveDigitalEmployeeSource() {
  if (!selectedEmployee.value || !canEditDigitalEmployeeSource.value || detailBusy.value) {
    return
  }

  const markdown = normalizeText(selectedEmployee.value.markdownContent)
  if (!markdown) {
    toast('Skills Markdown 源文件不能为空。')
    return
  }

  const nextVersion = incrementVersion(selectedEmployee.value.currentVersion)
  actionState.value = 'save-digital-source'
  busyEmployeeId.value = selectedEmployee.value.id

  try {
    await createAgentAssetVersion(
      selectedEmployee.value.id,
      {
        version: nextVersion,
        content: markdown,
        content_type: 'markdown',
        change_note: '通过数字员工页面更新 Skills Markdown 源文件。',
        created_by: resolveActor()
      },
      { actor: resolveActor() }
    )
    await refreshAfterMutation(selectedEmployee.value.id)
    toast(`Skills 源文件已保存为 ${nextVersion}。`)
  } catch (error) {
    toast(error?.message || 'Skills 源文件保存失败，请稍后重试。')
  } finally {
    actionState.value = ''
    busyEmployeeId.value = ''
  }
}

function openDigitalEmployeeSchedule(employee) {
  if (!employee || !canOperateDigitalEmployee.value) {
    return
  }
  scheduleTarget.value = employee
  scheduleForm.value = createDigitalEmployeeScheduleForm(resolveDigitalEmployeeScheduleValue(employee))
  scheduleEditorError.value = ''
  scheduleEditorOpen.value = true
}

function closeDigitalEmployeeSchedule() {
  if (scheduleEditorBusy.value) {
    return
  }
  scheduleEditorOpen.value = false
  scheduleTarget.value = null
  scheduleEditorError.value = ''
}

async function saveDigitalEmployeeSchedule() {
  const employee = scheduleTarget.value || selectedEmployee.value
  if (!employee || !canOperateDigitalEmployee.value || actionState.value) {
    return
  }

  let cron = ''
  try {
    cron = buildDigitalEmployeeScheduleCron(scheduleForm.value)
  } catch (error) {
    scheduleEditorError.value = error?.message || '定时计划格式不正确。'
    return
  }

  const nextConfig = buildDigitalEmployeeScheduleConfig(employee.configJson, cron)
  nextConfig.skill_category = employee.digitalEmployee?.skillCategory || employee.skillCategory || '整理'
  nextConfig.skill_category_options = DIGITAL_EMPLOYEE_SKILL_CATEGORY_OPTIONS

  actionState.value = 'save-digital-schedule'
  busyEmployeeId.value = employee.id

  try {
    await updateAgentAsset(employee.id, { config_json: nextConfig }, { actor: resolveActor() })
    await refreshAfterMutation(employee.id)
    scheduleEditorOpen.value = false
    scheduleTarget.value = null
    scheduleEditorError.value = ''
    toast(cron ? `定时计划已更新为 ${formatDigitalEmployeeCron(cron)}。` : '已改为手动触发。')
  } catch (error) {
    scheduleEditorError.value = error?.message || '定时计划保存失败，请稍后重试。'
    toast(scheduleEditorError.value)
  } finally {
    actionState.value = ''
    busyEmployeeId.value = ''
  }
}

async function runDigitalEmployeeNow(employee) {
  if (!employee || !canOperateDigitalEmployee.value || actionState.value) {
    return
  }

  actionState.value = 'run-digital-now'
  busyEmployeeId.value = employee.id

  try {
    const result = await runOrchestrator({
      source: 'schedule',
      task_id: employee.id,
      message: employee.name,
      context_json: {
        manual_trigger: true,
        entry: 'digital_employees'
      }
    })
    const runId = String(result?.run_id || '').trim()
    if (runId) {
      closeEmployeeDetail()
      activeSection.value = 'workRecords'
      workRecordFocusRunId.value = ''
      await nextTick()
      workRecordFocusRunId.value = runId
      toast(`已发起立即运行，已打开本次工作记录。Run ID：${runId}`)
    } else {
      toast('已发起立即运行，请在工作记录中查看结果。')
    }
  } catch (error) {
    toast(error?.message || '立即运行失败，请稍后重试。')
  } finally {
    actionState.value = ''
    busyEmployeeId.value = ''
  }
}

onMounted(() => {
  loadEmployees().catch(() => {})
})
</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/views/digital-employees-view.css"></style>
