<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import {
  ArrowLeft,
  Bot,
  ChevronRight,
  FileText,
  Info,
  LoaderCircle,
  ShieldCheck,
  Sparkles,
} from '@lucide/vue'
import {
  useAgentCreateOptionsQuery,
  useCreateAgentProposalMutation,
  type CreateAgentProposalRequest,
} from '../api/agentProposals'
import { useAuthStore } from '../stores/auth'
import AsyncStatePanel from '../components/mission-control/AsyncStatePanel.vue'

const router = useRouter()
const auth = useAuthStore()
const isOwner = computed(() => auth.isOwner)
const optionsQuery = useAgentCreateOptionsQuery(isOwner)
const createMutation = useCreateAgentProposalMutation()

const form = reactive({
  name: '',
  role: '',
  description: '',
  model: '',
})
const files = reactive<Record<string, string>>({})
const selectedFile = ref('')
const selectedFileContent = computed({
  get: () => selectedFile.value ? files[selectedFile.value] ?? '' : '',
  set: value => {
    if (selectedFile.value) files[selectedFile.value] = value
  },
})
const formError = ref('')
const lastRequestSignature = ref('')
const lastClientRequestId = ref('')

const options = computed(() => optionsQuery.data.value ?? null)
const modelOptions = computed(() => options.value?.models.filter(model => model.available) ?? [])
const canSubmit = computed(() => Boolean(options.value?.canSubmitProposal))
const configuredFileCount = computed(() => Object.values(files).filter(value => value.trim()).length)

watch(
  () => options.value?.standardFiles,
  standardFiles => {
    if (!standardFiles?.length) return
    for (const fileName of standardFiles) {
      if (!(fileName in files)) files[fileName] = ''
    }
    if (!selectedFile.value || !standardFiles.includes(selectedFile.value)) {
      selectedFile.value = standardFiles[0]
    }
  },
  { immediate: true },
)

function buildRequest(): CreateAgentProposalRequest {
  const configuredFiles = Object.fromEntries(
    Object.entries(files).filter(([, content]) => content.trim().length > 0),
  )
  return {
    name: form.name.trim(),
    role: form.role.trim() || null,
    description: form.description.trim() || null,
    model: form.model || null,
    files: Object.keys(configuredFiles).length ? configuredFiles : null,
  }
}

async function submitProposal() {
  formError.value = ''
  if (!form.name.trim()) {
    formError.value = 'Bitte gib dem Agenten einen Namen.'
    return
  }
  if (!canSubmit.value) {
    formError.value = options.value?.reason || 'Agent-Vorschläge sind derzeit nicht verfügbar.'
    return
  }

  const request = buildRequest()
  const signature = JSON.stringify(request)
  if (signature !== lastRequestSignature.value) {
    lastRequestSignature.value = signature
    lastClientRequestId.value = crypto.randomUUID()
  }

  try {
    const operation = await createMutation.mutateAsync({
      ...request,
      clientRequestId: lastClientRequestId.value,
    })
    if (!operation.ok || !operation.proposal) {
      formError.value = operation.recovery || operation.message
      return
    }
    await router.push({
      name: 'AgentProposalDetail',
      params: { proposalId: operation.proposal.id },
    })
  } catch (error) {
    formError.value = error instanceof Error ? error.message : 'Agent-Vorschlag konnte nicht erstellt werden.'
  }
}
</script>

<template>
  <div class="agent-create-page nexus-page nexus-page--reading">
    <header class="nexus-page-header">
      <div class="nexus-page-header__identity">
        <RouterLink class="back-link" to="/agents" aria-label="Zurück zu Agents">
          <ArrowLeft :size="17" aria-hidden="true" />
        </RouterLink>
        <div class="nexus-page-header__icon">
          <Sparkles :size="21" aria-hidden="true" />
        </div>
        <div>
          <h1>Agent vorschlagen</h1>
          <p class="page-subtitle">Konfiguration vorbereiten und anschließend bewusst freigeben.</p>
        </div>
      </div>
      <span class="nexus-status nexus-status--warning">
        <ShieldCheck :size="14" aria-hidden="true" />
        Owner-Approval
      </span>
    </header>

    <div v-if="!isOwner" class="nexus-state nexus-state--error" role="alert">
      <strong>Owner-Berechtigung erforderlich</strong>
      <span>Agent-Vorschläge enthalten OpenClaw-Konfiguration und sind deshalb ausschließlich für Owner sichtbar.</span>
      <RouterLink class="nexus-button" to="/agents">Zur Agentenübersicht</RouterLink>
    </div>
    <AsyncStatePanel
      v-else-if="optionsQuery.isPending.value"
      state="loading"
      title="OpenClaw-Optionen werden geprüft"
    />
    <AsyncStatePanel
      v-else-if="optionsQuery.isError.value"
      state="error"
      title="Agent-Optionen nicht verfügbar"
      :problem="optionsQuery.error.value"
      action-label="Erneut prüfen"
      @action="optionsQuery.refetch()"
    />

    <template v-else-if="options">
      <section
        class="availability-panel nexus-panel"
        :class="{ 'availability-panel--blocked': !options.canSubmitProposal }"
        :aria-label="options.canSubmitProposal ? 'Proposal-Erstellung verfügbar' : 'Proposal-Erstellung blockiert'"
      >
        <Info :size="18" aria-hidden="true" />
        <div>
          <strong>
            {{ options.canSubmitProposal ? 'Vorschlag kann erstellt werden' : 'Erstellung derzeit blockiert' }}
          </strong>
          <p>
            <template v-if="options.canSubmitProposal && options.canProvision">
              Nach deiner Freigabe kann Nexus den Agenten über OpenClaw provisionieren.
            </template>
            <template v-else-if="options.canSubmitProposal">
              Der Vorschlag kann gespeichert werden; die Provisionierung bleibt blockiert, bis die Runtime-Bedingungen erfüllt sind.
            </template>
            <template v-else>
              {{ options.reason || 'Die erforderlichen Management- oder Runtime-Bedingungen fehlen.' }}
            </template>
          </p>
        </div>
        <span class="nexus-mono">{{ options.state }}</span>
      </section>

      <form class="proposal-form" novalidate @submit.prevent="submitProposal">
        <section class="form-panel nexus-panel">
          <div class="section-heading">
            <span class="section-icon"><Bot :size="18" aria-hidden="true" /></span>
            <div>
              <h2>Identität und Auftrag</h2>
              <p>Diese Angaben werden im Review vollständig angezeigt.</p>
            </div>
          </div>

          <div class="field-grid">
            <label class="field">
              <span>Name <em>Pflichtfeld</em></span>
              <input
                v-model="form.name"
                class="nexus-field"
                name="agent-name"
                autocomplete="off"
                maxlength="80"
                required
                placeholder="z. B. Release Coordinator"
              />
            </label>
            <label class="field">
              <span>Rolle</span>
              <input
                v-model="form.role"
                class="nexus-field"
                name="agent-role"
                autocomplete="off"
                maxlength="120"
                placeholder="z. B. Delivery Operations"
              />
            </label>
          </div>

          <label class="field">
            <span>Zweck und Verantwortungsbereich</span>
            <textarea
              v-model="form.description"
              class="nexus-field"
              name="agent-description"
              rows="5"
              maxlength="1600"
              placeholder="Welche Ergebnisse soll der Agent liefern, und wo liegen seine Grenzen?"
            ></textarea>
          </label>

          <label class="field">
            <span>OpenClaw-Modell</span>
            <select v-model="form.model" class="nexus-field" name="agent-model">
              <option value="">OpenClaw-Standard verwenden</option>
              <option v-for="model in modelOptions" :key="model.id" :value="model.id">
                {{ model.name }} · {{ model.provider }}
              </option>
            </select>
          </label>
        </section>

        <section v-if="options.standardFiles.length" class="form-panel nexus-panel">
          <div class="section-heading">
            <span class="section-icon"><FileText :size="18" aria-hidden="true" /></span>
            <div>
              <h2>Initiale Agent-Dateien</h2>
              <p>Optional. Nur von OpenClaw erlaubte Standarddateien werden übertragen.</p>
            </div>
            <span class="configured-count nexus-badge">{{ configuredFileCount }} konfiguriert</span>
          </div>

          <div class="file-editor">
            <label class="field file-picker">
              <span>Datei</span>
              <select v-model="selectedFile" class="nexus-field">
                <option v-for="fileName in options.standardFiles" :key="fileName" :value="fileName">
                  {{ fileName }}
                </option>
              </select>
            </label>
            <label class="field">
              <span>{{ selectedFile }} Inhalt</span>
              <textarea
                v-model="selectedFileContent"
                class="nexus-field file-content"
                rows="12"
                maxlength="30000"
                :placeholder="`${selectedFile} leer lassen, um OpenClaws Standard zu verwenden.`"
              ></textarea>
            </label>
          </div>
        </section>

        <section class="review-panel nexus-panel" aria-labelledby="proposal-review-title">
          <div>
            <span class="review-eyebrow">Review</span>
            <h2 id="proposal-review-title">{{ form.name.trim() || 'Noch kein Name' }}</h2>
            <p>{{ form.role.trim() || 'Keine Rolle angegeben' }}</p>
          </div>
          <dl>
            <div><dt>Modell</dt><dd>{{ form.model || 'OpenClaw-Standard' }}</dd></div>
            <div><dt>Dateien</dt><dd>{{ configuredFileCount }}</dd></div>
            <div><dt>Nächster Schritt</dt><dd>Owner-Freigabe</dd></div>
          </dl>
        </section>

        <div v-if="formError" class="nexus-state nexus-state--error" role="alert">
          {{ formError }}
        </div>

        <footer class="form-actions">
          <RouterLink class="nexus-button" to="/agents">Abbrechen</RouterLink>
          <button
            type="submit"
            class="nexus-button nexus-button--primary"
            :disabled="createMutation.isPending.value || !canSubmit"
          >
            <LoaderCircle v-if="createMutation.isPending.value" class="spin" :size="16" aria-hidden="true" />
            <ChevronRight v-else :size="16" aria-hidden="true" />
            {{ createMutation.isPending.value ? 'Wird angelegt…' : 'Vorschlag anlegen' }}
          </button>
        </footer>
      </form>
    </template>
  </div>
</template>

<style scoped>
.agent-create-page { padding-bottom: 40px; }
.back-link { width: 42px; height: 42px; padding: 0; flex: 0 0 42px; text-decoration: none; }
.availability-panel { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; gap: 12px; border-color: var(--status-work-line); }
.availability-panel > svg { color: var(--st-work); margin-top: 2px; }
.availability-panel--blocked { border-color: var(--status-block-line); background: linear-gradient(135deg, var(--status-block-bg), var(--glass)); }
.availability-panel--blocked > svg { color: var(--st-block); }
.availability-panel strong { color: var(--tx); }
.availability-panel p { margin: 4px 0 0; color: var(--tx-2); line-height: 1.55; }
.availability-panel > .nexus-mono { color: var(--tx-3); }
.proposal-form { display: grid; gap: 16px; }
.form-panel { display: grid; gap: 18px; }
.section-heading { display: flex; align-items: center; gap: 12px; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.section-heading h2, .review-panel h2 { margin: 0; font-size: 16px; }
.section-heading p { margin: 3px 0 0; color: var(--tx-2); line-height: 1.45; }
.section-icon { width: 38px; height: 38px; display: grid; place-items: center; flex: 0 0 auto; border: 1px solid var(--line-2); border-radius: var(--r-sm); background: var(--grad-soft); color: var(--a-mid); }
.configured-count { margin-left: auto; }
.field-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.field { display: grid; gap: 7px; color: var(--tx-2); font-weight: 650; }
.field > span { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.field em { color: var(--a-mid); font-family: var(--font-mono-v2); font-size: 10px; font-style: normal; text-transform: uppercase; }
.nexus-field { width: 100%; padding: 10px 12px; }
textarea.nexus-field { line-height: 1.55; resize: vertical; }
.file-editor { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 14px; align-items: start; }
.file-content { min-height: 250px; font-family: var(--font-mono-v2); font-size: 12px; }
.review-panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, .7fr); gap: 20px; align-items: center; }
.review-eyebrow { display: block; margin-bottom: 6px; color: var(--a-mid); font-family: var(--font-mono-v2); font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.review-panel p { margin: 5px 0 0; color: var(--tx-2); }
.review-panel dl { display: grid; gap: 8px; margin: 0; }
.review-panel dl div { display: flex; justify-content: space-between; gap: 18px; padding-bottom: 8px; border-bottom: 1px solid var(--line); }
.review-panel dl div:last-child { padding-bottom: 0; border-bottom: 0; }
.review-panel dt { color: var(--tx-3); }
.review-panel dd { margin: 0; color: var(--tx); font-family: var(--font-mono-v2); text-align: right; overflow-wrap: anywhere; }
.form-actions { display: flex; justify-content: flex-end; gap: 10px; }
.form-actions a { text-decoration: none; }
.spin { animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (max-width: 720px) {
  .field-grid, .file-editor, .review-panel { grid-template-columns: minmax(0, 1fr); }
  .availability-panel { grid-template-columns: auto minmax(0, 1fr); }
  .availability-panel > .nexus-mono { grid-column: 2; }
  .configured-count { margin-left: 0; }
}
</style>
