<script setup lang="ts">
import { Boxes, CalendarClock, CircleAlert, Loader2, Plus, RefreshCw } from '@lucide/vue'
import { computed, ref } from 'vue'
import { RouterLink } from 'vue-router'
import { useProjects } from '../api/projects'
import AsyncStatePanel from '../components/mission-control/AsyncStatePanel.vue'

const projects = useProjects()
const name = ref('')
const description = ref('')
const formError = ref('')
const items = computed(() => projects.query.data.value ?? [])

function formatUpdated(value: string) {
  const date = new Date(value)
  return Number.isNaN(date.getTime())
    ? 'Zeitpunkt unbekannt'
    : date.toLocaleString('de-DE', {
        day: '2-digit',
        month: 'short',
        hour: '2-digit',
        minute: '2-digit',
      })
}

function statusTone(status: string) {
  const normalized = status.toLowerCase()
  if (normalized === 'online') return 'success'
  if (normalized === 'degraded') return 'warning'
  if (normalized === 'offline') return 'danger'
  return 'neutral'
}

async function submit() {
  const normalizedName = name.value.trim()
  if (!normalizedName || projects.creating.value) return
  formError.value = ''
  try {
    await projects.createProject({
      name: normalizedName,
      description: description.value.trim() || null,
    })
    name.value = ''
    description.value = ''
  } catch (error) {
    formError.value = error instanceof Error
      ? error.message
      : 'Projekt konnte nicht erstellt werden'
  }
}
</script>

<template>
  <div class="projects-page nexus-page">
    <header class="nexus-page-header">
      <div class="nexus-page-header__identity">
        <div class="nexus-page-header__icon"><Boxes :size="20" aria-hidden="true" /></div>
        <div>
          <span class="eyebrow">MISSION SCOPES</span>
          <h1>Projects</h1>
          <p class="page-subtitle">Tasks, agents, runs and incidents around one operational outcome.</p>
        </div>
      </div>
      <button
        type="button"
        class="nexus-button"
        :disabled="projects.query.isFetching.value"
        @click="projects.query.refetch()"
      >
        <Loader2 v-if="projects.query.isFetching.value" :size="15" class="spin" aria-hidden="true" />
        <RefreshCw v-else :size="15" aria-hidden="true" />
        Aktualisieren
      </button>
    </header>

    <form class="project-create nexus-panel" aria-labelledby="project-create-title" @submit.prevent="submit">
      <div>
        <span class="eyebrow">NEW SCOPE</span>
        <h2 id="project-create-title">Projekt anlegen</h2>
        <p>Ein klarer Scope verbindet Aufgaben und spätere OpenClaw-Runs.</p>
      </div>
      <label>
        <span>Name</span>
        <input v-model="name" required maxlength="160" autocomplete="off" placeholder="z. B. Release Automation" />
      </label>
      <label>
        <span>Beschreibung</span>
        <input v-model="description" maxlength="1000" autocomplete="off" placeholder="Gewünschtes Ergebnis und Grenze" />
      </label>
      <button type="submit" class="nexus-button nexus-button--primary" :disabled="!name.trim() || projects.creating.value">
        <Loader2 v-if="projects.creating.value" :size="15" class="spin" aria-hidden="true" />
        <Plus v-else :size="15" aria-hidden="true" />
        Projekt anlegen
      </button>
      <p v-if="formError" class="form-error" role="alert">{{ formError }}</p>
    </form>

    <AsyncStatePanel
      v-if="projects.query.isLoading.value"
      state="loading"
      title="Projekte werden geladen"
    />
    <AsyncStatePanel
      v-else-if="projects.query.isError.value"
      state="error"
      title="Projektliste nicht verfügbar"
      :problem="projects.query.error.value"
      @action="projects.query.refetch()"
    />
    <AsyncStatePanel
      v-else-if="!items.length"
      state="empty"
      title="Noch keine Projekte"
      message="Lege den ersten Mission-Scope über das Formular an."
    />
    <section v-else class="project-grid" aria-label="Projekte">
      <RouterLink
        v-for="project in items"
        :key="project.id"
        class="project-card nexus-card nexus-card--interactive"
        :to="{ name: 'ProjectDetail', params: { id: project.id } }"
      >
        <header>
          <span class="project-mark" aria-hidden="true">{{ project.name.slice(0, 1).toUpperCase() }}</span>
          <span class="status-badge" :data-tone="statusTone(project.status)">{{ project.status }}</span>
        </header>
        <div>
          <h2>{{ project.name }}</h2>
          <p>{{ project.description || 'Noch keine Beschreibung hinterlegt.' }}</p>
        </div>
        <div class="progress-row" :aria-label="`${project.progress} Prozent Fortschritt`">
          <span><i :style="{ width: `${Math.max(0, Math.min(100, Number(project.progress)))}%` }"></i></span>
          <strong>{{ project.progress }}%</strong>
        </div>
        <footer>
          <CalendarClock :size="13" aria-hidden="true" />
          <span>{{ formatUpdated(project.updatedAt) }}</span>
        </footer>
      </RouterLink>
    </section>
  </div>
</template>

<style scoped>
.projects-page { max-width: 1180px; margin: 0 auto; }
.project-create { display: grid; grid-template-columns: minmax(220px, 1.1fr) minmax(180px, .8fr) minmax(220px, 1fr) auto; align-items: end; gap: 14px; padding: 16px; }
.project-create h2 { margin: 3px 0 4px; font: 700 17px/1.25 var(--font-display); }
.project-create p { margin: 0; color: var(--tx-2); font-size: 12px; }
.project-create label { display: grid; gap: 6px; color: var(--tx-2); font-size: 12px; }
.project-create input { width: 100%; }
.form-error { grid-column: 1 / -1; color: var(--st-block); }
.project-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.project-card { display: grid; min-width: 0; gap: 16px; padding: 17px; color: inherit; text-decoration: none; }
.project-card header, .project-card footer, .progress-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.project-mark { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 11px; border: 1px solid var(--line-2); background: linear-gradient(135deg, color-mix(in srgb, var(--a-mid) 26%, var(--glass)), var(--glass)); color: var(--tx); font: 700 15px/1 var(--font-display); }
.status-badge { border: 1px solid var(--line); border-radius: 999px; padding: 4px 8px; color: var(--tx-2); font: 600 11px/1 var(--font-mono); text-transform: uppercase; }
.status-badge[data-tone="success"] { color: var(--st-done); border-color: color-mix(in srgb, var(--st-done) 38%, var(--line)); }
.status-badge[data-tone="warning"] { color: var(--st-review); border-color: color-mix(in srgb, var(--st-review) 38%, var(--line)); }
.status-badge[data-tone="danger"] { color: var(--st-block); border-color: color-mix(in srgb, var(--st-block) 38%, var(--line)); }
.project-card h2 { margin: 0 0 7px; font: 700 17px/1.25 var(--font-display); }
.project-card p { display: -webkit-box; min-height: 38px; margin: 0; overflow: hidden; color: var(--tx-2); font-size: 12px; line-height: 1.55; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.progress-row > span { flex: 1; height: 6px; overflow: hidden; border-radius: 999px; background: var(--glass-2); }
.progress-row i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--a-blue), var(--a-violet)); }
.progress-row strong { color: var(--tx-2); font: 600 11px/1 var(--font-mono); }
.project-card footer { justify-content: flex-start; color: var(--tx-3); font: 500 11px/1.2 var(--font-mono); }
.spin { animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (max-width: 1024px) {
  .project-create { grid-template-columns: 1fr 1fr; }
  .project-create > div, .project-create .form-error { grid-column: 1 / -1; }
  .project-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .project-create, .project-grid { grid-template-columns: 1fr; }
  .project-create > div, .project-create .form-error { grid-column: auto; }
  .project-create .nexus-button { min-height: 44px; }
}
</style>
