<template>
  <div class="backup-card card-glow">
    <div class="card-header">
      <h2 class="card-title">Run Script</h2>
      <span class="font-mono text-[10px] text-m-muted tracking-widest uppercase">Scripts</span>
    </div>

    <div v-if="loading" class="status-box">
      Chargement des scripts...
    </div>

    <div v-else class="backup-list">
      <button
        v-for="item in scripts"
        :key="item.key"
        type="button"
        class="backup-btn"
        :class="{ 'backup-btn-active': active === item.key }"
        :disabled="runningKey !== null"
        @click="runScript(item.key)"
      >
        <div class="flex items-center gap-2.5">
          <IconifyIcon :icon="item.icon" class="text-base text-m-accent" />
          <span class="font-display text-sm font-semibold uppercase tracking-wide">
            {{ item.label }}
          </span>
        </div>
        <IconifyIcon
          :icon="runningKey === item.key ? 'mdi:loading' : 'mdi:play'"
          class="text-lg text-m-muted transition-transform duration-200"
          :class="{
            'translate-x-0.5 !text-m-accent': active === item.key,
            'animate-spin': runningKey === item.key
          }"
        />
      </button>
    </div>

    <div v-if="message" class="status-box" :class="statusClass">
      <p class="status-title">{{ message }}</p>
      <pre v-if="output" class="status-output">{{ output }}</pre>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from "vue"
import { Icon as IconifyIcon } from "@iconify/vue"

type BackupScript = {
  key: string
  label: string
  icon: string
}

type BackupScriptListResponse = {
  scripts: BackupScript[]
}

type BackupScriptRunResponse = {
  ok: boolean
  key: string
  label: string
  output: string
}

const active = ref<string | null>(null)
const loading = ref(true)
const runningKey = ref<string | null>(null)
const scripts = ref<BackupScript[]>([])
const output = ref("")
const message = ref("")
const isError = ref(false)

const statusClass = computed(() => (isError.value ? "status-error" : "status-success"))

const loadScripts = async () => {
  loading.value = true
  try {
    const data = await $fetch<BackupScriptListResponse>("/api/backup-script")
    scripts.value = data.scripts
  } catch (error) {
    isError.value = true
    message.value = `Erreur chargement scripts: ${error instanceof Error ? error.message : String(error)}`
  } finally {
    loading.value = false
  }
}

const runScript = async (key: string) => {
  active.value = key
  runningKey.value = key
  output.value = ""
  message.value = ""
  isError.value = false

  try {
    const data = await $fetch<BackupScriptRunResponse>("/api/backup-script", {
      method: "POST",
      body: { key }
    })
    message.value = `${data.label} execute`
    output.value = data.output
  } catch (error: any) {
    isError.value = true
    message.value = error?.data?.statusMessage || "Erreur execution script"
    output.value = ""
  } finally {
    runningKey.value = null
  }
}

onMounted(loadScripts)
</script>

<style scoped>
.backup-card {
  background: rgb(var(--m-secondary));
  border-radius: 12px;
  padding: 1.25rem;
  transition: background-color 0.4s ease;
}

.card-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.75rem;
}

.card-title {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  color: rgb(var(--m-text));
}

.backup-list {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.backup-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.625rem 0.875rem;
  border-radius: 8px;
  background: rgb(var(--m-tertiary));
  border: 1px solid transparent;
  cursor: pointer;
  transition: all 0.2s ease;
  color: rgb(var(--m-text));
}

.backup-btn:disabled {
  cursor: wait;
  opacity: 0.7;
}

.backup-btn:hover {
  border-color: rgb(var(--m-accent) / 0.15);
  background: rgb(var(--m-accent) / 0.06);
}

.backup-btn-active {
  border-color: rgb(var(--m-accent) / 0.25);
  background: rgb(var(--m-accent) / 0.08);
  box-shadow: 0 0 12px -4px rgb(var(--m-accent) / 0.15);
}

.status-box {
  margin-top: 0.75rem;
  border-radius: 8px;
  padding: 0.875rem;
  background: rgb(var(--m-tertiary));
  color: rgb(var(--m-text));
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

.status-success {
  border: 1px solid rgb(var(--m-accent) / 0.18);
}

.status-error {
  border: 1px solid rgb(255 99 99 / 0.3);
}

.status-title {
  margin: 0;
}

.status-output {
  margin: 0.75rem 0 0;
  white-space: pre-wrap;
  word-break: break-word;
  color: rgb(var(--m-muted));
}
</style>
