<template>
  <div class="automation-page">
    <a-row :gutter="16" class="summary-row">
      <a-col :xs="24" :sm="12" :lg="6" v-for="item in summaryItems" :key="item.label">
        <a-card :bordered="false" class="summary-card">
          <div class="summary-label">{{ item.label }}</div>
          <div class="summary-value">{{ item.value }}</div>
        </a-card>
      </a-col>
    </a-row>

    <a-card :bordered="false" class="panel-card">
      <template #title>自动化处置</template>
      <template #extra>
        <a-space>
          <a-input v-model="filters.keyword" allow-clear placeholder="脚本 / 分类" />
          <a-select v-model="filters.status" allow-clear placeholder="状态" :style="{ width: '120px' }">
            <a-option value="enabled">启用</a-option>
            <a-option value="disabled">停用</a-option>
          </a-select>
          <a-button :loading="loading || executionLoading" :disabled="pageUnauthorized" @click="loadAll">
            <template #icon><icon-refresh /></template>
          </a-button>
          <a-button type="primary" :disabled="!canOperate" @click="openScriptForm()">
            <template #icon><icon-plus /></template>
            新增脚本
          </a-button>
        </a-space>
      </template>

      <PageState :status="pageStatus" :error-text="errorMessage" :partial-text="partialMessage" @retry="loadAll">
      <a-tabs v-if="pageStatus !== 'empty' && pageStatus !== 'error' && pageStatus !== 'unauthorized'" v-model:active-key="activeTab">
        <a-tab-pane key="scripts" title="脚本库">
          <a-table
            row-key="id"
            :data="scripts"
            :loading="loading"
            :pagination="scriptPagination"
            @page-change="handleScriptPage"
            @page-size-change="handleScriptPageSize"
          >
            <template #columns>
              <a-table-column title="名称" data-index="name" :width="180" />
              <a-table-column title="资源分类" data-index="resource_category" :width="120" />
              <a-table-column title="审批级别" data-index="approval_level" :width="120">
                <template #cell="{ record }">
                  <a-tag :color="record.approval_level === 'high' ? 'red' : 'arcoblue'">{{ record.approval_level }}</a-tag>
                </template>
              </a-table-column>
              <a-table-column title="回滚" :width="90">
                <template #cell="{ record }">
                  <a-tag :color="record.rollback_required ? 'orange' : 'gray'">{{ record.rollback_required ? '需要' : '无' }}</a-tag>
                </template>
              </a-table-column>
              <a-table-column title="状态" data-index="status" :width="100">
                <template #cell="{ record }">
                  <a-tag :color="record.status === 'enabled' ? 'green' : 'gray'">{{ record.status }}</a-tag>
                </template>
              </a-table-column>
              <a-table-column title="命令模板" data-index="command_template" ellipsis tooltip />
              <a-table-column title="操作" :width="250" fixed="right">
                <template #cell="{ record }">
                  <a-space>
                    <a-button type="text" size="small" :disabled="!canOperate" @click="openRunDrawer(record, 'dry_run')">Dry-run</a-button>
                    <a-button type="text" size="small" :disabled="!canOperate" @click="openRunDrawer(record, 'execute')">审批</a-button>
                    <a-button type="text" size="small" @click="openRunDrawer(record, 'rollback')" :disabled="!record.rollback_required || !canOperate">回滚</a-button>
                    <a-button type="text" size="small" :disabled="!canOperate" @click="openScriptForm(record)">编辑</a-button>
                  </a-space>
                </template>
              </a-table-column>
            </template>
          </a-table>
        </a-tab-pane>

        <a-tab-pane key="executions" title="执行记录">
          <a-table row-key="id" :data="executions" :loading="executionLoading" :pagination="executionPagination" @page-change="handleExecutionPage">
            <template #columns>
              <a-table-column title="ID" data-index="id" :width="80" />
              <a-table-column title="脚本" data-index="script_id" :width="100" />
              <a-table-column title="模式" data-index="mode" :width="110" />
              <a-table-column title="状态" data-index="status" :width="130">
                <template #cell="{ record }">
                  <a-tag :color="statusColor(record.status)">{{ record.status }}</a-tag>
                </template>
              </a-table-column>
              <a-table-column title="资源" data-index="resource_uid" :width="220" />
              <a-table-column title="退出码" data-index="exit_code" :width="90" />
              <a-table-column title="输出" data-index="stdout" ellipsis tooltip />
              <a-table-column title="操作" :width="130" fixed="right">
                <template #cell="{ record }">
                  <a-button type="text" size="small" :disabled="record.status !== 'pending_approval' || !canOperate" @click="approve(record)">审批执行</a-button>
                </template>
              </a-table-column>
            </template>
          </a-table>
        </a-tab-pane>
      </a-tabs>
      </PageState>
    </a-card>

    <a-modal v-model:visible="scriptFormVisible" title="自动化脚本" width="720px" @ok="saveScript" unmount-on-close>
      <a-form :model="scriptForm" layout="vertical">
        <a-form-item field="name" label="名称" required>
          <a-input v-model="scriptForm.name" />
        </a-form-item>
        <a-form-item field="resource_category" label="资源分类" required>
          <a-input v-model="scriptForm.resource_category" placeholder="host / database / network" />
        </a-form-item>
        <a-form-item field="approval_level" label="审批级别">
          <a-select v-model="scriptForm.approval_level">
            <a-option value="normal">normal</a-option>
            <a-option value="high">high</a-option>
          </a-select>
        </a-form-item>
        <a-form-item field="command_template" label="命令模板" required>
          <a-textarea v-model="scriptForm.command_template" :auto-size="{ minRows: 3, maxRows: 6 }" />
        </a-form-item>
        <a-form-item field="rollback_command" label="回滚命令">
          <a-textarea v-model="scriptForm.rollback_command" :auto-size="{ minRows: 2, maxRows: 5 }" />
        </a-form-item>
        <a-form-item field="status" label="状态">
          <a-radio-group v-model="scriptForm.status">
            <a-radio value="enabled">启用</a-radio>
            <a-radio value="disabled">停用</a-radio>
          </a-radio-group>
        </a-form-item>
        <a-form-item field="description" label="说明">
          <a-textarea v-model="scriptForm.description" />
        </a-form-item>
      </a-form>
    </a-modal>

    <a-drawer v-model:visible="runVisible" :width="620" :title="runTitle" unmount-on-close>
      <a-form :model="runForm" layout="vertical">
        <a-form-item field="resource_uid" label="资源 UID" required>
          <a-input v-model="runForm.resource_uid" placeholder="host:server-001" />
        </a-form-item>
        <a-form-item field="incident_id" label="Incident ID">
          <a-input-number v-model="runForm.incident_id" :min="0" />
        </a-form-item>
        <a-form-item field="ticket_id" label="工单 ID">
          <a-input-number v-model="runForm.ticket_id" :min="0" />
        </a-form-item>
        <a-form-item field="operator" label="操作人">
          <a-input v-model="runForm.operator" />
        </a-form-item>
        <a-form-item field="approver" label="审批人" v-if="runMode !== 'dry_run'">
          <a-input v-model="runForm.approver" />
        </a-form-item>
      </a-form>
      <template #footer>
        <a-space>
          <a-button @click="runVisible = false">取消</a-button>
          <a-button type="primary" :loading="running" @click="submitRun">{{ runMode === 'dry_run' ? '执行 dry-run' : '提交' }}</a-button>
        </a-space>
      </template>
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
import { computed, reactive, ref } from 'vue'
import { Modal, Message } from '@arco-design/web-vue'
import {
  approveAutomationExecution,
  createAutomationScript,
  dryRunAutomationScript,
  fetchAutomationExecutions,
  fetchAutomationScripts,
  requestAutomationExecution,
  updateAutomationScript,
  type AutomationExecution,
  type AutomationScript,
} from '@/api/ops/automation'

const activeTab = ref('scripts')
const loading = ref(false)
const executionLoading = ref(false)
const running = ref(false)
const errorMessage = ref('')
const partialMessage = ref('')
const pageUnauthorized = ref(false)
const scripts = ref<AutomationScript[]>([])
const executions = ref<AutomationExecution[]>([])
const currentScript = ref<AutomationScript | null>(null)
const scriptFormVisible = ref(false)
const runVisible = ref(false)
const runMode = ref<'dry_run' | 'execute' | 'rollback'>('dry_run')

const filters = reactive({ keyword: '', status: undefined as string | undefined })
const scriptPagination = reactive({ current: 1, pageSize: 20, total: 0, showTotal: true, showPageSize: true })
const executionPagination = reactive({ current: 1, pageSize: 20, total: 0, showTotal: true })
const scriptForm = reactive<Partial<AutomationScript>>({})
const runForm = reactive({ resource_uid: '', incident_id: undefined as number | undefined, ticket_id: undefined as number | undefined, operator: '', approver: '' })

const summaryItems = computed(() => [
  { label: '脚本总数', value: scriptPagination.total },
  { label: '启用脚本', value: scripts.value.filter((item) => item.status === 'enabled').length },
  { label: '待审批', value: executions.value.filter((item) => item.status === 'pending_approval').length },
  { label: '执行记录', value: executionPagination.total },
])

const canOperate = computed(() => !pageUnauthorized.value && !loading.value && !executionLoading.value)

const pageStatus = computed(() => {
  if (pageUnauthorized.value) return 'unauthorized'
  if (loading.value && executionLoading.value) return 'loading'
  if (errorMessage.value && !scripts.value.length && !executions.value.length) return 'error'
  if (partialMessage.value) return 'partial'
  if (!scripts.value.length && !executions.value.length) return 'empty'
  return 'success'
})

const isForbidden = (error: any) => error?.response?.status === 403 || error?.code === 403 || error?.code === 401

const setLoadError = (error: any, fallback: string) => {
  if (isForbidden(error)) {
    pageUnauthorized.value = true
    errorMessage.value = '当前账号没有访问自动化处置的权限。'
    return
  }
  errorMessage.value = error?.message || fallback
}

const runTitle = computed(() => {
  const map = { dry_run: 'Dry-run', execute: '发起审批', rollback: '发起回滚审批' }
  return `${map[runMode.value]} - ${currentScript.value?.name || ''}`
})

const unwrapPage = <T,>(response: any) => response?.details || response?.data || { data: [] as T[], total: 0 }

const loadScripts = async () => {
  loading.value = true
  errorMessage.value = ''
  try {
    const response = await fetchAutomationScripts({ page: scriptPagination.current, size: scriptPagination.pageSize, ...filters })
    const page = unwrapPage<AutomationScript>(response)
    scripts.value = page.data || []
    scriptPagination.total = page.total || 0
  } catch (error: any) {
    setLoadError(error, '加载脚本失败')
    Message.error(error.message || '加载脚本失败')
  } finally {
    loading.value = false
  }
}

const loadExecutions = async () => {
  executionLoading.value = true
  try {
    const response = await fetchAutomationExecutions({ page: executionPagination.current, size: executionPagination.pageSize })
    const page = unwrapPage<AutomationExecution>(response)
    executions.value = page.data || []
    executionPagination.total = page.total || 0
  } catch (error: any) {
    setLoadError(error, '加载执行记录失败')
    Message.error(error.message || '加载执行记录失败')
  } finally {
    executionLoading.value = false
  }
}

const loadAll = async () => {
  partialMessage.value = ''
  pageUnauthorized.value = false
  const results = await Promise.allSettled([loadScripts(), loadExecutions()])
  if (results.some((item) => item.status === 'rejected')) {
    partialMessage.value = '脚本库或执行记录部分加载失败，当前页面展示可用数据。'
  }
}

const openScriptForm = (record?: AutomationScript) => {
  Object.assign(scriptForm, record || { approval_level: 'normal', status: 'enabled' })
  if (!record) delete scriptForm.id
  scriptFormVisible.value = true
}

const saveScript = async () => {
  if (scriptForm.id) {
    await updateAutomationScript(scriptForm.id, scriptForm)
    Message.success('脚本已更新')
  } else {
    await createAutomationScript(scriptForm)
    Message.success('脚本已创建')
  }
  scriptFormVisible.value = false
  loadScripts()
}

const openRunDrawer = (record: AutomationScript, mode: 'dry_run' | 'execute' | 'rollback') => {
  currentScript.value = record
  runMode.value = mode
  Object.assign(runForm, { resource_uid: '', incident_id: undefined, ticket_id: undefined, operator: '', approver: '' })
  runVisible.value = true
}

const submitRun = async () => {
  if (!currentScript.value) return
  running.value = true
  try {
    const payload = {
      resource_uid: runForm.resource_uid,
      incident_id: runForm.incident_id,
      ticket_id: runForm.ticket_id,
      operator: runForm.operator,
      approver: runForm.approver,
      mode: runMode.value === 'rollback' ? 'rollback' : 'execute',
    } as any
    if (runMode.value === 'dry_run') {
      await dryRunAutomationScript(currentScript.value.id, payload)
      Message.success('dry-run 已记录')
    } else {
      await requestAutomationExecution(currentScript.value.id, payload)
      Message.success('审批已发起')
    }
    runVisible.value = false
    loadExecutions()
  } catch (error: any) {
    Message.error(error.message || '提交失败')
  } finally {
    running.value = false
  }
}

const approve = (record: AutomationExecution) => {
  Modal.confirm({
    title: '审批并执行',
    content: `确认审批执行记录 #${record.id}？`,
    onOk: async () => {
      await approveAutomationExecution(record.id, { approver: 'ops-admin', operator: record.operator })
      Message.success('审批执行已完成')
      loadExecutions()
    },
  })
}

const handleScriptPage = (page: number) => {
  scriptPagination.current = page
  loadScripts()
}

const handleScriptPageSize = (pageSize: number) => {
  scriptPagination.pageSize = pageSize
  scriptPagination.current = 1
  loadScripts()
}

const handleExecutionPage = (page: number) => {
  executionPagination.current = page
  loadExecutions()
}

const statusColor = (status: string) => {
  const map: Record<string, string> = {
    pending_approval: 'orange',
    dry_run: 'arcoblue',
    succeeded: 'green',
    failed: 'red',
    timed_out: 'red',
    running: 'purple',
  }
  return map[status] || 'gray'
}

loadAll()
</script>

<script lang="ts">
export default {
  name: 'OpsAutomation',
}
</script>

<style scoped lang="less">
.automation-page {
  padding: 16px 20px 24px;
}

.summary-row {
  margin-bottom: 16px;
}

.summary-card {
  min-height: 92px;
}

.summary-label {
  color: var(--color-text-2);
  font-size: 13px;
}

.summary-value {
  margin-top: 12px;
  font-size: 28px;
  line-height: 1;
  font-weight: 600;
}

.panel-card {
  border-radius: 6px;
}

@media (max-width: 768px) {
  .automation-page {
    padding: 12px;
  }

  :deep(.arco-card-header) {
    flex-wrap: wrap;
    gap: 8px;
  }

  :deep(.arco-card-extra) {
    width: 100%;
  }

  :deep(.arco-card-extra .arco-space) {
    width: 100%;
    flex-wrap: wrap;
    justify-content: flex-start;
  }

  :deep(.arco-input-wrapper),
  :deep(.arco-select) {
    max-width: 100%;
  }

  :deep(.arco-table-container) {
    overflow-x: auto;
  }
}
</style>
