<script setup lang="ts">
import { nextTick, onMounted, ref, watch } from 'vue'
import { RouterLink } from 'vue-router'
import { Bot, ChevronRight, FileText, Link2, Send, Workflow, X } from '@lucide/vue'
import type { ChatMessage } from './types'
import type { MissionControlContext } from '../../../types/mission-control'
import OperationResultCard from '../../mission-control/OperationResultCard.vue'

const props = defineProps<{
  messages: ChatMessage[]
  isThinking: boolean
  error?: string | null
  context: MissionControlContext
}>()

const emit = defineEmits<{
  send: [text: string]
  close: []
}>()

const inputText = ref('')
const dialogEl = ref<HTMLDialogElement | null>(null)
const inputEl = ref<HTMLInputElement | null>(null)
const scrollEl = ref<HTMLElement | null>(null)

function handleSend() {
  const text = inputText.value.trim()
  if (!text) return
  emit('send', text)
  inputText.value = ''
}

function onKeydown(event: KeyboardEvent) {
  if (event.key === 'Enter' && !event.shiftKey) {
    event.preventDefault()
    handleSend()
  }
}

function closeDialog() {
  dialogEl.value?.close()
}

function onBackdropClick(event: MouseEvent) {
  if (event.target === event.currentTarget) closeDialog()
}

watch(
  () => props.messages.length,
  () => {
    nextTick(() => {
      if (scrollEl.value) scrollEl.value.scrollTop = scrollEl.value.scrollHeight
    })
  },
)

onMounted(async () => {
  if (dialogEl.value && !dialogEl.value.open) dialogEl.value.showModal()
  await nextTick()
  inputEl.value?.focus()
})
</script>

<template>
  <dialog
    id="iris-chat-dialog"
    ref="dialogEl"
    class="iris-dialog"
    aria-labelledby="iris-chat-title"
    aria-describedby="iris-chat-description"
    @click="onBackdropClick"
    @cancel.prevent="closeDialog"
    @keydown.esc.prevent.stop="closeDialog"
    @close="emit('close')"
  >
    <section class="iris-panel">
      <header class="iris-head">
        <div class="iris-av" aria-hidden="true"><Bot :size="19" /></div>
        <div class="iris-identity">
          <h2 id="iris-chat-title" class="iris-name">Iris Chat</h2>
          <p id="iris-chat-description" class="iris-sub">
            Chief of Staff · <span class="online">online</span>
          </p>
        </div>
        <button
          class="close-btn"
          type="button"
          aria-label="Iris Chat schließen"
          @click="closeDialog"
        >
          <X :size="18" aria-hidden="true" />
        </button>
      </header>

      <div ref="scrollEl" class="chat-scroll" aria-live="polite">
        <div v-if="error" class="chat-msg-info error">{{ error }}</div>
        <div v-else-if="!messages.length && !isThinking" class="chat-msg-info">
          Noch keine Nachrichten.
        </div>

        <div v-for="(msg, index) in messages" :key="index" class="chat-row">
          <template v-if="msg.sender === 'iris'">
            <div class="bubble iris">{{ msg.text }}</div>
            <div v-if="msg.tool" class="tool">
              <FileText :size="12" aria-hidden="true" />{{ msg.tool }}
            </div>
            <RouterLink
              v-if="msg.runId && !msg.operation"
              class="result-card"
              :to="{ name: 'RunDetail', params: { id: msg.runId } }"
              @click="closeDialog"
            >
              <Workflow :size="15" aria-hidden="true" />
              <span>
                <strong>OpenClaw-Run öffnen</strong>
                <small>{{ msg.runState || 'Status wird synchronisiert' }}</small>
              </span>
              <ChevronRight :size="14" aria-hidden="true" />
            </RouterLink>
            <OperationResultCard
              v-if="msg.operation"
              :result="msg.operation"
              :title="msg.operation.primaryRef?.type === 'agent-proposal'
                ? 'Agent-Vorschlag'
                : 'OpenClaw-Run'"
              @click="closeDialog"
            />
          </template>
          <div v-else class="bubble me">{{ msg.text }}</div>
        </div>

        <div v-if="isThinking" class="chat-row">
          <div class="bubble iris" aria-label="Iris schreibt">
            <span class="caret" aria-hidden="true"></span>
          </div>
        </div>
      </div>

      <form class="chat-in" @submit.prevent="handleSend">
        <div class="context-chip" :title="context.path">
          <Link2 :size="12" aria-hidden="true" />
          <span>{{ context.surface }}</span>
          <code v-if="context.entityId">{{ context.entityId }}</code>
        </div>
        <input
          ref="inputEl"
          v-model="inputText"
          type="text"
          aria-label="Nachricht an Iris"
          placeholder="Nachricht an Iris…"
          @keydown="onKeydown"
        />
        <button
          class="send"
          type="submit"
          aria-label="Nachricht senden"
          :disabled="!inputText.trim()"
        >
          <Send :size="17" aria-hidden="true" />
        </button>
      </form>
    </section>
  </dialog>
</template>

<style scoped>
.iris-dialog {
  width: min(720px, calc(100vw - 32px));
  height: min(720px, calc(100dvh - 48px));
  max-width: none;
  max-height: none;
  margin: auto;
  padding: 0;
  overflow: visible;
  border: 0;
  background: transparent;
  color: var(--tx);
}

.iris-dialog[open] {
  animation: dialog-in .2s cubic-bezier(.2, .8, .3, 1);
}

.iris-dialog::backdrop {
  background: rgba(5, 4, 16, .78);
  backdrop-filter: blur(14px);
}

@keyframes dialog-in {
  from { opacity: 0; transform: translateY(12px) scale(.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.iris-panel {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  border: 1px solid var(--line-3);
  border-radius: var(--r-lg);
  background: linear-gradient(160deg, rgba(22, 18, 50, .98), rgba(10, 8, 28, .98));
  box-shadow:
    0 0 0 1px rgba(124, 108, 255, .12),
    0 32px 80px -16px rgba(0, 0, 0, .82),
    0 0 60px -12px rgba(124, 108, 255, .34);
  backdrop-filter: blur(18px);
}

.iris-head {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 68px;
  padding: 12px 14px 12px 16px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.iris-av {
  width: 40px;
  height: 40px;
  border-radius: 11px;
  background: var(--grad);
  display: grid;
  place-items: center;
  box-shadow: var(--glow-purple);
  flex: 0 0 auto;
}

.iris-av :deep(svg) {
  width: 19px;
  height: 19px;
  color: var(--tx-on-accent);
}

.iris-identity {
  min-width: 0;
}

.iris-name {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.2;
  color: var(--tx);
}

.iris-sub {
  margin: 2px 0 0;
  font-size: 11px;
  color: var(--tx-3);
}

.online {
  color: var(--st-work);
}

.close-btn {
  margin-left: auto;
  width: 40px;
  height: 40px;
  border-radius: var(--r-sm);
  border: 1px solid var(--line-2);
  background: var(--accent-wash);
  color: var(--tx-2);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background .15s, border-color .15s, color .15s;
  flex: 0 0 auto;
}

.close-btn:hover {
  border-color: var(--line-3);
  background: var(--accent-wash-strong);
  color: var(--tx);
}

.chat-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--accent-scroll) transparent;
}

.chat-scroll::-webkit-scrollbar { width: 7px; }
.chat-scroll::-webkit-scrollbar-thumb {
  background: var(--accent-scroll);
  border-radius: 7px;
}
.chat-scroll::-webkit-scrollbar-track { background: transparent; }

.chat-msg-info {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--tx-3);
  font-style: italic;
  text-align: center;
  padding: 24px 0;
}

.chat-msg-info.error {
  color: #fda4b0;
  font-style: normal;
}

.chat-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.bubble {
  max-width: 78%;
  padding: 10px 13px;
  border-radius: 14px;
  font-family: var(--font-body);
  font-size: 13px;
  line-height: 1.5;
}

.bubble.iris {
  background: rgba(124, 108, 255, .12);
  border: 1px solid var(--line-2);
  border-bottom-left-radius: 5px;
  color: var(--tx);
}

.bubble.me {
  background: var(--grad);
  color: var(--tx-on-accent);
  border-bottom-right-radius: 5px;
  margin-left: auto;
  box-shadow: var(--glow-purple);
}

.tool {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-left: 4px;
  font-family: var(--font-mono-v2);
  font-size: 10px;
  color: var(--st-think);
}

.tool :deep(svg) {
  width: 12px;
  height: 12px;
}

.result-card {
  width: min(78%, 420px);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 9px;
  padding: 10px 12px;
  border: 1px solid var(--line-2);
  border-radius: 11px;
  background: var(--accent-wash);
  color: var(--tx);
  text-decoration: none;
}

.result-card:hover {
  border-color: var(--line-3);
  background: var(--accent-wash-strong);
}

.result-card strong,
.result-card small {
  display: block;
}

.result-card strong {
  font-size: 11.5px;
}

.result-card small {
  margin-top: 2px;
  color: var(--tx-3);
  font: 9.5px var(--font-mono-v2);
}

.result-card:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

.caret::after {
  content: '▍';
  animation: blink 1s steps(1) infinite;
  color: var(--st-think);
}

@keyframes blink { 50% { opacity: 0; } }

.chat-in {
  padding: 14px;
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 9px;
  align-items: center;
  flex: 0 0 auto;
}

.context-chip {
  max-width: 190px;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 9px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--accent-wash);
  color: var(--tx-2);
  font-family: var(--font-body);
  font-size: 10.5px;
  white-space: nowrap;
}

.context-chip span,
.context-chip code {
  overflow: hidden;
  text-overflow: ellipsis;
}

.context-chip code {
  color: var(--tx-3);
  font-family: var(--font-mono-v2);
  font-size: 9.5px;
}

.chat-in input {
  flex: 1;
  min-width: 0;
  height: 44px;
  border-radius: 12px;
  border: 1px solid var(--line-2);
  background: var(--field-surface);
  color: var(--tx);
  padding: 0 14px;
  font-family: var(--font-body);
  font-size: 13px;
  outline: none;
  transition: border-color .15s, background .15s, box-shadow .15s;
}

.chat-in input::placeholder { color: var(--tx-3); }
.chat-in input:focus {
  border-color: var(--line-3);
  background: var(--field-surface-focus);
  box-shadow: var(--focus-ring);
}

.send {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  border: none;
  background: var(--grad);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: var(--glow-purple);
  flex: 0 0 auto;
  transition: filter .15s, opacity .15s;
}

.send:hover:not(:disabled) { filter: brightness(1.1); }
.send:disabled {
  cursor: not-allowed;
  opacity: .42;
  box-shadow: none;
}

.send :deep(svg) {
  width: 17px;
  height: 17px;
  color: var(--tx-on-accent);
}

.close-btn:focus-visible,
.send:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

@media (max-width: 767px) {
  .iris-dialog {
    width: calc(100vw - 16px);
    height: calc(100dvh - 24px);
  }

  .iris-panel {
    border-radius: var(--r);
  }

  .chat-scroll {
    padding: 14px;
  }

  .bubble {
    max-width: 88%;
  }

  .chat-in {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .context-chip {
    grid-column: 1 / -1;
    max-width: 100%;
    justify-self: start;
  }
}

@media (prefers-reduced-motion: reduce) {
  .iris-dialog[open],
  .caret::after {
    animation: none;
  }
}
</style>
