<template>
  <q-page padding>
    <div class="page-title">Messages</div>

    <!-- Filter tabs -->
    <q-tabs v-model="activeTab" dense align="left" class="q-mb-md bg-white rounded-borders"
      active-color="primary" indicator-color="primary" narrow-indicator>
      <q-tab name="all" label="Tous" no-caps />
      <q-tab name="SMS" label="SMS" no-caps icon="sms" />
      <q-tab name="Email" label="Courriel" no-caps icon="email" />
      <q-tab name="Phone" label="Appels" no-caps icon="phone" />
    </q-tabs>

    <!-- Loading -->
    <div v-if="loading" class="flex flex-center q-pa-xl">
      <q-spinner-dots size="48px" color="primary" />
    </div>

    <!-- Empty state -->
    <div v-else-if="!filteredMessages.length" class="text-center text-grey-6 q-pa-xl">
      <q-icon name="chat_bubble_outline" size="64px" class="q-mb-md" />
      <div class="text-h6">Aucun message</div>
    </div>

    <!-- Grouped messages -->
    <div v-else>
      <div v-for="group in groupedMessages" :key="group.key" class="q-mb-lg">
        <!-- Group header -->
        <div class="flex items-center q-mb-sm">
          <q-icon :name="groupIcon(group)" size="20px" color="grey-7" class="q-mr-sm" />
          <div class="text-subtitle2 text-weight-medium">
            {{ group.label }}
          </div>
          <q-badge v-if="group.ticketStatus" :color="ticketStatusColor(group.ticketStatus)"
            :label="group.ticketStatus" class="q-ml-sm" />
          <q-space />
          <span class="text-caption text-grey-6">{{ group.dateRange }}</span>
        </div>

        <!-- Messages in group -->
        <q-list bordered separator class="rounded-borders bg-white">
          <q-item v-for="msg in group.messages" :key="msg.name" class="q-pa-sm">
            <q-item-section avatar>
              <q-icon :name="mediumIcon(msg.communication_medium)"
                :color="msg.sent_or_received === 'Sent' ? 'primary' : 'grey-7'" />
            </q-item-section>
            <q-item-section>
              <q-item-label class="flex items-center">
                <q-icon v-if="msg.sent_or_received === 'Sent'" name="arrow_upward" size="14px" color="primary" class="q-mr-xs" />
                <q-icon v-else name="arrow_downward" size="14px" color="positive" class="q-mr-xs" />
                <span class="text-caption text-grey-7">
                  {{ msg.sent_or_received === 'Sent' ? 'Envoyé' : 'Reçu' }}
                  &middot; {{ formatDateTime(msg.creation) }}
                </span>
              </q-item-label>
              <q-item-label class="q-mt-xs message-content" v-html="truncateHTML(msg.content, 200)" />
              <q-item-label v-if="msg.phone_no" caption>
                <q-icon name="phone" size="12px" /> {{ msg.phone_no }}
              </q-item-label>
            </q-item-section>
            <q-item-section side v-if="msg.reference_doctype === 'Issue'">
              <q-btn flat dense size="sm" color="primary" no-caps
                :label="msg.reference_name"
                @click="$router.push('/tickets/' + msg.reference_name)" />
            </q-item-section>
          </q-item>
        </q-list>
      </div>
    </div>
  </q-page>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useQuasar } from 'quasar'
import { useCustomerStore } from 'src/stores/customer'
import { fetchAllCommunications } from 'src/api/portal'
import { useFormatters } from 'src/composables/useFormatters'
import { useSSE } from 'src/composables/useSSE'

const $q = useQuasar()
const store = useCustomerStore()
const { formatDate } = useFormatters()

const messages = ref([])
const loading = ref(true)
const activeTab = ref('all')

// SSE for real-time updates
const { connect: sseConnect } = useSSE({
  onMessage: async (data) => {
    if (data.customer === store.customerId) {
      // Reload full list on any new message
      messages.value = await fetchAllCommunications(store.customerId)
      if (data.direction === 'in') {
        $q.notify({
          type: 'info',
          icon: 'chat',
          message: `Nouveau message de ${data.customer_name || data.phone || 'Client'}`,
          timeout: 3000,
          position: 'top-right',
        })
      }
    }
  },
})

function mediumIcon (m) {
  if (m === 'SMS') return 'sms'
  if (m === 'Phone') return 'phone'
  if (m === 'Email') return 'email'
  return 'chat_bubble_outline'
}

function groupIcon (group) {
  if (group.type === 'ticket') return 'confirmation_number'
  if (group.medium === 'SMS') return 'sms'
  if (group.medium === 'Email') return 'email'
  if (group.medium === 'Phone') return 'phone'
  return 'chat_bubble_outline'
}

function ticketStatusColor (s) {
  if (s === 'Open') return 'primary'
  if (s === 'Closed' || s === 'Resolved') return 'positive'
  return 'grey'
}

function formatDateTime (d) {
  if (!d) return ''
  return new Date(d).toLocaleString('fr-CA', {
    year: 'numeric', month: 'short', day: 'numeric',
    hour: '2-digit', minute: '2-digit',
  })
}

function truncateHTML (html, maxLen) {
  if (!html) return ''
  // Strip HTML tags for length check, but return original if short enough
  const text = html.replace(/<[^>]+>/g, '')
  if (text.length <= maxLen) return html
  return text.substring(0, maxLen) + '...'
}

const filteredMessages = computed(() => {
  if (activeTab.value === 'all') return messages.value
  return messages.value.filter(m => m.communication_medium === activeTab.value)
})

const groupedMessages = computed(() => {
  const groups = new Map()

  for (const msg of filteredMessages.value) {
    let key, label, type, medium
    if (msg.reference_doctype === 'Issue' && msg.reference_name) {
      // Group by ticket
      key = 'ticket:' + msg.reference_name
      label = msg.reference_name + (msg.subject ? ' - ' + msg.subject : '')
      type = 'ticket'
    } else if (msg.communication_medium === 'SMS' && msg.phone_no) {
      // Group SMS by phone number + date
      const d = new Date(msg.creation).toISOString().slice(0, 10)
      key = 'sms:' + msg.phone_no + ':' + d
      label = 'SMS - ' + msg.phone_no
      type = 'sms'
      medium = 'SMS'
    } else if (msg.communication_medium === 'Email' && msg.subject) {
      // Group email by subject (strip Re: / Fwd: prefixes)
      const cleanSubject = (msg.subject || '').replace(/^(Re|Fwd|TR|RE):\s*/gi, '').trim()
      key = 'email:' + cleanSubject
      label = msg.subject
      type = 'email'
      medium = 'Email'
    } else {
      // Group by date
      const d = new Date(msg.creation).toISOString().slice(0, 10)
      key = 'other:' + d
      label = formatDate(msg.creation)
      type = 'other'
      medium = msg.communication_medium
    }

    if (!groups.has(key)) {
      groups.set(key, { key, label, type, medium, messages: [], ticketStatus: null })
    }
    groups.get(key).messages.push(msg)
  }

  // Sort groups by latest message, compute dateRange
  const result = Array.from(groups.values())
  for (const g of result) {
    g.messages.sort((a, b) => new Date(a.creation) - new Date(b.creation))
    const first = g.messages[0].creation
    const last = g.messages[g.messages.length - 1].creation
    if (first === last) {
      g.dateRange = formatDateTime(first)
    } else {
      g.dateRange = formatDateTime(first) + ' - ' + formatDateTime(last)
    }
  }
  // Sort groups: most recent message first
  result.sort((a, b) => {
    const aLast = new Date(a.messages[a.messages.length - 1].creation)
    const bLast = new Date(b.messages[b.messages.length - 1].creation)
    return bLast - aLast
  })
  return result
})

onMounted(async () => {
  if (!store.customerId) return
  try {
    messages.value = await fetchAllCommunications(store.customerId)
    sseConnect(['customer:' + store.customerId])
  } finally {
    loading.value = false
  }
})
</script>

<style scoped>
.message-content {
  word-break: break-word;
}
.message-content :deep(p) {
  margin: 0;
}
</style>
