<template>
  <v-container fluid class="pa-6">
    <!-- Toolbar -->
    <v-card elevation="0" border rounded="lg" class="mb-4">
      <v-card-title class="d-flex align-center">
        脚本库
        <v-spacer />
        <v-text-field
          v-model="search"
          prepend-inner-icon="mdi-magnify"
          label="搜索..."
          density="compact"
          hide-details
          variant="outlined"
          rounded
          style="max-width: 240px"
        />
        <v-btn color="primary" variant="flat" class="ml-3" prepend-icon="mdi-plus" size="small" @click="openEditor(null)">
          新建脚本
        </v-btn>
      </v-card-title>
    </v-card>

    <!-- Quick Execute Panel -->
    <v-card elevation="0" border rounded="lg" class="mb-4">
      <v-card-title class="d-flex align-center" style="cursor: pointer" @click="showQuickExec = !showQuickExec">
        <v-icon class="mr-2">mdi-console</v-icon>
        临时命令执行
        <v-spacer />
        <v-icon>{{ showQuickExec ? 'mdi-chevron-up' : 'mdi-chevron-down' }}</v-icon>
      </v-card-title>
      <v-expand-transition>
        <div v-show="showQuickExec">
          <v-divider />
          <v-card-text>
            <v-textarea
              v-model="quickCommand"
              label="命令"
              variant="outlined"
              density="compact"
              rows="3"
              placeholder="输入要执行的命令... (Ctrl+Enter 执行)"
              class="mb-3"
              @keydown.ctrl.enter="doQuickExec"
              :rules="[required('命令')]"
            />
            <v-row dense>
              <v-col cols="12" md="6">
                <v-select
                  v-model="quickServerIds"
                  :items="serverList"
                  item-title="name"
                  item-value="id"
                  label="目标服务器"
                  variant="outlined"
                  density="compact"
                  multiple
                  chips
                  closable-chips
                />
              </v-col>
              <v-col cols="6" md="3">
                <v-text-field v-model.number="quickTimeout" label="超时(秒)" variant="outlined" density="compact" type="number" />
              </v-col>
              <v-col cols="6" md="3" class="d-flex align-center">
                <v-btn color="primary" variant="flat" @click="doQuickExec" :loading="quickExecuting" :disabled="!quickCommand || quickServerIds.length === 0">
                  执行
                </v-btn>
              </v-col>
            </v-row>
          </v-card-text>
        </div>
      </v-expand-transition>
    </v-card>

    <!-- Script Grid -->
    <v-progress-linear v-if="loading" indeterminate color="primary" />
    <v-row>
      <v-col cols="12" sm="6" md="4" v-for="script in filteredScripts" :key="script.id">
        <v-card elevation="0" border rounded="lg" class="fill-height">
          <v-card-title class="d-flex align-center">
            <v-icon color="primary" class="mr-2">mdi-code-braces</v-icon>
            <span class="text-body-1 font-weight-medium">{{ script.name }}</span>
            <v-spacer />
            <v-menu>
              <template #activator="{ props: menuProps }">
                <v-btn icon="mdi-dots-vertical" variant="text" size="small" v-bind="menuProps" />
              </template>
              <v-list density="compact">
                <v-list-item title="编辑" @click="openEditor(script)">
                  <template #prepend><v-icon>mdi-pencil</v-icon></template>
                </v-list-item>
                <v-list-item title="执行" @click="runScript(script)">
                  <template #prepend><v-icon>mdi-play</v-icon></template>
                </v-list-item>
                <v-list-item title="删除" @click="confirmDelete(script)" class="text-error">
                  <template #prepend><v-icon color="error">mdi-delete</v-icon></template>
                </v-list-item>
              </v-list>
            </v-menu>
          </v-card-title>
          <v-card-text>
            <v-chip v-if="script.category" size="small" variant="tonal" label class="mb-2">{{ script.category }}</v-chip>
            <div class="text-body-2 text-medium-emphasis">{{ script.description || '无描述' }}</div>
            <div class="text-caption text-medium-emphasis mt-2">
              更新于 {{ script.updated_at || script.created_at }}
            </div>
          </v-card-text>
          <v-card-actions>
            <v-btn size="small" variant="tonal" prepend-icon="mdi-play" color="primary" @click="runScript(script)">执行</v-btn>
            <v-spacer />
            <v-btn size="small" variant="text" @click="viewHistory(script)">历史</v-btn>
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>

    <!-- Pagination -->
    <div v-if="totalItems > itemsPerPage" class="d-flex justify-center mt-4">
      <v-pagination v-model="page" :length="Math.ceil(totalItems / itemsPerPage)" rounded density="compact" @update:model-value="loadScripts" />
    </div>

    <!-- Execution Status Panel -->
    <v-card v-if="trackedExecs.length > 0" elevation="0" border rounded="lg" class="mt-4">
      <v-card-title class="d-flex align-center text-subtitle-1">
        <v-icon class="mr-2">mdi-progress-clock</v-icon>
        执行状态
        <v-spacer />
        <v-btn size="small" variant="text" @click="trackedExecs = []">清除</v-btn>
      </v-card-title>
      <v-divider />
      <v-card-text>
        <v-list density="compact">
          <v-list-item v-for="exec in trackedExecs" :key="exec.id" :title="exec.name">
            <template #subtitle>
              <span class="text-caption">ID: {{ exec.id }} · {{ exec.totalServers }} 台服务器</span>
            </template>
            <template #append>
              <div class="d-flex align-center ga-2">
                <v-chip :color="execStatusColor(exec.status)" size="x-small" variant="tonal" label>
                  {{ execStatusLabel(exec.status) }}
                </v-chip>
                <v-btn size="x-small" variant="text" @click="refreshExecStatus(exec)" :loading="exec.refreshing">
                  刷新
                </v-btn>
                <v-btn v-if="exec.status === 'running'" size="x-small" variant="text" color="error" @click="stopExec(exec)">
                  停止
                </v-btn>
              </div>
            </template>
          </v-list-item>
        </v-list>
      </v-card-text>
    </v-card>

    <!-- Script Editor Dialog -->
    <v-dialog v-model="showEditor" max-width="800" scrollable>
      <v-card border>
        <v-card-title>{{ editingScript ? '编辑脚本' : '新建脚本' }}</v-card-title>
        <v-divider />
        <v-card-text>
          <v-text-field v-model="form.name" label="脚本名称" variant="outlined" density="compact" class="mb-2" :rules="[required('脚本名称')]" />
          <v-text-field v-model="form.category" label="分类" variant="outlined" density="compact" class="mb-2" />
          <v-textarea v-model="form.description" label="描述" variant="outlined" density="compact" rows="2" class="mb-2" />
          <v-textarea
            v-model="form.content"
            label="脚本内容"
            variant="outlined"
            density="compact"
            rows="14"
            class="mt-2 font-monospace"
            :rules="[required('脚本内容')]"
          />
        </v-card-text>
        <v-divider />
        <v-card-actions>
          <v-spacer />
          <v-btn variant="text" @click="showEditor = false">取消</v-btn>
          <v-btn color="primary" variant="flat" @click="saveScript" :loading="saving">保存</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <!-- Run Script Dialog -->
    <v-dialog v-model="showRun" max-width="600">
      <v-card border>
        <v-card-title>执行脚本: {{ runningScript?.name }}</v-card-title>
        <v-card-text>
          <v-select
            v-model="runServerIds"
            :items="serverList"
            item-title="name"
            item-value="id"
            label="选择服务器"
            variant="outlined"
            density="compact"
            multiple
            chips
            class="mb-2"
          />
          <v-text-field v-model="runTimeout" label="超时（秒）" variant="outlined" density="compact" type="number" />
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn variant="text" @click="showRun = false">取消</v-btn>
          <v-btn color="primary" variant="flat" @click="doRun" :loading="executing">执行</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <!-- Delete Confirm -->
    <v-dialog v-model="showDelete" max-width="400">
      <v-card border>
        <v-card-title>确认删除</v-card-title>
        <v-card-text>确定要删除脚本 <strong>{{ deletingScript?.name }}</strong> 吗？</v-card-text>
        <v-card-actions>
          <v-spacer />
          <v-btn variant="text" @click="showDelete = false">取消</v-btn>
          <v-btn color="error" variant="flat" @click="doDelete">删除</v-btn>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <!-- Execution History Dialog -->
    <v-dialog v-model="showHistory" max-width="800" scrollable>
      <v-card border>
        <v-card-title>执行历史: {{ historyScript?.name }}</v-card-title>
        <v-divider />
        <v-card-text>
          <v-data-table
            :items="execHistory"
            :headers="execHeaders"
            density="compact"
            hover
          >
            <template #item.status="{ item }">
              <v-chip :color="item.status === 'completed' ? 'success' : item.status === 'failed' ? 'error' : 'info'" size="small" variant="tonal" label>
                {{ item.status }}
              </v-chip>
            </template>
            <template #item.command="{ item }">
              <code class="text-body-2">{{ item.command.length > 60 ? item.command.slice(0, 60) + '…' : item.command }}</code>
            </template>
            <template #item.progress="{ item }">
              <span v-if="item.progress">{{ item.progress.done }}/{{ item.progress.total }}</span>
              <span v-else class="text-medium-emphasis">—</span>
            </template>
            <template #no-data>
              <div class="text-center text-medium-emphasis py-6">暂无数据</div>
            </template>
          </v-data-table>
        </v-card-text>
      </v-card>
    </v-dialog>
  </v-container>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { http } from '@/api'
import { useServerList } from '@/composables/useServerList'
import { useSnackbar } from '@/composables/useSnackbar'
import { required } from '@/utils/validation'

const snackbar = useSnackbar()
const { servers: serverList, loadServers } = useServerList()

// ── State ──
const loading = ref(false)
const search = ref('')
const scripts = ref<ScriptItem[]>([])

// Pagination
const page = ref(1)
const totalItems = ref(0)
const itemsPerPage = ref(20)

// Editor
const showEditor = ref(false)
const editingScript = ref<ScriptItem | null>(null)
const saving = ref(false)
const form = ref({ name: '', category: '', description: '', content: '' })

// Run
const showRun = ref(false)
const runningScript = ref<ScriptItem | null>(null)
const runServerIds = ref<number[]>([])
const runTimeout = ref(300)
const executing = ref(false)

// Delete
const showDelete = ref(false)
const deletingScript = ref<ScriptItem | null>(null)

// History
const showHistory = ref(false)
const historyScript = ref<ScriptItem | null>(null)
interface ExecHistoryItem {
  id: number
  script_id: number
  command: string
  server_ids: string
  status: string
  results: Record<string, { status?: string; output?: string; exit_code?: number }>
  events: Array<{ event: string; ts: string }>
  operator: string | null
  started_at: string | null
  completed_at: string | null
  long_task?: boolean
  progress?: { total: number; done: number; succeeded: number; failed: number }
  source: string
}

const execHistory = ref<ExecHistoryItem[]>([])

// Quick Execute
const showQuickExec = ref(false)
const quickCommand = ref('')
const quickServerIds = ref<number[]>([])
const quickTimeout = ref(60)
const quickExecuting = ref(false)

// Execution Tracking
interface TrackedExec {
  id: number
  name: string
  status: 'running' | 'completed' | 'failed' | 'partial'
  totalServers: number
  completedServers: number
  refreshing: boolean
}

const trackedExecs = ref<TrackedExec[]>([])
let pollTimer: ReturnType<typeof setInterval> | null = null

const execHeaders = [
  { title: '命令', key: 'command' },
  { title: '状态', key: 'status', width: 100 },
  { title: '进度', key: 'progress', width: 100 },
  { title: '操作人', key: 'operator', width: 80 },
  { title: '开始时间', key: 'started_at', width: 160 },
]

const filteredScripts = computed(() => {
  if (!search.value) return scripts.value
  const q = search.value.toLowerCase()
  return scripts.value.filter(s =>
    s.name.toLowerCase().includes(q) ||
    (s.category || '').toLowerCase().includes(q)
  )
})

// ── Data loading ──
async function loadScripts() {
  loading.value = true
  try {
    const res = await http.getList<ScriptItem>('/scripts/', {
      page: page.value,
      per_page: itemsPerPage.value,
    })
    scripts.value = res.items
    totalItems.value = res.total
  } catch { scripts.value = [] }
  finally { loading.value = false }
}

watch(search, () => { page.value = 1; loadScripts() })

// ── Actions ──
function openEditor(script: ScriptItem | null) {
  editingScript.value = script
  if (script) {
    form.value = { name: script.name, category: script.category || '', description: script.description || '', content: script.content || '' }
  } else {
    form.value = { name: '', category: '', description: '', content: '' }
  }
  showEditor.value = true
}

async function saveScript() {
  saving.value = true
  try {
    if (editingScript.value) {
      await http.put(`/scripts/${editingScript.value.id}`, form.value)
    } else {
      await http.post('/scripts/', form.value)
    }
    showEditor.value = false
    loadScripts()
    snackbar('保存成功')
  } catch (e: any) {
    snackbar(e.message || '保存失败', 'error')
  } finally {
    saving.value = false
  }
}

function runScript(script: ScriptItem) {
  runningScript.value = script
  runServerIds.value = []
  showRun.value = true
}

async function doRun() {
  if (!runningScript.value || !runServerIds.value.length) {
    snackbar('请选择服务器', 'warning')
    return
  }
  executing.value = true
  try {
    const res = await http.post<{ execution_id: number }>('/scripts/exec', {
      script_id: runningScript.value.id,
      server_ids: runServerIds.value,
      timeout: runTimeout.value,
    })
    showRun.value = false
    snackbar('脚本已提交执行')
    addTrackedExecution(runningScript.value.name, res.execution_id, runServerIds.value.length)
  } catch (e: any) {
    snackbar(e.message || '执行失败', 'error')
  } finally {
    executing.value = false
  }
}

function confirmDelete(script: ScriptItem) {
  deletingScript.value = script
  showDelete.value = true
}

async function doDelete() {
  if (!deletingScript.value) return
  try {
    await http.delete(`/scripts/${deletingScript.value.id}`)
    showDelete.value = false
    loadScripts()
    snackbar('已删除')
  } catch (e: any) {
    snackbar(e.message || '删除失败', 'error')
  }
}

async function viewHistory(script: ScriptItem) {
  historyScript.value = script
  showHistory.value = true
  try {
    const res = await http.get<{ items: ExecHistoryItem[]; total: number }>('/scripts/executions', { script_id: script.id })
    execHistory.value = res.items || []
  } catch {
    execHistory.value = []
  }
}

// ── Quick Execute ──
async function doQuickExec() {
  if (!quickCommand.value || quickServerIds.value.length === 0) return
  quickExecuting.value = true
  try {
    const res = await http.post<{ execution_id: number; results: Record<string, unknown> }>('/scripts/exec', {
      command: quickCommand.value,
      server_ids: quickServerIds.value,
      timeout: quickTimeout.value,
    })
    snackbar(`已在 ${quickServerIds.value.length} 台服务器上执行`)
    addTrackedExecution('临时命令', res.execution_id, quickServerIds.value.length)
  } catch (e: any) { snackbar(e.message || '执行失败', 'error') }
  finally { quickExecuting.value = false }
}

// ── Execution Tracking ──
function addTrackedExecution(name: string, execId: number, totalServers: number) {
  trackedExecs.value.unshift({ id: execId, name, status: 'running', totalServers, completedServers: 0, refreshing: false })
  startPolling()
}

function startPolling() {
  if (pollTimer) return
  pollTimer = setInterval(async () => {
    const running = trackedExecs.value.filter(e => e.status === 'running')
    if (running.length === 0) { stopPolling(); return }
    for (const exec of running) await refreshExecStatus(exec)
  }, 5000)
}

function stopPolling() {
  if (pollTimer) { clearInterval(pollTimer); pollTimer = null }
}

async function refreshExecStatus(exec: TrackedExec) {
  exec.refreshing = true
  try {
    const res = await http.get<{ status: string; results: Record<string, { status: string }> }>(`/scripts/executions/${exec.id}`)
    const results = res.results || {}
    const statuses = Object.values(results)
    exec.completedServers = statuses.filter(s => s.status !== 'running' && s.status !== 'pending').length
    exec.status = res.status as TrackedExec['status']
  } catch { /* ignore */ }
  finally { exec.refreshing = false }
}

async function stopExec(exec: TrackedExec) {
  try {
    await http.post(`/scripts/executions/${exec.id}/stop`)
    exec.status = 'failed'
    snackbar('已发送停止指令')
  } catch (e: any) { snackbar(e.message || '停止失败', 'error') }
}

function execStatusColor(s: string) {
  return s === 'running' ? 'blue' : s === 'completed' ? 'green' : s === 'failed' ? 'red' : 'orange'
}

function execStatusLabel(s: string) {
  return s === 'running' ? '执行中' : s === 'completed' ? '已完成' : s === 'failed' ? '失败' : '部分完成'
}


onMounted(() => {
  loadScripts()
  loadServers()
})

onUnmounted(() => {
  stopPolling()
})

interface ScriptItem {
  id: number; name: string; category: string | null; description: string | null
  content: string | null; created_at: string; updated_at: string
}
</script>
