<script setup>
import { ref, reactive, onMounted, computed, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Delete, VideoPlay, Document, FolderOpened, Search, Refresh, CopyDocument } from '@element-plus/icons-vue'
import api from '@/api'
import { useAuthStore } from '@/stores/auth'
import MonacoEditor from '@/components/MonacoEditor.vue'

const authStore = useAuthStore()

// 脚本列表
const loading = ref(false)
const scriptList = ref([])
const categories = ref([])
const total = ref(0)
const query = reactive({
  page: 1,
  size: 100,
  category: '',
  keyword: ''
})

// 当前编辑的脚本
const currentScript = ref(null)
const scriptContent = ref('')
const isModified = ref(false)
const saving = ref(false)
const running = ref(false)

// 新建对话框
const createDialogVisible = ref(false)
const createForm = reactive({
  name: '',
  filename: '',
  description: '',
  category: '',
  script_content: '# 新脚本\n\nlog("Hello World!")\n'
})

// 运行结果
const runResult = ref(null)
const runDialogVisible = ref(false)

// SDK 文档
const sdkDocsVisible = ref(false)
const sdkDocs = ref(null)

// 监听内容变化
watch(scriptContent, (newVal) => {
  if (currentScript.value) {
    isModified.value = newVal !== currentScript.value.script_content
  }
})

// 获取脚本列表
async function fetchScripts() {
  loading.value = true
  try {
    const res = await api.get('/api/scripts', { params: query })
    scriptList.value = res.data.items || []
    categories.value = res.data.categories || []
    total.value = res.data.total || 0
  } catch (e) {
    console.error(e)
  } finally {
    loading.value = false
  }
}

// 选择脚本
async function selectScript(script) {
  // 检查是否有未保存的修改
  if (isModified.value && currentScript.value) {
    try {
      await ElMessageBox.confirm('当前脚本有未保存的修改，是否放弃？', '提示', {
        type: 'warning',
        confirmButtonText: '放弃',
        cancelButtonText: '取消'
      })
    } catch {
      return
    }
  }
  
  try {
    const res = await api.get(`/api/scripts/${script.id}`)
    currentScript.value = res.data
    scriptContent.value = res.data.script_content || ''
    isModified.value = false
  } catch (e) {
    console.error(e)
  }
}

// 保存脚本
async function handleSave() {
  if (!currentScript.value) return
  
  saving.value = true
  try {
    await api.put(`/api/scripts/${currentScript.value.id}`, {
      script_content: scriptContent.value
    })
    currentScript.value.script_content = scriptContent.value
    isModified.value = false
    ElMessage.success('保存成功')
  } catch (e) {
    // 错误已在拦截器处理
  } finally {
    saving.value = false
  }
}

// 运行脚本
async function handleRun() {
  if (!currentScript.value) return
  
  // 如果有修改，先保存
  if (isModified.value) {
    await handleSave()
  }
  
  running.value = true
  runResult.value = null
  
  try {
    const res = await api.post(`/api/scripts/${currentScript.value.id}/run`)
    runResult.value = res.data
    runDialogVisible.value = true
    fetchScripts() // 刷新执行状态
  } catch (e) {
    runResult.value = { success: false, error: e.message || '执行失败' }
    runDialogVisible.value = true
  } finally {
    running.value = false
  }
}

// 新建脚本
function handleCreate() {
  Object.assign(createForm, {
    name: '',
    filename: '',
    description: '',
    category: '',
    script_content: '# 新脚本\n\nlog("Hello World!")\n'
  })
  createDialogVisible.value = true
}

async function submitCreate() {
  if (!createForm.name) {
    ElMessage.warning('请输入脚本名称')
    return
  }
  
  try {
    const res = await api.post('/api/scripts', createForm)
    ElMessage.success('创建成功')
    createDialogVisible.value = false
    await fetchScripts()
    
    // 自动选中新创建的脚本
    const newScript = scriptList.value.find(s => s.id === res.data.id)
    if (newScript) {
      selectScript(newScript)
    }
  } catch (e) {
    // 错误已在拦截器处理
  }
}

// 删除脚本
async function handleDelete() {
  if (!currentScript.value) return
  
  await ElMessageBox.confirm(
    `确定删除脚本「${currentScript.value.name}」吗？此操作不可恢复。`,
    '删除确认',
    { type: 'warning' }
  )
  
  try {
    await api.delete(`/api/scripts/${currentScript.value.id}`)
    ElMessage.success('删除成功')
    currentScript.value = null
    scriptContent.value = ''
    isModified.value = false
    fetchScripts()
  } catch (e) {
    // 错误已在拦截器处理
  }
}

// 复制脚本
async function handleCopy() {
  if (!currentScript.value) return
  
  try {
    const res = await api.post(`/api/scripts/${currentScript.value.id}/copy`)
    ElMessage.success('复制成功')
    await fetchScripts()
    
    // 自动选中新创建的脚本
    const newScript = scriptList.value.find(s => s.id === res.data.id)
    if (newScript) {
      selectScript(newScript)
    }
  } catch (e) {
    // 错误已在拦截器处理
  }
}

// 更新脚本信息
async function handleUpdateInfo() {
  if (!currentScript.value) return
  
  const { value } = await ElMessageBox.prompt('请输入新的脚本名称', '修改名称', {
    inputValue: currentScript.value.name,
    confirmButtonText: '保存',
    cancelButtonText: '取消'
  })
  
  if (value && value !== currentScript.value.name) {
    try {
      await api.put(`/api/scripts/${currentScript.value.id}`, { name: value })
      currentScript.value.name = value
      ElMessage.success('修改成功')
      fetchScripts()
    } catch (e) {
      // 错误已在拦截器处理
    }
  }
}

// 查看 SDK 文档
async function handleShowSdkDocs() {
  try {
    const res = await api.get('/api/scheduled-tasks/sdk-docs')
    sdkDocs.value = res.data
    sdkDocsVisible.value = true
  } catch (e) {
    ElMessage.error('获取文档失败')
  }
}

// 格式化时间
function formatTime(time) {
  if (!time) return '-'
  return new Date(time).toLocaleString('zh-CN')
}

// 获取状态类型
function getStatusType(status) {
  const map = {
    success: 'success',
    failed: 'danger',
    running: 'warning'
  }
  return map[status] || 'info'
}

onMounted(() => {
  fetchScripts()
})
</script>

<template>
  <div class="scripts-page">
    <!-- 左侧：脚本列表 -->
    <div class="scripts-sidebar">
      <div class="sidebar-header">
        <h3>脚本管理</h3>
        <el-button v-if="authStore.isOperator" type="primary" size="small" @click="handleCreate">
          <el-icon><Plus /></el-icon>
          新建
        </el-button>
      </div>
      
      <!-- 搜索和筛选 -->
      <div class="sidebar-filter">
        <el-input
          v-model="query.keyword"
          placeholder="搜索脚本..."
          clearable
          size="small"
          @change="fetchScripts"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
        <el-select
          v-model="query.category"
          placeholder="分类"
          clearable
          size="small"
          style="width: 100%; margin-top: 8px"
          @change="fetchScripts"
        >
          <el-option
            v-for="cat in categories"
            :key="cat"
            :label="cat"
            :value="cat"
          />
        </el-select>
      </div>
      
      <!-- 脚本列表 -->
      <div class="scripts-list" v-loading="loading">
        <div
          v-for="script in scriptList"
          :key="script.id"
          class="script-item"
          :class="{ active: currentScript?.id === script.id }"
          @click="selectScript(script)"
        >
          <div class="script-icon">
            <el-icon><Document /></el-icon>
          </div>
          <div class="script-info">
            <div class="script-name">{{ script.name }}</div>
            <div class="script-meta">
              <el-tag v-if="script.category" size="small" type="info">{{ script.category }}</el-tag>
              <el-tag 
                v-if="script.last_run_status" 
                size="small" 
                :type="getStatusType(script.last_run_status)"
              >
                {{ script.last_run_status }}
              </el-tag>
            </div>
          </div>
        </div>
        
        <div v-if="!loading && scriptList.length === 0" class="empty-tip">
          暂无脚本
        </div>
      </div>
    </div>
    
    <!-- 右侧：编辑器区域 -->
    <div class="scripts-editor">
      <template v-if="currentScript">
        <!-- 工具栏 -->
        <div class="editor-toolbar">
          <div class="toolbar-left">
            <span class="script-title" @click="handleUpdateInfo">
              {{ currentScript.name }}
              <span v-if="isModified" class="modified-dot">●</span>
            </span>
            <span class="script-filename">{{ currentScript.filename }}</span>
          </div>
          <div class="toolbar-right">
            <el-button link size="small" @click="handleShowSdkDocs">
              SDK 文档
            </el-button>
            <el-button 
              type="primary" 
              size="small" 
              :loading="saving"
              :disabled="!isModified"
              @click="handleSave"
            >
              保存 (Ctrl+S)
            </el-button>
            <el-button 
              type="success" 
              size="small" 
              :loading="running"
              @click="handleRun"
            >
              <el-icon><VideoPlay /></el-icon>
              运行 (Ctrl+Enter)
            </el-button>
            <el-button link size="small" @click="handleCopy">
              <el-icon><CopyDocument /></el-icon>
              复制
            </el-button>
            <el-button v-if="authStore.isOperator" type="danger" link size="small" @click="handleDelete">
              <el-icon><Delete /></el-icon>
              删除
            </el-button>
          </div>
        </div>
        
        <!-- Monaco 编辑器 -->
        <div class="editor-container">
          <MonacoEditor
            v-model="scriptContent"
            language="python"
            theme="vs-dark"
            height="100%"
            @save="handleSave"
            @run="handleRun"
          />
        </div>
        
        <!-- 脚本信息 -->
        <div class="editor-footer">
          <span>创建：{{ formatTime(currentScript.created_at) }}</span>
          <span>更新：{{ formatTime(currentScript.updated_at) }}</span>
          <span v-if="currentScript.last_run_at">
            上次运行：{{ formatTime(currentScript.last_run_at) }}
            <el-tag size="small" :type="getStatusType(currentScript.last_run_status)">
              {{ currentScript.last_run_status }}
            </el-tag>
          </span>
        </div>
      </template>
      
      <!-- 未选择脚本时的占位 -->
      <div v-else class="editor-placeholder">
        <el-icon :size="64" color="#dcdfe6"><Document /></el-icon>
        <p>选择一个脚本开始编辑</p>
        <p style="color: #909399; font-size: 12px">或点击左上角"新建"创建新脚本</p>
      </div>
    </div>
    
    <!-- 新建脚本对话框 -->
    <el-dialog v-model="createDialogVisible" title="新建脚本" width="500px">
      <el-form :model="createForm" label-width="80px">
        <el-form-item label="脚本名称" required>
          <el-input v-model="createForm.name" placeholder="如：每日数据同步" />
        </el-form-item>
        <el-form-item label="文件名">
          <el-input v-model="createForm.filename" placeholder="可选，如 daily_sync.py" />
        </el-form-item>
        <el-form-item label="分类">
          <el-select v-model="createForm.category" placeholder="选择或输入分类" filterable allow-create style="width: 100%">
            <el-option v-for="cat in categories" :key="cat" :label="cat" :value="cat" />
          </el-select>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="createForm.description" type="textarea" :rows="2" placeholder="可选" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="createDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitCreate">创建</el-button>
      </template>
    </el-dialog>
    
    <!-- 运行结果对话框 -->
    <el-dialog v-model="runDialogVisible" title="运行结果" width="700px">
      <div v-if="runResult" class="run-result">
        <el-alert 
          :type="runResult.success ? 'success' : 'error'" 
          :closable="false"
          style="margin-bottom: 16px"
        >
          <template #title>
            {{ runResult.success ? '执行成功' : '执行失败' }}
            <span v-if="runResult.execution_time_ms" style="margin-left: 8px; color: #909399">
              ({{ runResult.execution_time_ms }}ms)
            </span>
          </template>
        </el-alert>
        
        <div v-if="runResult.error" class="result-section">
          <h4>错误信息</h4>
          <pre class="result-content error">{{ runResult.error }}</pre>
        </div>
        
        <div v-if="runResult.output" class="result-section">
          <h4>输出</h4>
          <pre class="result-content">{{ runResult.output }}</pre>
        </div>
        
        <div v-if="runResult.logs && runResult.logs.length" class="result-section">
          <h4>日志</h4>
          <pre class="result-content logs">{{ runResult.logs.join('\n') }}</pre>
        </div>
      </div>
      <template #footer>
        <el-button @click="runDialogVisible = false">关闭</el-button>
      </template>
    </el-dialog>
    
    <!-- SDK 文档对话框 -->
    <el-dialog v-model="sdkDocsVisible" title="SDK 文档" width="800px">
      <div v-if="sdkDocs" class="sdk-docs">
        <p>{{ sdkDocs.description }}</p>
        
        <h4>可用方法</h4>
        <div v-for="method in sdkDocs.methods" :key="method.name" class="sdk-method">
          <code>{{ method.name }}</code>
          <p>{{ method.description }}</p>
          <pre class="sdk-example">{{ method.example }}</pre>
        </div>
        
        <h4>示例脚本</h4>
        <pre class="sdk-example-script">{{ sdkDocs.example_script }}</pre>
      </div>
      <template #footer>
        <el-button @click="sdkDocsVisible = false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.scripts-page {
  display: flex;
  height: calc(100vh - 120px);
  background: #fff;
  border-radius: 8px;
  overflow: hidden;
}

/* 左侧边栏 */
.scripts-sidebar {
  width: 280px;
  border-right: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;
  background: #fafafa;
}

.sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-bottom: 1px solid #e4e7ed;
}

.sidebar-header h3 {
  margin: 0;
  font-size: 16px;
  color: #303133;
}

.sidebar-filter {
  padding: 12px 16px;
  border-bottom: 1px solid #e4e7ed;
}

.scripts-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
}

.script-item {
  display: flex;
  align-items: center;
  padding: 10px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
  margin-bottom: 4px;
}

.script-item:hover {
  background: #ecf5ff;
}

.script-item.active {
  background: #409eff;
  color: #fff;
}

.script-item.active .script-meta .el-tag {
  background: rgba(255, 255, 255, 0.2);
  border-color: rgba(255, 255, 255, 0.3);
  color: #fff;
}

.script-icon {
  margin-right: 10px;
  font-size: 20px;
  color: #909399;
}

.script-item.active .script-icon {
  color: #fff;
}

.script-info {
  flex: 1;
  min-width: 0;
}

.script-name {
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.script-meta {
  display: flex;
  gap: 4px;
  margin-top: 4px;
}

.empty-tip {
  text-align: center;
  color: #909399;
  padding: 40px 0;
}

/* 右侧编辑器 */
.scripts-editor {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.editor-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #e4e7ed;
  background: #fff;
}

.toolbar-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.script-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  cursor: pointer;
}

.script-title:hover {
  color: #409eff;
}

.modified-dot {
  color: #e6a23c;
  margin-left: 4px;
}

.script-filename {
  font-size: 12px;
  color: #909399;
}

.toolbar-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.editor-container {
  flex: 1;
  min-height: 0;
}

.editor-footer {
  display: flex;
  gap: 24px;
  padding: 8px 16px;
  font-size: 12px;
  color: #909399;
  background: #fafafa;
  border-top: 1px solid #e4e7ed;
}

.editor-placeholder {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: #909399;
}

.editor-placeholder p {
  margin-top: 16px;
  font-size: 14px;
}

/* 运行结果 */
.run-result {
  max-height: 500px;
  overflow-y: auto;
}

.result-section {
  margin-bottom: 16px;
}

.result-section h4 {
  margin: 0 0 8px;
  font-size: 14px;
  color: #303133;
}

.result-content {
  background: #f5f7fa;
  padding: 12px;
  border-radius: 4px;
  font-size: 13px;
  max-height: 200px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-all;
  margin: 0;
}

.result-content.error {
  background: #fef0f0;
  color: #f56c6c;
}

.result-content.logs {
  background: #1e1e1e;
  color: #d4d4d4;
}

/* SDK 文档 */
.sdk-docs {
  max-height: 60vh;
  overflow-y: auto;
}

.sdk-docs h4 {
  margin: 16px 0 8px;
  color: #303133;
}

.sdk-method {
  margin-bottom: 16px;
  padding: 12px;
  background: #f5f7fa;
  border-radius: 8px;
}

.sdk-method code {
  display: block;
  font-size: 14px;
  font-weight: 600;
  color: #409eff;
  margin-bottom: 8px;
}

.sdk-method p {
  margin: 0 0 8px;
  color: #606266;
}

.sdk-example {
  background: #fff;
  padding: 8px;
  border-radius: 4px;
  font-size: 12px;
  margin: 0;
  color: #303133;
}

.sdk-example-script {
  background: #1e1e1e;
  color: #d4d4d4;
  padding: 16px;
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
  overflow-x: auto;
}
</style>
