<template>
  <q-dialog :model-value="modelValue" @update:model-value="$emit('update:modelValue', $event)" maximized>
    <q-card class="column no-wrap">
      <q-toolbar class="bg-primary text-white">
        <q-icon name="chat" class="q-mr-sm" />
        <q-toolbar-title>{{ spotName }} 채팅</q-toolbar-title>
        <q-chip dense :color="connected ? 'positive' : 'grey-5'" text-color="white">
          {{ connected ? '실시간' : '연결 중…' }}
        </q-chip>
        <q-btn flat round dense icon="close" @click="close" />
      </q-toolbar>

      <!-- 메시지 목록 -->
      <q-scroll-area ref="scrollArea" class="col q-pa-md" style="background: #f4faff">
        <div v-if="!messages.length" class="text-center text-grey-5 q-mt-lg">
          첫 메시지를 남겨보세요. 이 스팟에 체크인한 이웃들과 대화해요.
        </div>
        <div
          v-for="m in messages"
          :key="m.id"
          class="q-mb-sm row"
          :class="isMine(m) ? 'justify-end' : 'justify-start'"
        >
          <div :class="isMine(m) ? 'msg mine' : 'msg'">
            <div v-if="!isMine(m)" class="text-caption text-weight-medium text-accent">
              {{ m.senderNickname }}
            </div>
            <div>{{ m.content }}</div>
            <div class="text-caption text-grey-6 text-right">{{ time(m.createdAt) }}</div>
          </div>
        </div>
      </q-scroll-area>

      <!-- 입력 -->
      <div class="row q-pa-sm q-gutter-sm bg-white items-center">
        <q-input
          v-model="draft"
          class="col"
          dense
          outlined
          placeholder="메시지 입력…"
          maxlength="1000"
          :disable="!connected"
          @keyup.enter="send"
        />
        <q-btn round color="primary" icon="send" :disable="!connected || !draft.trim()" @click="send" />
      </div>
    </q-card>
  </q-dialog>
</template>

<script setup lang="ts">
import { nextTick, onBeforeUnmount, ref, watch } from 'vue'
import { QScrollArea, useQuasar } from 'quasar'
import { chatApi, type ChatMessage } from '@/api/chat'
import { createSpotChat } from '@/lib/chatSocket'
import { useAuthStore } from '@/stores/auth'

const props = defineProps<{ modelValue: boolean; spotId: number; spotName: string }>()
const emit = defineEmits<{ (e: 'update:modelValue', v: boolean): void }>()

const $q = useQuasar()
const auth = useAuthStore()

const messages = ref<ChatMessage[]>([])
const draft = ref('')
const connected = ref(false)
const scrollArea = ref<QScrollArea | null>(null)
let chat: ReturnType<typeof createSpotChat> | null = null

watch(
  () => props.modelValue,
  async (open) => {
    if (open) await start()
    else stop()
  },
)

onBeforeUnmount(stop)

async function start() {
  messages.value = []
  try {
    messages.value = await chatApi.history(props.spotId)
    scrollToBottom()
  } catch {
    // 히스토리 실패해도 실시간 연결은 시도
  }
  chat = createSpotChat(
    props.spotId,
    (m) => {
      messages.value.push(m)
      scrollToBottom()
    },
    (c) => (connected.value = c),
  )
  chat.activate()
}

function stop() {
  chat?.deactivate()
  chat = null
  connected.value = false
}

function send() {
  const text = draft.value.trim()
  if (!text || !chat) return
  chat.send(text)
  draft.value = ''
}

function close() {
  emit('update:modelValue', false)
}

function isMine(m: ChatMessage) {
  return m.senderId === auth.member?.id
}

function time(iso: string) {
  const d = new Date(iso)
  return d.toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit' })
}

function scrollToBottom() {
  nextTick(() => {
    const el = scrollArea.value
    if (el) el.setScrollPercentage('vertical', 1, 150)
  })
}
</script>

<style scoped>
.msg {
  max-width: 76%;
  padding: 8px 12px;
  border-radius: 12px;
  background: #ffffff;
  border: 1px solid #e3eef7;
  word-break: break-word;
}
.msg.mine {
  background: #d7ecfb;
  border-color: #cfe8fb;
}
</style>
