<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import {
  getProject, updateProject, triggerBuild, startProject, stopProject, restartProject,
  getBuilds, uploadFile, createLogStream,
  getDeployConfig, updateDeployConfig, deleteDeployConfig, triggerDeploy, getDeployRecords, getDeployLog
} from '../api'
import { ElMessage, ElMessageBox } from 'element-plus'

const props = defineProps({ id: String })
const router = useRouter()

const project = ref(null)
const builds = ref([])
const logs = ref([])
const logContainer = ref(null)
const activeTab = ref('overview')
const loading = ref(true)
const actionLoading = ref(false)
const editingSettings = ref(false)
const settingsForm = ref({})
const uploadRef = ref(null)

const deployConfig = ref(null)
const deployRecords = ref([])
const editingDeploy = ref(false)
const deployForm = ref({
  host: '', port: 22, username: '', auth_method: 'key',
  ssh_key: '', ssh_password: '',
  deploy_dir: '', file_mappings: '',
  pre_deploy_command: '', post_deploy_command: '',
  health_check_url: '', health_check_timeout: 30,
  auto_deploy: false,
})

let sse = null

const projectId = () => parseInt(props.id)

const fetchProject = async () => {
  try {
    project.value = await getProject(projectId())
  } catch (e) {
    ElMessage.error('Project not found')
    router.push('/')
  } finally {
    loading.value = false
  }
}

const fetchBuilds = async () => {
  try { builds.value = await getBuilds(projectId()) } catch (e) { /* ignore */ }
}

const connectLogStream = () => {
  if (sse) sse.close()
  sse = createLogStream(projectId())
  sse.onmessage = (event) => {
    logs.value.push(event.data)
    if (logs.value.length > 1000) logs.value.shift()
    setTimeout(() => {
      if (logContainer.value) logContainer.value.scrollTop = logContainer.value.scrollHeight
    }, 50)
  }
  sse.onerror = () => {}
}

const doBuild = async () => {
  actionLoading.value = true
  try {
    await triggerBuild(projectId())
    ElMessage.success('Build started')
    logs.value = []
    activeTab.value = 'logs'
    connectLogStream()
    fetchDeployRecords()
    pollStatus(30000)
  } catch (e) {
    ElMessage.error(e.response?.data?.error || 'Build failed')
  } finally {
    actionLoading.value = false
  }
}

const doStart = async () => {
  actionLoading.value = true
  try {
    await startProject(projectId())
    ElMessage.success('Project started')
    fetchProject()
  } catch (e) {
    ElMessage.error(e.response?.data?.error || 'Failed to start')
  } finally { actionLoading.value = false }
}

const doStop = async () => {
  actionLoading.value = true
  try {
    await stopProject(projectId())
    ElMessage.success('Project stopped')
    fetchProject()
  } catch (e) {
    ElMessage.error(e.response?.data?.error || 'Failed to stop')
  } finally { actionLoading.value = false }
}

const doRestart = async () => {
  actionLoading.value = true
  try {
    await restartProject(projectId())
    ElMessage.success('Project restarted')
    fetchProject()
  } catch (e) {
    ElMessage.error(e.response?.data?.error || 'Failed to restart')
  } finally { actionLoading.value = false }
}

const doUpload = async (file) => {
  const formData = new FormData()
  formData.append('file', file.file)
  try {
    await uploadFile(projectId(), formData)
    ElMessage.success('File uploaded and extracted')
    fetchProject()
  } catch (e) {
    ElMessage.error(e.response?.data?.error || 'Upload failed')
  }
}

const saveSettings = async () => {
  try {
    await updateProject(projectId(), settingsForm.value)
    ElMessage.success('Settings saved')
    editingSettings.value = false
    fetchProject()
  } catch (e) {
    ElMessage.error('Failed to save settings')
  }
}

const fetchDeployConfig = async () => {
  try {
    const cfg = await getDeployConfig(projectId())
    if (cfg && cfg.id) deployConfig.value = cfg
  } catch (e) {}
}

const fetchDeployRecords = async () => {
  try { deployRecords.value = await getDeployRecords(projectId()) } catch (e) {}
}

const saveDeployConfig = async () => {
  try {
    await updateDeployConfig(projectId(), deployForm.value)
    ElMessage.success('Deploy config saved')
    editingDeploy.value = false
    fetchDeployConfig()
  } catch (e) {
    ElMessage.error(e.response?.data?.error || 'Failed to save deploy config')
  }
}

const removeDeployConfig = async () => {
  try {
    await ElMessageBox.confirm('Remove deploy configuration?', 'Confirm', { type: 'warning' })
    await deleteDeployConfig(projectId())
    ElMessage.success('Deploy config removed')
    deployConfig.value = null
    deployRecords.value = []
  } catch (e) {}
}

const doDeploy = async () => {
  actionLoading.value = true
  try {
    await triggerDeploy(projectId())
    ElMessage.success('Deployment started')
    logs.value = []
    activeTab.value = 'logs'
    connectLogStream()
    setTimeout(() => { fetchProject(); fetchDeployRecords() }, 3000)
  } catch (e) {
    ElMessage.error(e.response?.data?.error || 'Failed to start deploy')
  } finally { actionLoading.value = false }
}

const viewDeployLog = async (deployId) => {
  try {
    const log = await getDeployLog(projectId(), deployId)
    logs.value = log.split('\n')
    activeTab.value = 'logs'
    setTimeout(() => {
      if (logContainer.value) logContainer.value.scrollTop = logContainer.value.scrollHeight
    }, 100)
  } catch (e) {
    ElMessage.error('Failed to load deploy log')
  }
}

const deployStatusTag = (s) => {
  const map = { running: 'warning', success: 'success', failed: 'danger' }
  return map[s] || 'info'
}

const pollStatus = (duration) => {
  const interval = setInterval(async () => {
    try {
      const p = await getProject(projectId())
      project.value = p
      if (p.status !== 'building') {
        clearInterval(interval)
        fetchBuilds()
      }
    } catch (e) { clearInterval(interval) }
  }, 2000)
  setTimeout(() => clearInterval(interval), duration)
}

const statusTag = (s) => {
  const map = { running: 'success', stopped: 'info', building: 'warning', error: 'danger' }
  return map[s] || 'info'
}

onMounted(() => {
  fetchProject()
  fetchBuilds()
  fetchDeployConfig()
  fetchDeployRecords()
  connectLogStream()
})

onUnmounted(() => { if (sse) sse.close() })
</script>

<template>
  <div v-loading="loading" class="detail-page">
    <el-page-header @back="router.push('/')" class="page-back">
      <template #content>
        <span v-if="project" class="back-title">{{ project.name }}</span>
      </template>
    </el-page-header>

    <div v-if="project">
      <!-- ==== Action Bar ==== -->
      <div class="action-bar">
        <div class="action-bar-left">
          <span class="status-badge" :class="'badge-' + project.status">
            <span class="badge-dot"></span>
            {{ project.status }}
          </span>
          <span class="mode-badge">{{ project.mode === 'git' ? 'Git' : 'Upload' }}</span>
        </div>
        <div class="action-bar-right">
          <el-button-group class="btn-group">
            <el-button type="primary" :loading="actionLoading" @click="doBuild" :disabled="project.status === 'building'">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="btn-icon"><polyline points="14.5 17.5 3 6 3 3 6 3 17.5 14.5"/><line x1="13" y1="19" x2="19" y2="13"/><line x1="16" y1="16" x2="20" y2="20"/><line x1="19" y1="21" x2="21" y2="19"/></svg>
              Build
            </el-button>
            <el-button type="success" :loading="actionLoading" @click="doStart" :disabled="project.status === 'running'">
              <svg viewBox="0 0 24 24" fill="currentColor" stroke="none" class="btn-icon"><polygon points="5 3 19 12 5 21 5 3"/></svg>
              Start
            </el-button>
            <el-button type="warning" :loading="actionLoading" @click="doStop" :disabled="project.status !== 'running'">
              <svg viewBox="0 0 24 24" fill="currentColor" stroke="none" class="btn-icon"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>
              Stop
            </el-button>
            <el-button :loading="actionLoading" @click="doRestart" :disabled="project.status !== 'running'">
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="btn-icon"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>
              Restart
            </el-button>
          </el-button-group>
          <el-button
            v-if="deployConfig"
            type="primary"
            :loading="actionLoading"
            @click="doDeploy"
            class="btn-deploy"
            plain
          >
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="btn-icon"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
            Deploy
          </el-button>
        </div>
      </div>

      <!-- ==== Tabs ==== -->
      <el-tabs v-model="activeTab" class="main-tabs">
        <!-- Overview -->
        <el-tab-pane label="Overview" name="overview">
          <div class="overview-grid">
            <el-card class="ov-card" shadow="never">
              <template #header><span class="card-header-title">Project Info</span></template>
              <el-descriptions :column="1" border>
                <el-descriptions-item label="Status">
                  <el-tag :type="statusTag(project.status)" effect="dark" size="small">{{ project.status }}</el-tag>
                </el-descriptions-item>
                <el-descriptions-item label="Mode">{{ project.mode }}</el-descriptions-item>
                <el-descriptions-item label="PID">{{ project.pid || '—' }}</el-descriptions-item>
                <el-descriptions-item label="Port">{{ project.port || '—' }}</el-descriptions-item>
                <el-descriptions-item label="Created">{{ new Date(project.created_at).toLocaleString() }}</el-descriptions-item>
              </el-descriptions>
            </el-card>
            <el-card class="ov-card" shadow="never" v-if="project.mode === 'git'">
              <template #header><span class="card-header-title">Git Repository</span></template>
              <el-descriptions :column="1" border>
                <el-descriptions-item label="URL">{{ project.git_url || '—' }}</el-descriptions-item>
                <el-descriptions-item label="Branch">{{ project.git_branch || 'master' }}</el-descriptions-item>
              </el-descriptions>
            </el-card>
            <el-card class="ov-card" shadow="never">
              <template #header><span class="card-header-title">Build Config</span></template>
              <el-descriptions :column="1" border>
                <el-descriptions-item label="Build Script">{{ project.build_script || 'go build -o app .' }}</el-descriptions-item>
                <el-descriptions-item label="Output Binary">{{ project.output_binary || 'app' }}</el-descriptions-item>
                <el-descriptions-item label="Run Command">{{ project.run_command || './app' }}</el-descriptions-item>
              </el-descriptions>
            </el-card>
          </div>
          <el-card v-if="project.mode === 'upload'" shadow="never" class="upload-card">
            <template #header><span class="card-header-title">Upload Source Files</span></template>
            <el-upload ref="uploadRef" drag :auto-upload="false" :on-change="doUpload" :limit="1" accept=".zip,.tar.gz,.tgz">
              <div class="upload-area">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" class="upload-icon"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
                <p>Drop .zip or .tar.gz here or click to upload</p>
              </div>
            </el-upload>
          </el-card>
        </el-tab-pane>

        <!-- Logs -->
        <el-tab-pane label="Logs" name="logs">
          <div class="log-console" ref="logContainer">
            <div v-if="logs.length === 0" class="log-empty">
              <span class="log-prompt">Waiting for output...</span>
            </div>
            <div v-for="(line, i) in logs" :key="i" class="log-line" :class="{ 'log-deploy': line.startsWith('[Deploy]'), 'log-error': line.includes('ERROR') || line.includes('FAILED') || line.includes('failed'), 'log-success': line.includes('SUCCESS') || line.includes('completed successfully') }">{{ line }}</div>
          </div>
        </el-tab-pane>

        <!-- Build History -->
        <el-tab-pane label="Build History" name="builds">
          <el-card shadow="never">
            <el-table :data="builds" stripe class="history-table">
              <el-table-column prop="id" label="#" width="60" align="center" />
              <el-table-column prop="status" label="Status" width="110">
                <template #default="{ row }">
                  <el-tag :type="row.status === 'success' ? 'success' : row.status === 'running' ? 'warning' : 'danger'" size="small" effect="dark" round>
                    {{ row.status }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="Commit" width="120">
                <template #default="{ row }">
                  <code v-if="row.commit_hash" class="commit-hash">{{ (row.commit_hash || '').slice(0, 7) }}</code>
                  <span v-else class="text-muted">—</span>
                </template>
              </el-table-column>
              <el-table-column label="Started" width="180">
                <template #default="{ row }">{{ new Date(row.started_at).toLocaleString() }}</template>
              </el-table-column>
              <el-table-column label="Duration">
                <template #default="{ row }">
                  <span v-if="row.finished_at">{{ Math.round((new Date(row.finished_at) - new Date(row.started_at)) / 1000) }}s</span>
                  <span v-else class="text-muted">—</span>
                </template>
              </el-table-column>
              <el-table-column label="Log" width="100" align="center">
                <template #default="{ row }">
                  <el-button size="small" text type="primary" @click="activeTab = 'logs'">View</el-button>
                </template>
              </el-table-column>
            </el-table>
            <el-empty v-if="builds.length === 0" description="No builds yet" :image-size="80" />
          </el-card>
        </el-tab-pane>

        <!-- Settings -->
        <el-tab-pane label="Settings" name="settings">
          <el-card shadow="never">
            <template #header>
              <div class="card-header-row">
                <span class="card-header-title">Project Settings</span>
                <el-button v-if="!editingSettings" type="primary" plain size="small" round @click="editingSettings = true; settingsForm = { ...project }">Edit</el-button>
              </div>
            </template>
            <el-form v-if="editingSettings" :model="settingsForm" label-position="top">
              <el-form-item label="Name"><el-input v-model="settingsForm.name" /></el-form-item>
              <el-form-item label="Description"><el-input v-model="settingsForm.description" type="textarea" :rows="2" /></el-form-item>
              <el-form-item v-if="project.mode === 'git'" label="Git URL"><el-input v-model="settingsForm.git_url" /></el-form-item>
              <el-form-item v-if="project.mode === 'git'" label="Branch"><el-input v-model="settingsForm.git_branch" /></el-form-item>
              <el-form-item label="Build Script"><el-input v-model="settingsForm.build_script" type="textarea" :rows="3" /></el-form-item>
              <el-form-item label="Run Command"><el-input v-model="settingsForm.run_command" /></el-form-item>
              <el-form-item label="Port"><el-input-number v-model="settingsForm.port" /></el-form-item>
              <el-form-item label="Env Vars"><el-input v-model="settingsForm.env_vars" type="textarea" :rows="2" /></el-form-item>
              <el-form-item>
                <el-button type="primary" @click="saveSettings">Save</el-button>
                <el-button @click="editingSettings = false">Cancel</el-button>
              </el-form-item>
            </el-form>
            <el-descriptions v-else :column="1" border>
              <el-descriptions-item label="Name">{{ project.name }}</el-descriptions-item>
              <el-descriptions-item label="Description">{{ project.description || '—' }}</el-descriptions-item>
              <el-descriptions-item label="Mode">{{ project.mode }}</el-descriptions-item>
              <el-descriptions-item v-if="project.mode === 'git'" label="Git URL">{{ project.git_url || '—' }}</el-descriptions-item>
              <el-descriptions-item label="Build Script">{{ project.build_script || 'go build -o app .' }}</el-descriptions-item>
              <el-descriptions-item label="Run Command">{{ project.run_command || './app' }}</el-descriptions-item>
              <el-descriptions-item label="Port">{{ project.port || '—' }}</el-descriptions-item>
            </el-descriptions>
          </el-card>
        </el-tab-pane>

        <!-- Deploy -->
        <el-tab-pane label="Deploy" name="deploy">
          <el-card class="deploy-config-card" shadow="never">
            <template #header>
              <div class="card-header-row">
                <span class="card-header-title">Deploy Configuration</span>
                <div class="header-actions">
                  <el-button v-if="!editingDeploy && deployConfig" type="primary" plain size="small" round @click="editingDeploy = true; deployForm = { ...deployConfig, ssh_key: '', ssh_password: '' }">Edit</el-button>
                  <el-button v-if="!editingDeploy && !deployConfig" type="primary" size="small" round @click="editingDeploy = true">Add Config</el-button>
                </div>
              </div>
            </template>

            <el-form v-if="editingDeploy" :model="deployForm" label-position="top" class="deploy-form">
              <div class="form-section">
                <h4 class="section-subtitle">SSH Connection</h4>
                <div class="form-row three-col">
                  <el-form-item label="Host" required><el-input v-model="deployForm.host" placeholder="192.168.1.100" /></el-form-item>
                  <el-form-item label="Port"><el-input-number v-model="deployForm.port" :min="1" :max="65535" style="width:100%" /></el-form-item>
                  <el-form-item label="Username" required><el-input v-model="deployForm.username" placeholder="root" /></el-form-item>
                </div>
                <el-form-item label="Auth Method">
                  <el-radio-group v-model="deployForm.auth_method">
                    <el-radio value="key">SSH Key</el-radio>
                    <el-radio value="password">Password</el-radio>
                  </el-radio-group>
                </el-form-item>
                <el-form-item v-if="deployForm.auth_method === 'key'" label="SSH Private Key">
                  <el-input v-model="deployForm.ssh_key" type="textarea" :rows="4" placeholder="-----BEGIN OPENSSH PRIVATE KEY-----&#10;...&#10;-----END OPENSSH PRIVATE KEY-----" />
                </el-form-item>
                <el-form-item v-if="deployForm.auth_method === 'password'" label="SSH Password">
                  <el-input v-model="deployForm.ssh_password" type="password" placeholder="SSH password" show-password />
                </el-form-item>
              </div>

              <div class="form-section">
                <h4 class="section-subtitle">Deployment</h4>
                <el-form-item label="Deploy Directory" required><el-input v-model="deployForm.deploy_dir" placeholder="/opt/myapp" /></el-form-item>
                <el-form-item label="File Mappings">
                  <el-input v-model="deployForm.file_mappings" type="textarea" :rows="3" placeholder='[{"local":"app","remote":"/opt/myapp/app"}]' />
                </el-form-item>
                <div class="form-row two-col">
                  <el-form-item label="Pre-deploy Command"><el-input v-model="deployForm.pre_deploy_command" placeholder="systemctl stop myapp" /></el-form-item>
                  <el-form-item label="Post-deploy Command"><el-input v-model="deployForm.post_deploy_command" placeholder="systemctl start myapp" /></el-form-item>
                </div>
              </div>

              <div class="form-section">
                <h4 class="section-subtitle">Health Check</h4>
                <div class="form-row two-col">
                  <el-form-item label="Health Check URL"><el-input v-model="deployForm.health_check_url" placeholder="http://192.168.1.100:8080/health" /></el-form-item>
                  <el-form-item label="Timeout (seconds)"><el-input-number v-model="deployForm.health_check_timeout" :min="5" :max="120" style="width:100%" /></el-form-item>
                </div>
              </div>

              <div class="form-section">
                <h4 class="section-subtitle">Automation</h4>
                <el-form-item label="Auto-deploy after successful build">
                  <el-switch v-model="deployForm.auto_deploy" active-text="On" inactive-text="Off" />
                </el-form-item>
              </div>

              <div class="form-actions">
                <el-button @click="editingDeploy = false">Cancel</el-button>
                <el-button v-if="deployConfig" type="danger" plain @click="removeDeployConfig">Remove Config</el-button>
                <el-button type="primary" @click="saveDeployConfig">Save Configuration</el-button>
              </div>
            </el-form>

            <el-descriptions v-else-if="deployConfig" :column="1" border>
              <el-descriptions-item label="SSH">{{ deployConfig.username }}@{{ deployConfig.host }}:{{ deployConfig.port }}</el-descriptions-item>
              <el-descriptions-item label="Auth">{{ deployConfig.auth_method === 'key' ? 'SSH Key' : 'Password' }}</el-descriptions-item>
              <el-descriptions-item label="Deploy Directory">{{ deployConfig.deploy_dir }}</el-descriptions-item>
              <el-descriptions-item label="Pre-deploy">{{ deployConfig.pre_deploy_command || '—' }}</el-descriptions-item>
              <el-descriptions-item label="Post-deploy">{{ deployConfig.post_deploy_command || '—' }}</el-descriptions-item>
              <el-descriptions-item label="Health Check">{{ deployConfig.health_check_url || '—' }}</el-descriptions-item>
              <el-descriptions-item label="Auto-deploy">{{ deployConfig.auto_deploy ? 'Enabled' : 'Disabled' }}</el-descriptions-item>
            </el-descriptions>

            <el-empty v-else description="No deploy configuration yet. Click 'Add Config' to set up SSH deployment." :image-size="80" />
          </el-card>

          <el-card shadow="never" class="deploy-history-card">
            <template #header><span class="card-header-title">Deploy History</span></template>
            <el-table :data="deployRecords" stripe class="history-table">
              <el-table-column prop="id" label="#" width="60" align="center" />
              <el-table-column label="Status" width="110">
                <template #default="{ row }">
                  <el-tag :type="deployStatusTag(row.status)" size="small" effect="dark" round>{{ row.status }}</el-tag>
                </template>
              </el-table-column>
              <el-table-column label="Started" width="180">
                <template #default="{ row }">{{ new Date(row.started_at).toLocaleString() }}</template>
              </el-table-column>
              <el-table-column label="Duration">
                <template #default="{ row }">
                  <span v-if="row.finished_at">{{ Math.round((new Date(row.finished_at) - new Date(row.started_at)) / 1000) }}s</span>
                  <span v-else class="text-muted">—</span>
                </template>
              </el-table-column>
              <el-table-column label="Build #" width="90" align="center">
                <template #default="{ row }">{{ row.build_record_id || '—' }}</template>
              </el-table-column>
              <el-table-column label="Log" width="100" align="center">
                <template #default="{ row }">
                  <el-button size="small" text type="primary" @click="viewDeployLog(row.id)">View</el-button>
                </template>
              </el-table-column>
            </el-table>
            <el-empty v-if="deployRecords.length === 0" description="No deployments yet" :image-size="80" />
          </el-card>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>

<style scoped>
.detail-page { max-width: 1100px; }
.page-back { margin-bottom: 16px; }
.back-title { font-size: 20px; font-weight: 700; color: #1a1d2e; }

/* ════ Action Bar ════ */
.action-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  padding: 18px 22px;
  background: #fff;
  border-radius: 14px;
  border: 1px solid #ebeef2;
  margin-bottom: 20px;
  box-shadow: 0 1px 3px #00000004;
}
.action-bar-left  { display: flex; align-items: center; gap: 12px; }
.action-bar-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 14px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.badge-dot { width: 7px; height: 7px; border-radius: 50%; }
.badge-running  { background: #eaf7e2; color: #3d8c1e; }
.badge-running .badge-dot  { background: #67c23a; }
.badge-stopped  { background: #f0f1f3; color: #6a6e78; }
.badge-stopped .badge-dot  { background: #909399; }
.badge-building { background: #fef5e7; color: #b07816; }
.badge-building .badge-dot { background: #e6a23c; animation: pulse 1.2s ease-in-out infinite; }
.badge-error    { background: #fef0f0; color: #c03639; }
.badge-error .badge-dot    { background: #f56c6c; }

@keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }

.mode-badge {
  padding: 4px 12px;
  border-radius: 14px;
  font-size: 12px;
  font-weight: 500;
  background: #e8ecf1;
  color: #606470;
}

.btn-group .el-button { padding: 8px 16px; }
.btn-icon { width: 15px; height: 15px; margin-right: 4px; vertical-align: -2px; }
.btn-deploy {
  border-color: #409eff;
  color: #409eff;
  font-weight: 600;
}
.btn-deploy:hover { background: #409eff10; }

/* ════ Tabs ════ */
.main-tabs :deep(.el-tabs__header) { margin-bottom: 18px; }
.main-tabs :deep(.el-tabs__item) {
  font-size: 14px;
  font-weight: 500;
  padding: 0 20px;
}

/* ════ Overview ════ */
.overview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
  margin-bottom: 16px;
}
.ov-card { border-radius: 12px; border: 1px solid #ebeef2; }
.upload-card { margin-top: 0; border-radius: 12px; border: 1px solid #ebeef2; }
.upload-area { padding: 10px 0; text-align: center; color: #909399; }
.upload-icon { width: 52px; height: 52px; color: #c0c4cc; margin-bottom: 8px; }

/* ════ Cards ════ */
.card-header-row { display: flex; justify-content: space-between; align-items: center; }
.card-header-title { font-size: 15px; font-weight: 700; color: #1a1d2e; }
.header-actions { display: flex; gap: 8px; }

/* ════ Log Console ════ */
.log-console {
  background: #161821;
  color: #c8d1e0;
  font-family: 'JetBrains Mono', 'Cascadia Code', 'Consolas', monospace;
  font-size: 13px;
  padding: 18px 20px;
  border-radius: 12px;
  min-height: 480px;
  max-height: 560px;
  overflow-y: auto;
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-all;
}
.log-console::-webkit-scrollbar { width: 6px; }
.log-console::-webkit-scrollbar-track { background: transparent; }
.log-console::-webkit-scrollbar-thumb { background: #3a3d4a; border-radius: 3px; }

.log-empty { color: #5a5e6e; padding: 20px 0; text-align: center; }
.log-prompt::before { content: '▎'; animation: blink 1s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }

.log-deploy  { color: #7dcfff; }
.log-error   { color: #f7768e; font-weight: 500; }
.log-success { color: #9ece6a; }

/* ════ Tables ════ */
.history-table { border-radius: 8px; overflow: hidden; }
.commit-hash {
  font-family: 'JetBrains Mono', 'Consolas', monospace;
  font-size: 12px;
  background: #f0f1f3;
  padding: 2px 8px;
  border-radius: 4px;
  color: #409eff;
}
.text-muted { color: #c0c4cc; }

/* ════ Deploy config ════ */
.deploy-config-card { border-radius: 12px; border: 1px solid #ebeef2; margin-bottom: 16px; }
.deploy-history-card { border-radius: 12px; border: 1px solid #ebeef2; }
.deploy-form .form-section {
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid #f5f5f5;
}
.deploy-form .form-section:last-of-type { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }

.section-subtitle {
  font-size: 13px;
  font-weight: 700;
  color: #409eff;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 2px solid #409eff15;
}

.form-row { display: flex; gap: 16px; }
.form-row > * { flex: 1; }

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding-top: 12px;
}
</style>
