<template>
  <div class="inbox-root">

    <!-- ── Thin icon nav ──────────────────────────────────────────── -->
    <nav class="inbox-nav">
      <div class="nav-logo">
        <img v-if="cfg.logoUrl" :src="cfg.logoUrl" class="logo-img" alt="" />
        <svg v-else viewBox="0 0 40 40" width="32" height="32">
          <circle cx="20" cy="20" r="20" fill="#25d366"/>
          <path d="M20 8C13.37 8 8 13.37 8 20c0 2.2.6 4.25 1.64 6.02L8 32l6.1-1.6A12 12 0 1020 8z" fill="white"/>
        </svg>
      </div>

      <a href="/inbox"           class="nav-icon active" title="Inbox">      <i class="fas fa-inbox"></i>     </a>
      <a :href="cfg.routes?.dashboard"  class="nav-icon" title="Dashboard">  <i class="fas fa-home"></i>      </a>
      <a :href="cfg.routes?.setup"      class="nav-icon" title="WA Setup">   <i class="fab fa-whatsapp"></i>  </a>
      <a :href="cfg.routes?.apiDocs"    class="nav-icon" title="API Docs">   <i class="fas fa-code"></i>      </a>

      <div class="nav-spacer"></div>

      <div class="wa-status-dot" :class="cfg.waConnected ? 'on' : 'off'"
        :title="cfg.waConnected ? 'WhatsApp Connected' : 'WhatsApp Disconnected'"></div>

      <form method="POST" :action="cfg.routes?.logout" style="margin:0">
        <input type="hidden" name="_token" :value="cfg.csrfToken" />
        <button type="submit" class="nav-icon logout-btn" title="Logout">
          <i class="fas fa-sign-out-alt"></i>
        </button>
      </form>
    </nav>

    <!-- ── Conversation list ──────────────────────────────────────── -->
    <ConversationList
      :conversations="filteredConversations"
      :selectedId="selectedConv?.id ?? null"
      :currentFilter="filter"
      :search="search"
      @select="selectConversation"
      @filterChange="f => filter = f"
      @searchChange="s => search = s"
    />

    <!-- ── Chat window ────────────────────────────────────────────── -->
    <ChatWindow
      :conversation="selectedConv"
      :messages="messages"
      :sending="sending"
      @send="sendText"
      @sendMedia="sendMedia"
      @sendLocation="sendLocation"
      @statusChange="updateStatus"
      @labelChange="updateLabel"
    />

    <!-- Toast -->
    <div v-if="toast" class="toast" :class="toast.type">{{ toast.text }}</div>
  </div>
</template>

<script>
import ConversationList from './ConversationList.vue';
import ChatWindow       from './ChatWindow.vue';
import Pusher           from 'pusher-js';

const cfg = window.InboxConfig || {};

export default {
  name: 'InboxApp',
  components: { ConversationList, ChatWindow },

  data() {
    return {
      cfg,
      conversations: [],
      selectedConv:  null,
      messages:      [],
      filter:        'all',
      search:        '',
      sending:       false,
      toast:         null,
      pusher:        null,
    };
  },

  computed: {
    filteredConversations() {
      let list = this.conversations;
      if (this.filter !== 'all') list = list.filter(c => c.status === this.filter);
      if (this.search.trim()) {
        const q = this.search.toLowerCase();
        list = list.filter(c =>
          (c.contact_name || '').toLowerCase().includes(q) ||
          c.contact_phone.toLowerCase().includes(q)
        );
      }
      return list;
    },
  },

  async mounted() {
    await this.fetchConversations();
    this.initPusher();
  },

  beforeUnmount() {
    this.pusher?.disconnect();
  },

  methods: {
    // ── Fetch ─────────────────────────────────────────────────────
    async fetchConversations() {
      try {
        const res  = await this.get('/inbox/api/conversations');
        this.conversations = await res.json();
      } catch { this.toast_('Failed to load conversations', 'error'); }
    },

    async selectConversation(id) {
      if (this.selectedConv?.id === id) return;
      this.messages = [];
      try {
        const res  = await this.get(`/inbox/api/conversations/${id}/messages`);
        const data = await res.json();
        this.messages     = data.messages;
        this.selectedConv = data.conversation;
        this.patchConv(data.conversation);

        // Send read receipt for the last incoming message
        const lastIn = [...data.messages].reverse().find(m => m.direction === 'incoming' && m.wa_message_id);
        if (lastIn) this.markRead(id, lastIn.wa_message_id);
      } catch { this.toast_('Failed to load messages', 'error'); }
    },

    // ── Text ──────────────────────────────────────────────────────
    async sendText(text) {
      if (!this.selectedConv || this.sending) return;
      this.sending = true;
      try {
        const res  = await this.post(`/inbox/api/conversations/${this.selectedConv.id}/send`,
          { message: text });
        const data = await res.json();
        if (!res.ok) { this.toast_(data.error || 'Send failed', 'error'); return; }
        this.messages.push(data.message);
        this.selectedConv = data.conversation;
        this.patchConv(data.conversation);
      } catch { this.toast_('Send failed', 'error'); }
      finally { this.sending = false; }
    },

    // ── Media ─────────────────────────────────────────────────────
    async sendMedia(file, type, caption = '') {
      if (!this.selectedConv) return;
      this.sending = true;
      const form = new FormData();
      form.append('file', file);
      form.append('type', type);
      if (caption) form.append('caption', caption);

      try {
        const res = await fetch(`/inbox/api/conversations/${this.selectedConv.id}/send-media`, {
          method: 'POST',
          headers: { 'X-CSRF-TOKEN': cfg.csrfToken, 'X-Requested-With': 'XMLHttpRequest' },
          body: form,
        });
        const data = await res.json();
        if (!res.ok) { this.toast_(data.error || 'Upload failed', 'error'); return; }
        this.messages.push(data.message);
        this.selectedConv = data.conversation;
        this.patchConv(data.conversation);
      } catch { this.toast_('Upload failed', 'error'); }
      finally { this.sending = false; }
    },

    // ── Location ──────────────────────────────────────────────────
    async sendLocation(locData) {
      if (!this.selectedConv) return;
      this.sending = true;
      try {
        const res  = await this.post(`/inbox/api/conversations/${this.selectedConv.id}/send-location`, {
          latitude:  locData.lat,
          longitude: locData.lng,
          name:      locData.name,
          address:   locData.address,
        });
        const data = await res.json();
        if (!res.ok) { this.toast_(data.error || 'Failed', 'error'); return; }
        this.messages.push(data.message);
        this.selectedConv = data.conversation;
        this.patchConv(data.conversation);
      } catch { this.toast_('Failed to send location', 'error'); }
      finally { this.sending = false; }
    },

    // ── Mark read ─────────────────────────────────────────────────
    async markRead(convId, waMessageId) {
      try {
        await this.post(`/inbox/api/conversations/${convId}/mark-read`, { wa_message_id: waMessageId });
      } catch { /* non-critical */ }
    },

    // ── Typing ───────────────────────────────────────────────────
    async sendTyping(waMessageId) {
      if (!this.selectedConv) return;
      try {
        await this.post(`/inbox/api/conversations/${this.selectedConv.id}/typing`, { wa_message_id: waMessageId });
      } catch { /* non-critical */ }
    },

    // ── Status / Label ────────────────────────────────────────────
    async updateStatus(newStatus) {
      if (!this.selectedConv) return;
      try {
        const res  = await this.patch(`/inbox/api/conversations/${this.selectedConv.id}/status`, { status: newStatus });
        const data = await res.json();
        this.selectedConv = data.conversation;
        this.patchConv(data.conversation);
      } catch { this.toast_('Failed to update status', 'error'); }
    },

    async updateLabel(label) {
      if (!this.selectedConv) return;
      try {
        const res  = await this.patch(`/inbox/api/conversations/${this.selectedConv.id}/label`, { label });
        const data = await res.json();
        this.selectedConv = data.conversation;
        this.patchConv(data.conversation);
      } catch { this.toast_('Failed to update label', 'error'); }
    },

    // ── Pusher ────────────────────────────────────────────────────
    initPusher() {
      if (!cfg.pusherKey) return;
      this.pusher = new Pusher(cfg.pusherKey, { cluster: cfg.pusherCluster });
      const ch    = this.pusher.subscribe(`inbox-${cfg.userId}`);

      ch.bind('message.received', ({ conversation, message }) => {
        if (this.selectedConv?.id === conversation.id) {
          this.messages.push(message);
          this.selectedConv = { ...conversation, unread_count: 0 };
          this.patchConv(this.selectedConv);
          // Send read receipt automatically
          if (message.wa_message_id) this.markRead(conversation.id, message.wa_message_id);
        } else {
          this.patchConv(conversation);
        }
        this.moveTop(conversation.id);
      });
    },

    // ── Helpers ───────────────────────────────────────────────────
    patchConv(updated) {
      const idx = this.conversations.findIndex(c => c.id === updated.id);
      if (idx !== -1) this.conversations.splice(idx, 1, updated);
      else this.conversations.unshift(updated);
    },
    moveTop(id) {
      const idx = this.conversations.findIndex(c => c.id === id);
      if (idx > 0) this.conversations.unshift(...this.conversations.splice(idx, 1));
    },
    toast_(text, type = 'info') {
      this.toast = { text, type };
      setTimeout(() => { this.toast = null; }, 3500);
    },

    // Fetch helpers
    get(url) {
      return fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' } });
    },
    post(url, body) {
      return fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': cfg.csrfToken, 'X-Requested-With': 'XMLHttpRequest' },
        body: JSON.stringify(body),
      });
    },
    patch(url, body) {
      return fetch(url, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': cfg.csrfToken, 'X-Requested-With': 'XMLHttpRequest' },
        body: JSON.stringify(body),
      });
    },
  },
};
</script>

<style scoped>
.inbox-root {
  display: flex; height: 100%; width: 100%;
  background: #0b141a; color: #e9edef;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  overflow: hidden;
}

/* ── Thin nav ─────────────────────────────────────────────────── */
.inbox-nav {
  width: 60px; min-width: 60px;
  background: #111b21;
  border-right: 1px solid #2a3942;
  display: flex; flex-direction: column;
  align-items: center; padding: 10px 0 12px; gap: 4px;
}
.nav-logo { margin-bottom: 8px; }
.logo-img { width: 32px; height: 32px; object-fit: contain; border-radius: 6px; }

.nav-icon {
  width: 40px; height: 40px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  color: #8696a0; font-size: 15px; cursor: pointer;
  text-decoration: none; transition: .15s; border: none; background: transparent;
  position: relative;
}
.nav-icon:hover  { background: #2a3942; color: #e9edef; }
.nav-icon.active { background: #25d366; color: #000; }

.nav-spacer { flex: 1; }
.wa-status-dot {
  width: 10px; height: 10px; border-radius: 50%; margin: 4px 0;
}
.wa-status-dot.on  { background: #25d366; box-shadow: 0 0 6px #25d366; }
.wa-status-dot.off { background: #ef4444; }

.logout-btn:hover { background: rgba(239,68,68,.15); color: #f87171; }

/* ── Toast ────────────────────────────────────────────────────── */
.toast {
  position: fixed; bottom: 20px; right: 20px;
  padding: 10px 18px; border-radius: 10px;
  font-size: 13px; font-weight: 500; z-index: 9999;
  animation: toastIn .2s ease;
}
.toast.info  { background: #1b2e24; color: #25d366; border: 1px solid rgba(37,211,102,.3); }
.toast.error { background: #2e1b1b; color: #f87171; border: 1px solid rgba(248,113,113,.3); }
@keyframes toastIn { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
</style>
