<script setup lang="ts">
type ChatConversation = {
  id: string;
  title: string;
  lastMessageText?: string | null;
};

type PilotMessage = {
  id: string;
  role: "user" | "assistant" | "system";
  text: string;
  messageKind?: string | null;
  changeSummary?: string | null;
  changeItems?: Array<{ id: string; entity: string; action: string; title: string }> | null;
  changeSetId?: string | null;
  changeStatus?: string | null;
  createdAt?: string;
};

type ContextScopeChip = {
  scope: string;
  label: string;
};

defineProps<{
  pilotHeaderText: string;
  chatSwitching: boolean;
  chatThreadsLoading: boolean;
  chatConversations: ChatConversation[];
  authMe: { conversation?: { title?: string | null } | null } | null;
  chatCreating: boolean;
  renderedPilotMessages: PilotMessage[];
  pilotLiveLogs: Array<{ id: string; text: string }>;
  pilotLiveLogsExpanded: boolean;
  pilotLiveLogHiddenCount: number;
  pilotVisibleLogCount: number;
  pilotVisibleLiveLogs: Array<{ id: string; text: string }>;
  chatThreadPickerOpen: boolean;
  selectedChatId: string;
  chatArchivingId: string;
  pilotInputRef: { value: string };
  pilotRecording: boolean;
  contextScopeChips: ContextScopeChip[];
  contextPickerEnabled: boolean;
  pilotTranscribing: boolean;
  pilotSending: boolean;
  pilotMicSupported: boolean;
  pilotMicError: string | null;
  toggleChatThreadPicker: () => void;
  createNewChatConversation: () => void;
  pilotRoleBadge: (role: PilotMessage["role"]) => string;
  pilotRoleName: (role: PilotMessage["role"]) => string;
  formatPilotStamp: (iso?: string) => string;
  summarizeChangeActions: (items: PilotMessage["changeItems"] | null | undefined) => {
    created: number;
    updated: number;
    deleted: number;
  };
  summarizeChangeEntities: (
    items: PilotMessage["changeItems"] | null | undefined,
  ) => Array<{ entity: string; count: number }>;
  openChangeReview: (changeSetId: string, step?: number, push?: boolean) => void;
  togglePilotLiveLogsExpanded: () => void;
  closeChatThreadPicker: () => void;
  switchChatConversation: (id: string) => void;
  formatChatThreadMeta: (conversation: ChatConversation) => string;
  archiveChatConversation: (id: string) => void;
  handlePilotComposerEnter: (event: KeyboardEvent) => void;
  setPilotWaveContainerRef: (element: HTMLDivElement | null) => void;
  toggleContextPicker: () => void;
  removeContextScope: (scope: string) => void;
  togglePilotRecording: () => void;
  handlePilotSendAction: () => void;
}>();
</script>

<template>
  <aside class="pilot-shell min-h-0 border-r border-base-300">
    <div class="flex h-full min-h-0 flex-col p-0">
      <div class="pilot-header">
        <div>
          <h2 class="text-sm font-semibold text-white/75">{{ pilotHeaderText }}</h2>
        </div>
      </div>
      <div class="pilot-threads">
        <div class="flex w-full items-center justify-between gap-2">
          <button
            class="btn btn-ghost btn-xs h-7 min-h-7 max-w-[228px] justify-start px-1 text-xs font-medium text-white/90 hover:bg-white/10"
            :disabled="chatSwitching || chatThreadsLoading || chatConversations.length === 0"
            :title="authMe?.conversation?.title || 'Thread'"
            @click="toggleChatThreadPicker"
          >
            <span class="truncate">{{ authMe?.conversation?.title || "Thread" }}</span>
            <svg viewBox="0 0 20 20" class="ml-1 h-3.5 w-3.5 fill-current opacity-80">
              <path fill-rule="evenodd" clip-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" />
            </svg>
          </button>
          <button
            class="btn btn-ghost btn-xs h-7 min-h-7 px-1 text-white/85 hover:bg-white/10"
            :disabled="chatCreating"
            title="New chat"
            @click="createNewChatConversation"
          >
            {{ chatCreating ? "…" : "+" }}
          </button>
        </div>
      </div>

      <div class="pilot-stream-wrap min-h-0 flex-1">
        <div class="pilot-timeline min-h-0 h-full overflow-y-auto">
          <div
            v-for="message in renderedPilotMessages"
            :key="message.id"
            class="pilot-row"
          >
            <div class="pilot-avatar" :class="message.role === 'user' ? 'pilot-avatar-user' : ''">
              {{ pilotRoleBadge(message.role) }}
            </div>

            <div class="pilot-body">
              <div class="pilot-meta">
                <span class="pilot-author">{{ pilotRoleName(message.role) }}</span>
                <span class="pilot-time">{{ formatPilotStamp(message.createdAt) }}</span>
              </div>

              <div v-if="message.messageKind === 'change_set_summary'" class="rounded-xl border border-amber-300/35 bg-amber-500/10 p-3">
                <p class="text-xs font-semibold text-amber-100">
                  {{ message.changeSummary || "Technical change summary" }}
                </p>
                <div class="mt-2 overflow-x-auto">
                  <table class="w-full min-w-[340px] text-left text-[11px] text-white/85">
                    <thead>
                      <tr class="text-white/60">
                        <th class="py-1 pr-2 font-medium">Metric</th>
                        <th class="py-1 pr-2 font-medium">Value</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr>
                        <td class="py-1 pr-2">Total changes</td>
                        <td class="py-1 pr-2">{{ message.changeItems?.length || 0 }}</td>
                      </tr>
                      <tr>
                        <td class="py-1 pr-2">Created</td>
                        <td class="py-1 pr-2">{{ summarizeChangeActions(message.changeItems).created }}</td>
                      </tr>
                      <tr>
                        <td class="py-1 pr-2">Updated</td>
                        <td class="py-1 pr-2">{{ summarizeChangeActions(message.changeItems).updated }}</td>
                      </tr>
                      <tr>
                        <td class="py-1 pr-2">Archived</td>
                        <td class="py-1 pr-2">{{ summarizeChangeActions(message.changeItems).deleted }}</td>
                      </tr>
                    </tbody>
                  </table>
                </div>
                <div v-if="summarizeChangeEntities(message.changeItems).length" class="mt-2 flex flex-wrap gap-1.5">
                  <span
                    v-for="row in summarizeChangeEntities(message.changeItems)"
                    :key="`entity-summary-${message.id}-${row.entity}`"
                    class="rounded border border-white/20 px-2 py-0.5 text-[10px] text-white/75"
                  >
                    {{ row.entity }}: {{ row.count }}
                  </span>
                </div>
                <div class="mt-3 flex flex-wrap items-center gap-2">
                  <button
                    v-if="message.changeSetId"
                    class="btn btn-xs btn-outline"
                    @click="openChangeReview(message.changeSetId, 0, true)"
                  >
                    Review Changes
                  </button>
                  <span class="text-[10px] uppercase tracking-wide text-amber-100/80">
                    status: {{ message.changeStatus || "pending" }}
                  </span>
                </div>
              </div>

              <div v-else class="pilot-message-text">
                {{ message.text }}
              </div>
            </div>
          </div>
          <div v-if="pilotLiveLogs.length" class="pilot-stream-status">
            <div class="pilot-stream-head">
              <p v-if="!pilotLiveLogsExpanded && pilotLiveLogHiddenCount > 0" class="pilot-stream-caption">
                Showing last {{ pilotVisibleLogCount }} steps
              </p>
              <button
                v-if="pilotLiveLogHiddenCount > 0 || pilotLiveLogsExpanded"
                type="button"
                class="pilot-stream-toggle"
                @click="togglePilotLiveLogsExpanded"
              >
                {{ pilotLiveLogsExpanded ? "Show less" : `Show all (+${pilotLiveLogHiddenCount})` }}
              </button>
            </div>
            <p
              v-for="log in pilotVisibleLiveLogs"
              :key="`pilot-log-${log.id}`"
              class="pilot-stream-line"
              :class="log.id === pilotLiveLogs[pilotLiveLogs.length - 1]?.id ? 'pilot-stream-line-current' : ''"
            >
              {{ log.text }}
            </p>
          </div>
        </div>

        <div v-if="chatThreadPickerOpen" class="pilot-thread-overlay">
          <div class="mb-2 flex items-center justify-between">
            <p class="text-[11px] font-semibold uppercase tracking-wide text-white/60">Threads</p>
            <button class="btn btn-ghost btn-xs btn-square text-white/70 hover:bg-white/10" title="Close" @click="closeChatThreadPicker">
              <svg viewBox="0 0 20 20" class="h-3.5 w-3.5 fill-current">
                <path d="M11.06 10 15.53 5.53a.75.75 0 1 0-1.06-1.06L10 8.94 5.53 4.47a.75.75 0 0 0-1.06 1.06L8.94 10l-4.47 4.47a.75.75 0 1 0 1.06 1.06L10 11.06l4.47 4.47a.75.75 0 0 0 1.06-1.06z" />
              </svg>
            </button>
          </div>
          <div class="max-h-full space-y-1 overflow-y-auto pr-1">
            <div
              v-for="thread in chatConversations"
              :key="`thread-row-${thread.id}`"
              class="flex items-center gap-1 rounded-md"
            >
              <button
                class="min-w-0 flex-1 rounded-md px-2 py-1.5 text-left transition hover:bg-white/10"
                :class="selectedChatId === thread.id ? 'bg-white/12' : ''"
                :disabled="chatSwitching || chatArchivingId === thread.id"
                @click="switchChatConversation(thread.id)"
              >
                <p class="truncate text-xs font-medium text-white">{{ thread.title }}</p>
                <p class="truncate text-[11px] text-white/55">
                  {{ thread.lastMessageText || "No messages yet" }} · {{ formatChatThreadMeta(thread) }}
                </p>
              </button>
              <button
                class="btn btn-ghost btn-xs btn-square text-white/55 hover:bg-white/10 hover:text-red-300"
                :disabled="chatSwitching || chatArchivingId === thread.id || chatConversations.length <= 1"
                title="Archive thread"
                @click="archiveChatConversation(thread.id)"
              >
                <span v-if="chatArchivingId === thread.id" class="loading loading-spinner loading-xs" />
                <svg v-else viewBox="0 0 24 24" class="h-3.5 w-3.5 fill-current">
                  <path d="M20.54 5.23 19 3H5L3.46 5.23A2 2 0 0 0 3 6.36V8a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6.36a2 2 0 0 0-.46-1.13M5.16 5h13.68l.5.73A.5.5 0 0 1 19.5 6H4.5a.5.5 0 0 1-.34-.27zM6 12h12v6a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2z" />
                </svg>
              </button>
            </div>
          </div>
        </div>
      </div>

      <div class="pilot-input-wrap">
        <div class="pilot-input-shell">
          <textarea
            v-model="pilotInputRef.value"
            class="pilot-input-textarea"
            :placeholder="pilotRecording ? 'Recording... speak, then press mic to fill or send to submit' : 'Type a message for Pilot...'"
            @keydown.enter="handlePilotComposerEnter"
          />

          <div v-if="pilotRecording" class="pilot-meter">
            <div :ref="setPilotWaveContainerRef" class="pilot-wave-canvas" />
          </div>

          <div v-if="!pilotRecording" class="pilot-input-context">
            <button
              v-if="contextScopeChips.length === 0"
              class="context-pipette-trigger"
              :class="contextPickerEnabled ? 'context-pipette-active' : ''"
              :disabled="pilotTranscribing || pilotSending"
              aria-label="Контекстная пипетка"
              :title="contextPickerEnabled ? 'Выключить пипетку' : 'Включить пипетку контекста'"
              @click="toggleContextPicker"
            >
              <svg viewBox="0 0 24 24" class="h-3.5 w-3.5 fill-current">
                <path d="M19.29 4.71a1 1 0 0 0-1.42 0l-2.58 2.58-1.17-1.17a1 1 0 0 0-1.41 0l-1.42 1.42a1 1 0 0 0 0 1.41l.59.59-5.3 5.3a2 2 0 0 0-.53.92l-.86 3.43a1 1 0 0 0 1.21 1.21l3.43-.86a2 2 0 0 0 .92-.53l5.3-5.3.59.59a1 1 0 0 0 1.41 0l1.42-1.42a1 1 0 0 0 0-1.41l-1.17-1.17 2.58-2.58a1 1 0 0 0 0-1.42z" />
              </svg>
            </button>

            <div v-else class="pilot-context-chips">
              <button
                v-for="chip in contextScopeChips"
                :key="`context-chip-${chip.scope}`"
                type="button"
                class="context-pipette-chip"
                @click="removeContextScope(chip.scope)"
              >
                {{ chip.label }}
                <span class="opacity-70">×</span>
              </button>
            </div>
          </div>

          <div class="pilot-input-actions">
            <button
              class="btn btn-xs btn-circle border border-white/20 bg-transparent text-white/90 hover:bg-white/10"
              :class="pilotRecording ? 'pilot-mic-active' : ''"
              :disabled="!pilotMicSupported || pilotTranscribing || pilotSending"
              :title="pilotRecording ? 'Stop and insert transcript' : 'Voice input'"
              @click="togglePilotRecording"
            >
              <svg v-if="!pilotTranscribing" viewBox="0 0 24 24" class="h-3.5 w-3.5 fill-current">
                <path d="M12 15a3 3 0 0 0 3-3V7a3 3 0 1 0-6 0v5a3 3 0 0 0 3 3m5-3a1 1 0 1 1 2 0 7 7 0 0 1-6 6.92V21h3a1 1 0 1 1 0 2H8a1 1 0 1 1 0-2h3v-2.08A7 7 0 0 1 5 12a1 1 0 1 1 2 0 5 5 0 0 0 10 0" />
              </svg>
              <span v-else class="loading loading-spinner loading-xs" />
            </button>

            <button
              class="btn btn-sm btn-circle border-0 bg-[#5865f2] text-white hover:bg-[#4752c4]"
              :disabled="pilotTranscribing || pilotSending || (!pilotRecording && !pilotInputRef.value.trim())"
              :title="pilotRecording ? 'Transcribe and send' : 'Send message'"
              @click="handlePilotSendAction"
            >
              <svg viewBox="0 0 24 24" class="h-4 w-4 fill-current" :class="pilotSending ? 'opacity-50' : ''">
                <path d="M4.5 19.5 21 12 4.5 4.5l.02 5.84L15 12l-10.48 1.66z" />
              </svg>
            </button>
          </div>
        </div>
        <p v-if="pilotMicError" class="pilot-mic-error">{{ pilotMicError }}</p>
      </div>
    </div>
  </aside>
</template>

<style scoped>
.pilot-shell {
  background:
    radial-gradient(circle at 10% -10%, rgba(124, 144, 255, 0.25), transparent 40%),
    radial-gradient(circle at 85% 110%, rgba(88, 101, 242, 0.2), transparent 45%),
    #151821;
  color: #f5f7ff;
}

.pilot-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  padding: 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(8, 10, 16, 0.2);
}

.pilot-threads {
  padding: 10px 10px 8px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.pilot-timeline {
  padding: 10px 8px;
}

.pilot-stream-wrap {
  position: relative;
}

.pilot-thread-overlay {
  position: absolute;
  inset: 0;
  z-index: 20;
  padding: 10px 8px;
  background:
    linear-gradient(180deg, rgba(15, 18, 28, 0.96), rgba(15, 18, 28, 0.92)),
    rgba(15, 18, 28, 0.9);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.pilot-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 6px;
  border-radius: 10px;
}

.pilot-row:hover {
  background: rgba(255, 255, 255, 0.04);
}

.pilot-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: #e6ebff;
  background: linear-gradient(135deg, #5865f2, #7c90ff);
}

.pilot-avatar-user {
  background: linear-gradient(135deg, #2a9d8f, #38b2a7);
}

.pilot-body {
  min-width: 0;
  width: 100%;
}

.pilot-meta {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pilot-author {
  font-size: 13px;
  font-weight: 700;
  color: #f8f9ff;
}

.pilot-time {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.45);
}

.pilot-message-text {
  margin-top: 2px;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  color: rgba(255, 255, 255, 0.92);
}

.pilot-input-wrap {
  display: grid;
  gap: 6px;
  padding: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  background: transparent;
}

.pilot-input-shell {
  position: relative;
}

.pilot-input-textarea {
  width: 100%;
  min-height: 96px;
  resize: none;
  border-radius: 0;
  border: 0;
  background: transparent;
  color: #f5f7ff;
  padding: 10px 88px 36px 12px;
  font-size: 13px;
  line-height: 1.4;
}

.pilot-input-textarea::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.pilot-input-textarea:focus {
  outline: none;
  box-shadow: none;
}

.pilot-input-actions {
  position: absolute;
  right: 10px;
  bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.pilot-input-context {
  position: absolute;
  left: 10px;
  bottom: 8px;
  right: 96px;
  display: flex;
  align-items: center;
  min-height: 24px;
  overflow: hidden;
}

.context-pipette-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.06);
  color: rgba(245, 247, 255, 0.94);
  padding: 0;
  transition: transform 220ms ease, border-color 220ms ease, background-color 220ms ease;
}

.context-pipette-trigger:hover {
  transform: scale(1.03);
  border-color: color-mix(in oklab, var(--color-primary) 62%, transparent);
  background: color-mix(in oklab, var(--color-primary) 18%, transparent);
}

.context-pipette-active {
  border-color: color-mix(in oklab, var(--color-primary) 72%, transparent);
  background: color-mix(in oklab, var(--color-primary) 24%, transparent);
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--color-primary) 38%, transparent) inset;
}

.pilot-context-chips {
  display: flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  overflow-x: auto;
  padding-bottom: 1px;
}

.pilot-context-chips::-webkit-scrollbar {
  height: 3px;
}

.pilot-context-chips::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.24);
  border-radius: 999px;
}

.context-pipette-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.08);
  color: rgba(245, 247, 255, 0.95);
  padding: 4px 9px;
  font-size: 10px;
  line-height: 1;
  white-space: nowrap;
  transition: transform 220ms ease, border-color 220ms ease, background-color 220ms ease;
}

.context-pipette-chip:hover {
  transform: scale(1.03);
  border-color: color-mix(in oklab, var(--color-primary) 62%, transparent);
  background: color-mix(in oklab, var(--color-primary) 20%, transparent);
}

.pilot-meter {
  position: absolute;
  left: 12px;
  right: 88px;
  bottom: 9px;
  height: 22px;
}

.pilot-wave-canvas {
  width: 100%;
  height: 100%;
  display: block;
  overflow: hidden;
}

.pilot-wave-canvas :deep(wave) {
  display: block;
  height: 100% !important;
}

.pilot-wave-canvas :deep(canvas) {
  height: 100% !important;
}

.pilot-mic-active {
  border-color: rgba(255, 95, 95, 0.8) !important;
  background: rgba(255, 95, 95, 0.16) !important;
  color: #ffd9d9 !important;
}

.pilot-mic-error {
  margin: 0;
  font-size: 11px;
  color: rgba(255, 160, 160, 0.92);
}

.pilot-stream-status {
  margin-top: 8px;
  padding: 2px 4px 8px;
  display: grid;
  gap: 3px;
}

.pilot-stream-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-bottom: 2px;
}

.pilot-stream-caption {
  margin: 0;
  text-align: center;
  font-size: 10px;
  line-height: 1.3;
  color: rgba(174, 185, 223, 0.72);
}

.pilot-stream-toggle {
  border: 1px solid rgba(164, 179, 230, 0.35);
  background: rgba(25, 33, 56, 0.45);
  color: rgba(229, 235, 255, 0.92);
  border-radius: 999px;
  font-size: 10px;
  line-height: 1.2;
  padding: 3px 8px;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.pilot-stream-toggle:hover {
  border-color: rgba(180, 194, 240, 0.6);
  background: rgba(35, 45, 72, 0.7);
}

.pilot-stream-line {
  margin: 0;
  text-align: center;
  font-size: 11px;
  line-height: 1.35;
  color: rgba(189, 199, 233, 0.72);
}

.pilot-stream-line-current {
  color: rgba(234, 239, 255, 0.95);
}
</style>
