<template>
  <div
    class="backup-card card-glow"
    :class="{
      'card-glow-success': message && !isError,
      'card-glow-error': message && isError
    }"
  >
    <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"
      role="status"
      aria-live="polite"
      aria-busy="true"
    >
      Chargement des scripts...
    </div>

    <div
      v-else-if="scripts.length"
      class="backup-list"
      :aria-busy="runningKey !== null"
    >
      <button
        v-for="item in scripts"
        :key="item.key"
        type="button"
        class="backup-btn"
        :class="{ 'backup-btn-active': active === item.key }"
        :disabled="runningKey !== null"
        :aria-pressed="active === item.key"
        :aria-label="`Executer ${item.label}`"
        @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-else
      class="status-box status-empty"
      role="status"
      aria-live="polite"
    >
      Aucun script disponible.
    </div>

    <div
      v-if="message"
      class="status-box"
      :class="statusClass"
      role="status"
      :aria-live="isError ? 'assertive' : 'polite'"
    >
      <p class="status-title">{{ message }}</p>
    </div>

  </div>
</template>

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

type BackupScript = {
  key: string
  label: string
  icon: string
  downloadFolders?: string[]
}

type BackupScriptListResponse = {
  scripts: BackupScript[]
}

type BackupScriptRunResponse = {
  ok: boolean
  key: string
  label: string
  downloadFolders?: string[]
  output: string
}

type ScriptResult = {
  key: string | null
  label: string
  output: string
  isError: boolean
  downloadFolders: string[]
}

const emit = defineEmits<{
  result: [payload: ScriptResult]
}>()

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

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

const loadScripts = async () => {
  loading.value = true
  message.value = ""
  output.value = ""
  isError.value = false
  emit("result", {
    key: null,
    label: "",
    output: "",
    isError: false,
    downloadFolders: []
  })
  try {
    const data = await $fetch<BackupScriptListResponse>("/api/backup-script", {
      headers: apiAuthHeader
    })
    scripts.value = data.scripts
  } catch (error) {
    scripts.value = []
    isError.value = true
    message.value = "Erreur lors de l'opération"
    emit("result", {
      key: null,
      label: "",
      output: "",
      isError: true,
      downloadFolders: []
    })
  } 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 },
      headers: apiAuthHeader
    })
    message.value = `${data.label} execute avec succes`
    output.value = data.output || "Aucune sortie retournee."
    emit("result", {
      key: data.key,
      label: data.label,
      output: output.value,
      isError: false,
      downloadFolders: data.downloadFolders || []
    })
  } catch (error: any) {
    isError.value = true
    message.value = error?.data?.statusMessage || "Erreur lors de l'opération"
    output.value = ""
    emit("result", {
      key,
      label: scripts.value.find((item) => item.key === key)?.label || key,
      output: "",
      isError: true,
      downloadFolders: []
    })
  } 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:focus-visible {
  outline: 2px solid rgb(var(--m-accent) / 0.7);
  outline-offset: 2px;
}

.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-empty {
  color: rgb(var(--m-muted));
}

.status-title {
  margin: 0;
  line-height: 1.5;
}
</style>
