<template>
  <div class="chat-view">
    <h1 class="page-title">Knowledge Chat</h1>
    <p class="page-subtitle">Ask questions grounded in your uploaded medical textbooks.</p>

    <!-- Session selection -->
    <div v-if="!chatStore.session" class="session-setup card">
      <div class="setup-header">
        <h2 class="section-title">Free-form Chat</h2>
      </div>

      <div v-if="chatStore.error" class="error-banner">{{ chatStore.error }}</div>

      <div v-if="loadingTopicSessions" class="sessions-loading">
        <div class="spinner spinner-dark" style="width:20px;height:20px;display:inline-block;"></div>
        Loading previous chats...
      </div>

      <div v-else-if="topicSessions.length > 0" class="previous-sessions">
        <h3 class="sessions-label">Previous Chats</h3>
        <div
          v-for="s in topicSessions"
          :key="s.sessionId"
          class="session-row"
          @click="handleResumeSession(s)"
        >
          <span class="session-row-date">{{ formatDate(s.createdAt) }}</span>
          <span class="session-row-action">Resume →</span>
        </div>
      </div>

      <div v-else-if="!loadingTopicSessions" class="no-sessions-hint">
        No previous chats for this topic.
      </div>

      <button
        class="btn btn-primary"
        :disabled="chatStore.loading"
        @click="handleNewChat"
      >
        <span v-if="chatStore.loading" class="spinner"></span>
        {{ chatStore.loading ? 'Starting...' : '+ New Chat' }}
      </button>
    </div>

    <!-- Step 3: Active Session -->
    <div v-else-if="chatStore.session" class="chat-layout">
      <!-- Session Info Bar -->
      <div class="session-bar card">
        <div class="session-info">
          <button class="btn-back" @click="handleLeaveSession">← Back</button>
          <span class="session-topic">{{ getTopicName(chatStore.session.topicId) }}</span>
          <span class="session-id">{{ chatStore.session.sessionId.slice(0, 8) }}...</span>
        </div>
      </div>

      <!-- Chat + Reader split -->
      <div class="chat-reader-split">
        <!-- Messages + Input -->
        <div class="chat-column">
          <!-- Messages Area -->
          <div class="messages-container" ref="messagesContainer">
            <div v-if="chatStore.loading && chatStore.messages.length === 0" class="empty-state">
              <div class="spinner spinner-dark" style="width:32px;height:32px;margin:0 auto 1rem;"></div>
              <p class="empty-state-text">Loading messages...</p>
            </div>

            <div v-else-if="chatStore.messages.length === 0" class="empty-state">
              <div class="empty-state-icon">💬</div>
              <p class="empty-state-text">No messages yet</p>
              <p class="empty-state-hint">Ask a question about the uploaded books below.</p>
            </div>

            <div v-else class="messages-list">
              <ChatMessage
                v-for="message in chatStore.messages"
                :key="message.id"
                :message="message"
                @open-source="handleOpenSource"
              />
              <div v-if="chatStore.sending" class="typing-indicator">
                <div class="typing-bubble">
                  <span></span><span></span><span></span>
                </div>
              </div>
            </div>
          </div>

          <!-- Input Area -->
          <div class="input-area card">
            <div v-if="chatStore.error" class="error-banner">{{ chatStore.error }}</div>
            <div class="input-row">
              <textarea
                v-model="inputText"
                class="message-input"
                placeholder="Ask a question about your uploaded books..."
                rows="2"
                :disabled="chatStore.sending"
                @keydown.enter.exact.prevent="handleSend"
                @keydown.enter.shift.exact="inputText += '\n'"
              ></textarea>
              <button
                class="btn btn-primary send-btn"
                :disabled="!inputText.trim() || chatStore.sending"
                @click="handleSend"
              >
                <span v-if="chatStore.sending" class="spinner"></span>
                <span v-else>Send</span>
              </button>
            </div>
            <p class="input-hint">Press Enter to send, Shift+Enter for new line.</p>
          </div>
        </div>

        <!-- Inline book reader panel -->
        <BookPagePanel
          v-if="readerPanel"
          :book-id="readerPanel.bookId"
          :page="readerPanel.page"
          :book-title="readerPanel.bookTitle"
          class="reader-panel"
          @close="readerPanel = null"
          @navigate="(p) => readerPanel && (readerPanel.page = p)"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick, onMounted, watch, inject } from 'vue'
import { useChatStore } from '@/stores/chatStore'
import { useTopicStore } from '@/stores/topicStore'
import { useBookStore } from '@/stores/bookStore'
import type { ChatSession } from '@/stores/chatStore'
import ChatMessage from '@/components/ChatMessage.vue'
import BookPagePanel from '@/components/BookPagePanel.vue'

interface Topic {
  id: string
  name: string
  category: string
  description: string
}

const chatStore = useChatStore()
const topicStore = useTopicStore()
const bookStore = useBookStore()
const showToast = inject<(msg: string, type?: 'error' | 'success') => void>('showToast')

const selectedTopic = ref<Topic | null>(null)
const topicSessions = ref<ChatSession[]>([])
const loadingTopicSessions = ref(false)
const inputText = ref('')
const messagesContainer = ref<HTMLElement | null>(null)

interface ReaderPanel { bookId: string; page: number; bookTitle?: string }
const readerPanel = ref<ReaderPanel | null>(null)

function handleOpenSource(bookId: string, page: number) {
  const book = bookStore.books.find(b => b.id === bookId)
  readerPanel.value = { bookId, page, bookTitle: book?.title }
}

onMounted(async () => {
  if (topicStore.topics.length === 0) {
    await topicStore.fetchTopics()
  }
  const freeForm = topicStore.topics.find((t) => t.id === 'free-form')
  if (freeForm) {
    await handleTopicSelect(freeForm)
  }
})

watch(
  () => chatStore.messages.length,
  async () => { await nextTick(); scrollToBottom() }
)

watch(
  () => chatStore.sending,
  async () => { await nextTick(); scrollToBottom() }
)

function scrollToBottom() {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

function getTopicName(topicId: string | null): string {
  if (!topicId) return 'Free-form Chat'
  const topic = topicStore.topics.find((t) => t.id === topicId)
  return topic ? topic.name : topicId
}

function formatDate(iso: string): string {
  return new Date(iso).toLocaleString()
}

async function handleTopicSelect(topic: Topic) {
  selectedTopic.value = topic
  loadingTopicSessions.value = true
  topicSessions.value = await chatStore.fetchSessionsByTopic(topic.id)
  loadingTopicSessions.value = false
}

async function handleNewChat() {
  const ok = await chatStore.createSession(selectedTopic.value!.id)
  if (!ok) {
    showToast?.(chatStore.error ?? 'Could not start session.', 'error')
  }
}

async function handleResumeSession(session: ChatSession) {
  chatStore.session = session
  await chatStore.loadMessages()
}

function handleLeaveSession() {
  chatStore.leaveSession()
  if (selectedTopic.value) {
    loadingTopicSessions.value = true
    chatStore.fetchSessionsByTopic(selectedTopic.value.id).then((sessions) => {
      topicSessions.value = sessions
      loadingTopicSessions.value = false
    })
  }
}

async function handleSend() {
  const content = inputText.value.trim()
  if (!content || chatStore.sending) return
  inputText.value = ''
  const ok = await chatStore.sendMessage(content)
  if (!ok) {
    showToast?.(chatStore.error ?? 'Failed to send message.', 'error')
  }
}
</script>

<style scoped>
.section-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: #2d3748;
  margin: 0;
}

.session-setup {
  max-width: 540px;
}

.setup-header {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.btn-back {
  background: none;
  border: none;
  color: #3182ce;
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
  padding: 0;
  white-space: nowrap;
}

.btn-back:hover {
  color: #2b6cb0;
}

.sessions-loading {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: #718096;
  margin-bottom: 1rem;
}

.previous-sessions {
  margin-bottom: 1.25rem;
}

.sessions-label {
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #a0aec0;
  margin-bottom: 0.5rem;
}

.session-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 0.75rem;
  border: 1px solid #e2e8f0;
  border-radius: 6px;
  margin-bottom: 0.4rem;
  cursor: pointer;
  transition: background 0.12s;
}

.session-row:hover {
  background: #ebf8ff;
  border-color: #bee3f8;
}

.session-row-date {
  font-size: 0.875rem;
  color: #4a5568;
}

.session-row-action {
  font-size: 0.8rem;
  color: #3182ce;
  font-weight: 500;
}

.no-sessions-hint {
  font-size: 0.875rem;
  color: #a0aec0;
  font-style: italic;
  margin-bottom: 1.25rem;
}

.chat-layout {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  height: calc(100vh - 180px);
  min-height: 500px;
}

.chat-reader-split {
  display: flex;
  flex: 1;
  min-height: 0;
  gap: 0;
}

.chat-column {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  gap: 1rem;
}

.reader-panel {
  width: 420px;
  flex-shrink: 0;
  border-radius: 10px;
  margin-left: 1rem;
  box-shadow: -2px 0 8px rgba(0, 0, 0, 0.07);
}

.session-bar {
  display: flex;
  align-items: center;
  padding: 0.75rem 1rem;
  flex-shrink: 0;
}

.session-info {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.session-id {
  font-family: monospace;
  font-size: 0.85rem;
  color: #4a5568;
  background: #f7fafc;
  padding: 0.15rem 0.4rem;
  border-radius: 4px;
}

.session-topic {
  font-size: 0.875rem;
  color: #2b6cb0;
  font-weight: 500;
}

.messages-container {
  flex: 1;
  overflow-y: auto;
  background: #f7fafc;
  border-radius: 10px;
  padding: 1rem;
  scroll-behavior: smooth;
}

.messages-list {
  display: flex;
  flex-direction: column;
}

.typing-indicator {
  display: flex;
  margin-bottom: 1rem;
}

.typing-bubble {
  background: white;
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  border-bottom-left-radius: 4px;
  padding: 0.75rem 1rem;
  display: flex;
  gap: 0.3rem;
  align-items: center;
}

.typing-bubble span {
  width: 8px;
  height: 8px;
  background: #a0aec0;
  border-radius: 50%;
  animation: bounce 1.2s infinite ease-in-out;
}

.typing-bubble span:nth-child(2) { animation-delay: 0.15s; }
.typing-bubble span:nth-child(3) { animation-delay: 0.3s; }

@keyframes bounce {
  0%, 60%, 100% { transform: translateY(0); }
  30% { transform: translateY(-6px); }
}

.input-area {
  flex-shrink: 0;
}

.input-row {
  display: flex;
  gap: 0.75rem;
  align-items: flex-end;
}

.message-input {
  flex: 1;
  padding: 0.65rem 0.75rem;
  border: 1px solid #cbd5e0;
  border-radius: 6px;
  font-size: 0.9rem;
  font-family: inherit;
  color: #2d3748;
  resize: none;
  line-height: 1.5;
}

.message-input:focus {
  outline: none;
  border-color: #3182ce;
  box-shadow: 0 0 0 3px rgba(49, 130, 206, 0.2);
}

.send-btn {
  flex-shrink: 0;
  min-width: 72px;
  height: 42px;
}

.input-hint {
  font-size: 0.75rem;
  color: #a0aec0;
  margin-top: 0.4rem;
}

.error-banner {
  background: #fff5f5;
  border: 1px solid #fed7d7;
  color: #742a2a;
  border-radius: 6px;
  padding: 0.6rem 0.85rem;
  font-size: 0.875rem;
  margin-bottom: 0.75rem;
}

@media (max-width: 768px) {
  .chat-layout {
    height: auto;
    min-height: unset;
  }

  .chat-reader-split {
    flex-direction: column;
  }

  .chat-column {
    min-height: 60vh;
  }

  .reader-panel {
    width: 100%;
    margin-left: 0;
    margin-top: 1rem;
    box-shadow: none;
  }
}
</style>
