import { createContext, useContext, useEffect, useState, useCallback } from 'react'
import useAuthStore from '../store/authStore'
import useNotificationSettingsStore from '../store/notificationSettingsStore'
import client from '../api/client'

const NotificationContext = createContext(null)

export function useNotifications() {
  return useContext(NotificationContext)
}

// ─── Per-type visual config ────────────────────────────────────────────────

const TYPE_THEME = {
  manager: {
    bg: '#1e1b4b', border: '#6366f1', ackBg: '#4f46e5',
    labelColor: '#a5b4fc', icon: '📢',
  },
  kds_order_done: {
    bg: '#052e16', border: '#22c55e', ackBg: '#16a34a',
    labelColor: '#86efac', icon: '✅',
  },
  kds_item_done: {
    bg: '#052e16', border: '#4ade80', ackBg: '#15803d',
    labelColor: '#86efac', icon: '🍽️',
  },
  kds_call_order: {
    bg: '#2d1505', border: '#f97316', ackBg: '#ea580c',
    labelColor: '#fed7aa', icon: '🔔',
  },
  kds_call_general: {
    bg: '#2d1505', border: '#f59e0b', ackBg: '#d97706',
    labelColor: '#fde68a', icon: '👋',
  },
}

function getTheme(messageType) {
  return TYPE_THEME[messageType] || TYPE_THEME.manager
}

function isManagerMessage(msg) {
  return msg.message_type === 'manager' || !msg.message_type
}

// ─── Rich body renderer — highlights #order, table name, and zone after " - " ─

const HIGHLIGHT = { color: '#7dd3fc', fontWeight: 800 }  // light blue bold

function RichBody({ text }) {
  if (!text) return null
  // Highlighted tokens:
  //   #digits          → order number
  //   τραπέζι <word>   → keep "τραπέζι " plain, highlight the word after it
  //   " - " <rest>     → keep " - " plain, highlight everything after
  const parts = []
  const re = /(#\d+|τραπέζι \S+| - .+$)/g
  let last = 0
  let m
  while ((m = re.exec(text)) !== null) {
    if (m.index > last) parts.push({ t: 'plain', v: text.slice(last, m.index) })
    const v = m[0]
    if (v.startsWith('τραπέζι ')) {
      parts.push({ t: 'plain', v: 'τραπέζι ' })
      parts.push({ t: 'hi',    v: v.slice(8) })
    } else if (v.startsWith(' - ')) {
      parts.push({ t: 'plain', v: ' - ' })
      parts.push({ t: 'hi',    v: v.slice(3) })
    } else {
      parts.push({ t: 'hi', v })
    }
    last = m.index + v.length
  }
  if (last < text.length) parts.push({ t: 'plain', v: text.slice(last) })

  return (
    <>
      {parts.map((p, i) =>
        p.t === 'hi'
          ? <span key={i} style={HIGHLIGHT}>{p.v}</span>
          : <span key={i}>{p.v}</span>
      )}
    </>
  )
}

// ─── Persistent banner (one message at a time, stacked) ─────────────────────

function NotificationBanner({ message, onAck, autoDismiss }) {
  const tableIds = (() => { try { return JSON.parse(message.table_ids || '[]') } catch { return [] } })()
  const theme = getTheme(message.message_type)

  useEffect(() => {
    if (!autoDismiss) return
    const t = setTimeout(() => onAck(message.id), 3000)
    return () => clearTimeout(t)
  }, [message.id, autoDismiss, onAck])

  return (
    <div style={{
      display: 'flex', alignItems: 'flex-start', gap: 12,
      background: theme.bg, border: `1px solid ${theme.border}`,
      borderRadius: 14, padding: '12px 14px',
      boxShadow: '0 8px 24px rgba(0,0,0,0.4)',
      animation: 'slideIn 0.25s ease',
    }}>
      <span style={{ fontSize: 22, flexShrink: 0 }}>{theme.icon}</span>
      <div style={{ flex: 1, minWidth: 0 }}>
        {(message.kds_zone || message.sender_name) && (
          <div style={{ fontSize: 11, fontWeight: 700, color: theme.labelColor, marginBottom: 2, textTransform: 'uppercase', letterSpacing: 0.5 }}>
            {message.kds_zone || message.sender_name}
          </div>
        )}
        <div style={{ fontSize: 15, fontWeight: 600, color: '#e2e8f0', lineHeight: 1.4 }}>
          <RichBody text={message.body} />
        </div>
        {tableIds.length > 0 && (
          <div style={{ fontSize: 12, color: '#94a3b8', marginTop: 4 }}>
            Τραπέζι{tableIds.length > 1 ? 'α' : ''}: {tableIds.join(', ')}
          </div>
        )}
      </div>
      <button
        onClick={() => onAck(message.id)}
        style={{
          flexShrink: 0, height: 32, padding: '0 12px',
          borderRadius: 8, border: 'none',
          background: theme.ackBg, color: 'white',
          fontSize: 12, fontWeight: 700, cursor: 'pointer',
        }}
      >OK ✓</button>
    </div>
  )
}

export function NotificationProvider({ children }) {
  const { token, user } = useAuthStore()
  const { popupMode, persistentPopup } = useNotificationSettingsStore()

  const [pendingMessages, setPendingMessages] = useState([])
  const [recentMessages, setRecentMessages] = useState([])

  // Messages to show as popup banners (filtered by popupMode)
  const popupMessages = pendingMessages.filter(msg => {
    if (popupMode === 'never') return false
    if (popupMode === 'manager_only') return isManagerMessage(msg)
    return true
  })

  const fetchUnread = useCallback(async () => {
    if (!token || !user) return
    try {
      const res = await client.get('/api/notifications/unread')
      setPendingMessages(res.data)
    } catch { /* offline or unauthenticated — swallow */ }
  }, [token, user?.id])

  const fetchRecent = useCallback(async () => {
    if (!token || !user) return
    try {
      const res = await client.get('/api/notifications/recent?limit=10')
      setRecentMessages(res.data)
    } catch { }
  }, [token, user?.id])

  // Initial load + 5s fallback poll (SSE is primary, poll is safety net)
  useEffect(() => {
    if (!token || !user) return
    fetchUnread()
    fetchRecent()
    const id = setInterval(fetchUnread, 5000)
    return () => clearInterval(id)
  }, [token, user?.id])

  // SSE message_sent events → add to pending without polling
  useEffect(() => {
    function onSSEEvent(e) {
      const { type, data } = e.detail
      if (type !== 'message_sent') return
      if (!user) return

      const targets = data.target_waiter_ids || []
      if (targets.length > 0 && !targets.includes(user.id)) return

      const msg = {
        id: data.id,
        sender_id: data.sender_id,
        sender_name: data.sender_name,
        body: data.body,
        table_ids: data.table_ids,
        message_type: data.message_type || 'manager',
        kds_zone: data.kds_zone || null,
        created_at: data.created_at,
        acked_by: [],
      }

      setRecentMessages(prev => {
        if (prev.find(m => m.id === msg.id)) return prev
        return [msg, ...prev].slice(0, 10)
      })

      // popupMode=never + not persistent → ACK immediately (silent delivery, no badge)
      if (popupMode === 'never' && !persistentPopup) {
        client.post(`/api/notifications/${msg.id}/ack`).catch(() => {})
        return
      }

      // All other cases: add to pending so bell badge shows and/or popup renders
      setPendingMessages(prev => {
        if (prev.find(m => m.id === msg.id)) return prev
        return [msg, ...prev]
      })
    }

    window.addEventListener('sse-event', onSSEEvent)
    return () => window.removeEventListener('sse-event', onSSEEvent)
  }, [user?.id, persistentPopup, popupMode])

  // Fallback: re-fetch unread when SSE reconnects
  useEffect(() => {
    function onSSEConnect() {
      fetchUnread()
      fetchRecent()
    }
    window.addEventListener('sse-reconnected', onSSEConnect)
    return () => window.removeEventListener('sse-reconnected', onSSEConnect)
  }, [fetchUnread, fetchRecent])

  async function ackMessage(messageId) {
    try {
      await client.post(`/api/notifications/${messageId}/ack`)
      setPendingMessages(prev => prev.filter(m => m.id !== messageId))
      fetchRecent()
    } catch { }
  }

  // Mark all pending as read (used when notification panel opens in never-popup mode)
  async function ackAll() {
    const ids = [...pendingMessages.map(m => m.id)]
    setPendingMessages([])
    await Promise.allSettled(ids.map(id => client.post(`/api/notifications/${id}/ack`)))
    fetchRecent()
  }

  const unreadCount = pendingMessages.length

  return (
    <NotificationContext.Provider value={{ pendingMessages, recentMessages, unreadCount, ackMessage, ackAll, fetchRecent, fetchUnread }}>
      {children}

      {/* Floating banner stack — only when popupMode allows */}
      {popupMessages.length > 0 && (
        <div style={{
          position: 'fixed', top: 64, left: 0, right: 0, zIndex: 9999,
          padding: '0 12px',
          display: 'flex', flexDirection: 'column', gap: 8,
          pointerEvents: 'none',
        }}>
          <style>{`@keyframes slideIn { from { transform: translateY(-16px); opacity: 0 } to { transform: translateY(0); opacity: 1 } }`}</style>
          {popupMessages.slice(0, 3).map(msg => (
            <div key={msg.id} style={{ pointerEvents: 'all' }}>
              <NotificationBanner
                message={msg}
                onAck={ackMessage}
                autoDismiss={!persistentPopup}
              />
            </div>
          ))}
          {popupMessages.length > 3 && (
            <div style={{
              textAlign: 'center', fontSize: 12, color: '#94a3b8',
              pointerEvents: 'all',
            }}>
              +{popupMessages.length - 3} ακόμα μηνύματα
            </div>
          )}
        </div>
      )}
    </NotificationContext.Provider>
  )
}
