// frontend/src/pages/crm/comms/CommsPage.jsx
// Unified communications log across all channel types.
// Timeline — tall cards, hover-overlay action panel, colored type/direction icons.

import { useState, useEffect, useCallback, useRef } from 'react'
import { Link } from 'react-router-dom'
import api from '@/lib/api'
import { useAuth } from '@/hooks/useAuth'
import { useToast } from '@/components/ui/Toast'
import PageHeader from '@/components/ui/PageHeader'
import Button from '@/components/ui/Button'
import Spinner from '@/components/ui/Spinner'
import SearchBar from '@/components/ui/SearchBar'
import Select from '@/components/ui/Select'
import Pagination from '@/components/ui/Pagination'
import ConfirmDialog from '@/components/ui/ConfirmDialog'
import IconButtonGroup from '@/components/ui/IconButtonGroup'
import MailViewModal from '@/modals/crm/MailViewModal'
import ComposeEmailModal from '@/modals/crm/ComposeEmailModal'
import EditCommsEntryModal from '@/modals/crm/EditCommsEntryModal'
import { fmtRelative, fmtDateTime as fmtDateTimeCentral } from '@/lib/formatters'

// ─── constants ───────────────────────────────────────────────────────────────

const COMMS_TYPES = ['email', 'whatsapp', 'call', 'sms', 'note', 'in_person']
const DIRECTIONS  = ['inbound', 'outbound', 'internal']

// Each type: icon path + tint color (used as CSS filter tint via wrapper)
const TYPE_META = {
  email:     { label: 'Email',     icon: '/src/assets/comms/email.svg',    color: 'var(--color-info)',    bg: 'var(--color-info-bg)' },
  whatsapp:  { label: 'WhatsApp',  icon: '/src/assets/comms/whatsapp.svg', color: 'var(--color-success)', bg: 'var(--color-success-bg)' },
  call:      { label: 'Call',      icon: '/src/assets/comms/call.svg',     color: 'var(--color-warning)', bg: 'var(--color-warning-bg)' },
  sms:       { label: 'SMS',       icon: '/src/assets/comms/sms.svg',      color: 'var(--color-warning)', bg: 'var(--color-warning-bg)' },
  note:      { label: 'Note',      icon: '/src/assets/comms/note.svg',     color: 'var(--color-text-muted)', bg: 'var(--color-bg-elevated)' },
  in_person: { label: 'In person', icon: '/src/assets/comms/inperson.svg', color: 'var(--color-primary)', bg: 'var(--color-primary-subtle)' },
}

const DIR_META = {
  inbound:  { label: 'Inbound',  icon: '/src/assets/comms/inbound.svg',  color: 'var(--color-success)' },
  outbound: { label: 'Outbound', icon: '/src/assets/comms/outbound.svg', color: 'var(--color-info)' },
  internal: { label: 'Internal', icon: '/src/assets/comms/internal.svg', color: 'var(--color-text-muted)' },
}

// ─── helpers ────────────────────────────────────────────────────────────────

function formatRelative(val) { return fmtRelative(val) }
function formatFull(val) { return fmtDateTimeCentral(val) }

// ─── SVGs ────────────────────────────────────────────────────────────────────

const IconRefresh = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M23 4v6h-6"/><path d="M1 20v-6h6"/>
    <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>
  </svg>
)
const IconDownload = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
    <polyline points="7 10 12 15 17 10"/>
    <line x1="12" y1="15" x2="12" y2="3"/>
  </svg>
)
const IconExpand  = () => <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M16 8L21 3M21 3H16M21 3V8M8 8L3 3M3 3L3 8M3 3L8 3M8 16L3 21M3 21H8M3 21L3 16M16 16L21 21M21 21V16M21 21H16"/></svg>
const IconReply   = () => <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 17 4 12 9 7"/><path d="M20 18v-2a4 4 0 0 0-4-4H4"/></svg>
const IconEdit    = () => <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20,16v4a2,2,0,0,1-2,2H4a2,2,0,0,1-2-2V6A2,2,0,0,1,4,4H8"/><polygon points="12.5 15.8 22 6.2 17.8 2 8.3 11.5 8 16 12.5 15.8"/></svg>
const IconDelete  = () => <svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M5.755,20.283,4,8H20L18.245,20.283A2,2,0,0,1,16.265,22H7.735A2,2,0,0,1,5.755,20.283ZM21,4H16V3a1,1,0,0,0-1-1H9A1,1,0,0,0,8,3V4H3A1,1,0,0,0,3,6H21a1,1,0,0,0,0-2Z"/></svg>

// ─── TypeIcon ─────────────────────────────────────────────────────────────────

function TypeIconBadge({ type }) {
  const meta = TYPE_META[type] || TYPE_META.note
  return (
    <div style={{
      width: 48, height: 48,
      borderRadius: 'var(--radius-lg)',
      backgroundColor: meta.bg,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0,
    }}>
      <img
        src={meta.icon}
        width={24} height={24}
        alt={meta.label}
        style={{
          filter: 'brightness(0) invert(1)',
          opacity: 0.9,
        }}
      />
    </div>
  )
}

function DirBadge({ direction }) {
  const meta = DIR_META[direction] || DIR_META.internal
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
      <img
        src={meta.icon}
        width={13} height={13}
        alt={meta.label}
        style={{ filter: 'brightness(0) invert(1)', opacity: 0.55, flexShrink: 0 }}
      />
      <span style={{ fontSize: 'var(--font-size-xs)', color: meta.color, textTransform: 'capitalize', fontWeight: 'var(--font-weight-medium)' }}>
        {meta.label}
      </span>
    </div>
  )
}

function TimelineDot({ type }) {
  const meta = TYPE_META[type] || TYPE_META.note
  return (
    <div style={{
      width: 12, height: 12, borderRadius: 'var(--radius-full)',
      backgroundColor: meta.color,
      border: '2px solid var(--color-bg-base)',
      boxShadow: `0 0 0 2px ${meta.color}33`,
      flexShrink: 0, zIndex: 1,
    }} />
  )
}

// ─── CommsEntryCard ──────────────────────────────────────────────────────────

function CommsEntryCard({ entry, customer, expanded, canEdit, onToggle, onDelete, onEdit, onView, onReply }) {
  const [hovered, setHovered] = useState(false)
  const meta = TYPE_META[entry.type] || { label: entry.type, color: 'var(--color-text-muted)' }

  return (
    <div
      className="comms-card"
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
      style={{
        backgroundColor: 'var(--color-bg-surface)',
        border: '1px solid var(--color-border)',
        borderRadius: 'var(--radius-lg)',
        overflow: 'hidden',
        transition: 'border-color 0.15s',
        position: 'relative',
      }}
    >
      {/* ── Hover overlay: gradient + action panel — collapsed only ── */}
      {hovered && !expanded && (
        <div style={{
          position: 'absolute', inset: 0,
          pointerEvents: 'none',
          zIndex: 2,
          background: 'linear-gradient(to left, rgba(10,14,20,0.92) 0%, rgba(16,20,26,0.5) 30%, transparent 52%)',
          borderRadius: 'inherit',
        }}>
          <div style={{
            position: 'absolute', right: 28, top: '50%', transform: 'translateY(-50%)',
            display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 14,
            pointerEvents: 'all',
          }}>

            {/* Col 1: date info */}
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 3 }}>
              <span style={{ fontSize: 11, color: 'rgba(255,255,255,0.5)', whiteSpace: 'nowrap', lineHeight: 1.4 }}>
                {entry.direction === 'inbound' ? 'Received' : entry.direction === 'outbound' ? 'Sent' : 'Logged'} via {meta.label}
              </span>
              <span style={{ fontSize: 11, color: 'rgba(255,255,255,0.88)', whiteSpace: 'nowrap', lineHeight: 1.4 }}>
                {formatFull(entry.occurred_at)}
              </span>
            </div>

            {/* Divider */}
            <div style={{ width: 1, alignSelf: 'stretch', backgroundColor: 'rgba(255,255,255,0.16)', flexShrink: 0, margin: '4px 0' }} />

            {/* Col 2: View / Reply */}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              <div style={{ minWidth: 112 }}>
                <Button
                  variant="secondary"
                  size="md"
                  disabled={entry.type !== 'email'}
                  onClick={(e) => { e.stopPropagation(); if (entry.type === 'email') onView(entry) }}
                  style={{ width: '100%', justifyContent: 'center' }}
                >
                  <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconExpand />Full view</span>
                </Button>
              </div>
              <div style={{ minWidth: 112 }}>
                <Button
                  variant="info"
                  size="md"
                  onClick={(e) => { e.stopPropagation(); onReply(entry.from_addr || '', entry.mailbox_account) }}
                  style={{ width: '100%', justifyContent: 'center' }}
                >
                  <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconReply />Reply</span>
                </Button>
              </div>
            </div>

            {/* Col 3: Edit / Delete (canEdit only) */}
            {canEdit && (
              <>
                <div style={{ width: 1, alignSelf: 'stretch', backgroundColor: 'rgba(255,255,255,0.16)', flexShrink: 0, margin: '4px 0' }} />
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  <div style={{ minWidth: 112 }}>
                    <Button
                      variant="warning"
                      size="md"
                      onClick={(e) => { e.stopPropagation(); onEdit(entry) }}
                      style={{ width: '100%', justifyContent: 'center' }}
                    >
                      <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconEdit />Edit</span>
                    </Button>
                  </div>
                  <div style={{ minWidth: 112 }}>
                    <Button
                      variant="danger"
                      size="md"
                      onClick={(e) => { e.stopPropagation(); onDelete(entry.id) }}
                      style={{ width: '100%', justifyContent: 'center' }}
                    >
                      <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconDelete />Delete</span>
                    </Button>
                  </div>
                </div>
              </>
            )}
          </div>
        </div>
      )}

      {/* ── Card header ── */}
      <div
        onClick={() => entry.body && onToggle(entry.id)}
        style={{
          display: 'grid',
          gridTemplateColumns: '48px 1fr auto',
          gap: 'var(--space-4)',
          padding: 'var(--space-5)',
          cursor: entry.body ? 'pointer' : 'default',
          alignItems: 'flex-start',
        }}
      >
        {/* Type icon badge */}
        <TypeIconBadge type={entry.type} />

        {/* Center */}
        <div style={{ minWidth: 0 }}>
          {/* type · direction · customer */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', flexWrap: 'wrap', marginBottom: 'var(--space-1)' }}>
            <span style={{
              fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-semibold)',
              color: meta.color,
            }}>
              {meta.label}
            </span>
            <span style={{ color: 'var(--color-text-primary)', fontSize: 'var(--font-size-sm)', lineHeight: 1 }}>·</span>
            <DirBadge direction={entry.direction} />
            {customer ? (
              <>
                <span style={{ color: 'var(--color-text-primary)', fontSize: 'var(--font-size-sm)', lineHeight: 1 }}>·</span>
                <Link
                  to={`/crm/customers/${customer.id}`}
                  onClick={(e) => e.stopPropagation()}
                  style={{ color: 'var(--color-text-accent)', fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-medium)', textDecoration: 'none' }}
                >
                  {customer.name}{customer.surname ? ` ${customer.surname}` : ''}
                  {customer.organization ? ` · ${customer.organization}` : ''}
                </Link>
              </>
            ) : (entry.from_addr || entry.to_addr) ? (
              <>
                <span style={{ color: 'var(--color-text-primary)', fontSize: 'var(--font-size-sm)', lineHeight: 1 }}>·</span>
                <span style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)' }}>
                  {entry.direction === 'outbound' ? (entry.to_addr || entry.from_addr) : (entry.from_addr || entry.to_addr)}
                </span>
              </>
            ) : null}
          </div>

          {/* Subject */}
          {entry.subject && (
            <p style={{ margin: '0 0 var(--space-1)', color: 'var(--color-text-primary)', fontWeight: 'var(--font-weight-medium)', fontSize: 'var(--font-size-base)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {entry.subject}
            </p>
          )}

          {/* Body preview (collapsed) */}
          {entry.body && !expanded && (
            <p style={{ margin: 0, color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              {entry.body.replace(/<[^>]*>/g, '').slice(0, 140)}
            </p>
          )}

          {/* Logged by */}
          {entry.logged_by && (
            <span style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-more-muted)', display: 'block', marginTop: 'var(--space-1)' }}>
              by {entry.logged_by}
            </span>
          )}
        </div>

        {/* Right: time only — no chevron */}
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 'var(--space-2)', flexShrink: 0 }}>
          <span
            title={formatFull(entry.occurred_at)}
            style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)', whiteSpace: 'nowrap' }}
          >
            {formatRelative(entry.occurred_at)}
          </span>
          {entry.attachments?.length > 0 && (
            <span style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)' }}>
              {entry.attachments.length} file{entry.attachments.length !== 1 ? 's' : ''}
            </span>
          )}
        </div>
      </div>

      {/* Expanded body */}
      {expanded && entry.body && (
        <div style={{ borderTop: '1px solid var(--color-border)', padding: 'var(--space-5)', backgroundColor: 'var(--color-bg-void)' }}>
          <pre style={{
            margin: 0, color: 'var(--color-text-primary)', fontSize: 'var(--font-size-base)',
            lineHeight: 1.7, whiteSpace: 'pre-wrap', fontFamily: 'var(--font-family-base)',
            maxHeight: 400, overflowY: 'auto',
          }}>
            {entry.body.replace(/<[^>]*>/g, '')}
          </pre>
        </div>
      )}

      {/* ── Expanded action bar ── */}
      {expanded && (
        <div style={{
          borderTop: '1px solid var(--color-border)',
          padding: 'var(--space-3) var(--space-5)',
          display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: 'var(--space-4)',
          backgroundColor: 'var(--color-bg-surface)',
        }}>
          {/* Info */}
          <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)', whiteSpace: 'nowrap' }}>
            {entry.direction === 'inbound' ? 'Received' : entry.direction === 'outbound' ? 'Sent' : 'Logged'} via {meta.label}
            {' · '}
            {formatFull(entry.occurred_at)}
          </span>

          {/* Divider */}
          <div style={{ width: 1, alignSelf: 'stretch', backgroundColor: 'var(--color-border-strong)', flexShrink: 0 }} />

          {/* Actions */}
          <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)' }}>
            <Button
              variant="secondary"
              size="md"
              disabled={entry.type !== 'email'}
              onClick={(e) => { e.stopPropagation(); if (entry.type === 'email') onView(entry) }}
            >
              <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconExpand />Full view</span>
            </Button>
            <Button
              variant="info"
              size="md"
              onClick={(e) => { e.stopPropagation(); onReply(entry.from_addr || '', entry.mailbox_account) }}
            >
              <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconReply />Reply</span>
            </Button>
            {canEdit && (
              <>
                <Button
                  variant="warning"
                  size="md"
                  onClick={(e) => { e.stopPropagation(); onEdit(entry) }}
                >
                  <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconEdit />Edit</span>
                </Button>
                <Button
                  variant="danger"
                  size="md"
                  onClick={(e) => { e.stopPropagation(); onDelete(entry.id) }}
                >
                  <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconDelete />Delete</span>
                </Button>
              </>
            )}
          </div>
        </div>
      )}
    </div>
  )
}

// ─── main ─────────────────────────────────────────────────────────────────────

const PAGE_SIZE_OPTIONS = [10, 20, 50, 100]

export default function CommsPage() {
  const { hasPermission } = useAuth()
  const { toast } = useToast()
  const canEdit = hasPermission('crm', 'edit')

  const [entries, setEntries]     = useState([])
  const [customers, setCustomers] = useState({})
  const [loading, setLoading]     = useState(true)
  const [error, setError]         = useState('')

  const [typeFilter, setTypeFilter] = useState('')
  const [dirFilter, setDirFilter]   = useState('')
  const [custFilter, setCustFilter] = useState('')
  const [search, setSearch]         = useState('')

  const [page, setPage]         = useState(1)
  const [pageSize, setPageSize] = useState(20)

  const [expandedId, setExpandedId] = useState(null)
  const [deleteId, setDeleteId]     = useState(null)
  const [deleting, setDeleting]     = useState(false)
  const [editEntry, setEditEntry]   = useState(null)

  const [custPickerOpen, setCustPickerOpen] = useState(false)
  const [custSearch, setCustSearch]         = useState('')
  const custSearchRef = useRef(null)

  const [syncing, setSyncing] = useState(false)

  const [viewEntry, setViewEntry]             = useState(null)
  const [composeOpen, setComposeOpen]         = useState(false)
  const [composeTo, setComposeTo]             = useState('')
  const [composeFromAccount, setComposeFromAccount] = useState('')

  // ── data ──
  const loadAll = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const params = new URLSearchParams({ limit: 500 })
      if (typeFilter) params.set('type', typeFilter)
      if (dirFilter)  params.set('direction', dirFilter)
      const [commsData, custsData] = await Promise.all([
        api.get(`/crm/comms/all?${params}`),
        api.get('/crm/customers'),
      ])
      setEntries(commsData.entries || [])
      const map = {}
      for (const c of custsData.customers || []) map[c.id] = c
      setCustomers(map)
    } catch (err) {
      setError(err.message)
    } finally {
      setLoading(false)
    }
  }, [typeFilter, dirFilter])

  useEffect(() => { loadAll() }, [loadAll])
  useEffect(() => { setPage(1) }, [typeFilter, dirFilter, custFilter, search])

  useEffect(() => {
    if (custPickerOpen) {
      setCustSearch('')
      setTimeout(() => custSearchRef.current?.focus(), 60)
    }
  }, [custPickerOpen])

  useEffect(() => {
    if (!custPickerOpen) return
    const h = (e) => { if (e.key === 'Escape') setCustPickerOpen(false) }
    window.addEventListener('keydown', h)
    return () => window.removeEventListener('keydown', h)
  }, [custPickerOpen])

  const syncEmails = async () => {
    setSyncing(true)
    try {
      const data = await api.post('/crm/comms/email/sync', {})
      toast.success('Synced', `${data.new_count} new email${data.new_count !== 1 ? 's' : ''} pulled.`)
      await loadAll()
    } catch (err) { toast.danger('Sync failed', err.message) }
    finally { setSyncing(false) }
  }

  const handleDelete = async () => {
    if (!deleteId) return
    setDeleting(true)
    try {
      await api.delete(`/crm/comms/${deleteId}`)
      toast.success('Deleted', 'Communication entry removed.')
      setDeleteId(null); await loadAll()
    } catch (err) { toast.danger('Delete failed', err.message) }
    finally { setDeleting(false) }
  }

  const openReply = (toAddr, sourceAccount = '') => {
    setViewEntry(null); setComposeTo(toAddr || ''); setComposeFromAccount(sourceAccount || ''); setComposeOpen(true)
  }

  // ── filtering ──
  const q = search.trim().toLowerCase()

  const customerOptions = Object.values(customers).sort((a, b) =>
    (a.name || '').localeCompare(b.name || '')
  )
  const filteredCustOptions = custSearch.trim()
    ? customerOptions.filter((c) => {
        const t = custSearch.trim().toLowerCase()
        return (
          (c.name || '').toLowerCase().includes(t) ||
          (c.surname || '').toLowerCase().includes(t) ||
          (c.organization || '').toLowerCase().includes(t)
        )
      })
    : customerOptions

  const filtered = entries
    .filter((e) => !custFilter || e.customer_id === custFilter)
    .filter((e) => {
      if (!q) return true
      const cust = customers[e.customer_id]
      return (
        (e.subject || '').toLowerCase().includes(q) ||
        (e.body || '').toLowerCase().includes(q) ||
        (cust?.name || '').toLowerCase().includes(q) ||
        (cust?.organization || '').toLowerCase().includes(q)
      )
    })
    .sort((a, b) => {
      const ta = Date.parse(a?.occurred_at || a?.created_at || '') || 0
      const tb = Date.parse(b?.occurred_at || b?.created_at || '') || 0
      return tb - ta
    })

  const totalPages = Math.max(1, Math.ceil(filtered.length / (pageSize || filtered.length)))
  const safePage   = Math.min(page, totalPages)
  const paged      = pageSize > 0 ? filtered.slice((safePage - 1) * pageSize, safePage * pageSize) : filtered

  const selectedCustLabel = custFilter && customers[custFilter]
    ? `${customers[custFilter].name}${customers[custFilter].organization ? ` — ${customers[custFilter].organization}` : ''}`
    : 'All customers'

  const hasFilters = typeFilter || dirFilter || custFilter || search

  return (
    <>
      <style>{`
        .comms-card:hover { border-color: var(--color-border-strong) !important; }
        .cust-picker-row {
          padding: 10px var(--space-4);
          font-size: var(--font-size-sm);
          cursor: pointer;
          color: var(--color-text-primary);
          transition: background 0.1s;
          font-family: var(--font-family-base);
        }
        .cust-picker-row:hover { background: var(--color-bg-elevated); }
        .cust-picker-row.selected-cust { color: var(--color-text-accent); font-weight: var(--font-weight-semibold); background: var(--color-primary-subtle); }
      `}</style>

      <div className="page-wrapper">
        <PageHeader title="Comms Log" subtitle="All customer interactions across every channel">
          <IconButtonGroup
            size="md"
            buttons={[
              { label: 'Refresh',     icon: <IconRefresh />,    onClick: loadAll,    loading: loading && !syncing },
              { label: 'Sync emails', icon: <IconDownload />,   onClick: syncEmails, loading: syncing },
            ]}
          />
        </PageHeader>

        {/* Filter bar */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)', flexWrap: 'wrap' }}>

          <div style={{ minWidth: 148 }}>
            <Select value={typeFilter} onChange={(e) => setTypeFilter(e.target.value)} placeholder="All types">
              <option value="">All types</option>
              {COMMS_TYPES.map((t) => <option key={t} value={t}>{TYPE_META[t]?.label || t}</option>)}
            </Select>
          </div>

          <div style={{ minWidth: 148 }}>
            <Select value={dirFilter} onChange={(e) => setDirFilter(e.target.value)} placeholder="All directions">
              <option value="">All directions</option>
              {DIRECTIONS.map((d) => <option key={d} value={d}>{DIR_META[d]?.label || d}</option>)}
            </Select>
          </div>

          {/* Customer picker — styled exactly like Select trigger */}
          <button
            onClick={() => setCustPickerOpen(true)}
            className="input select-trigger"
            style={{
              minWidth: 148,
              maxWidth: 200,
              width: 180,
              color: custFilter ? 'var(--color-text-accent)' : 'var(--color-text-muted)',
              fontWeight: custFilter ? 'var(--font-weight-semibold)' : 'var(--font-weight-normal)',
            }}
          >
            <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1 }}>
              {selectedCustLabel}
            </span>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0, opacity: 0.5 }}>
              <polyline points="6 9 12 15 18 9"/>
            </svg>
          </button>

          <div style={{ flex: 1, minWidth: 200, maxWidth: 320 }}>
            <SearchBar value={search} onChange={setSearch} placeholder="Search communications…" />
          </div>

          {hasFilters && (
            <Button variant="ghost" size="sm" onClick={() => { setTypeFilter(''); setDirFilter(''); setCustFilter(''); setSearch('') }}>
              Clear filters
            </Button>
          )}
        </div>

        {/* Error */}
        {error && (
          <div style={{
            padding: 'var(--space-3) var(--space-4)',
            backgroundColor: 'var(--color-danger-bg)',
            border: '1px solid var(--color-danger)',
            borderRadius: 'var(--radius-lg)',
            color: 'var(--color-danger)',
            fontSize: 'var(--font-size-sm)',
          }}>
            {error}
          </div>
        )}

        {/* Content area: count/pagination + list, tightly grouped */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-3)', marginTop: 'calc(var(--space-3) - var(--space-6))' }}>

          {/* Count + pagination row */}
          {!loading && !error && (
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 'var(--space-4)' }}>
              <p style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)', margin: 0, paddingTop: 'var(--space-4)', paddingLeft: 'calc(12px + var(--space-4))' }}>
                {filtered.length} entr{filtered.length !== 1 ? 'ies' : 'y'}{hasFilters ? ' (filtered)' : ''}
              </p>
              <Pagination
                page={safePage}
                pageSize={pageSize}
                total={filtered.length}
                onPageChange={setPage}
                onSizeChange={(s) => { setPageSize(s); setPage(1) }}
                pageSizes={PAGE_SIZE_OPTIONS}
              />
            </div>
          )}

          {/* Loading */}
          {loading ? (
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 'var(--space-16)', gap: 'var(--space-3)' }}>
              <Spinner size="md" />
              <span style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)' }}>Loading communications…</span>
            </div>

          ) : filtered.length === 0 ? (
            <div style={{
              display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--space-4)',
              padding: 'var(--space-16)',
              backgroundColor: 'var(--color-bg-surface)',
              border: '1px solid var(--color-border)',
              borderRadius: 'var(--radius-xl)',
            }}>
              <img src="/src/assets/comms/mail.svg" width={44} height={44} alt="" style={{ opacity: 0.22, filter: 'brightness(0) invert(1)' }} />
              <p style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-base)', margin: 0 }}>
                {hasFilters ? 'No communications match your filters.' : 'No communications logged yet.'}
              </p>
              {hasFilters && (
                <Button variant="secondary" size="sm" onClick={() => { setTypeFilter(''); setDirFilter(''); setCustFilter(''); setSearch('') }}>
                  Clear filters
                </Button>
              )}
            </div>

          ) : (
            /* Timeline */
            <div style={{ display: 'flex', flexDirection: 'column' }}>
              {paged.map((entry, idx) => (
                <div
                  key={entry.id}
                  style={{ display: 'flex', gap: 'var(--space-4)', alignItems: 'flex-start', position: 'relative', paddingBottom: 'var(--space-4)' }}
                >
                  {/* Timeline column */}
                  <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', width: 12, flexShrink: 0, paddingTop: 18, alignSelf: 'stretch' }}>
                    <TimelineDot type={entry.type} />
                    {idx < paged.length - 1 && (
                      <div style={{
                        position: 'absolute', top: 36, bottom: -16, left: '50%', transform: 'translateX(-50%)',
                        width: 2,
                        backgroundColor: (TYPE_META[entry.type] || TYPE_META.note).color,
                        WebkitMaskImage: 'linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.3) 65%, transparent 100%)',
                        maskImage: 'linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.3) 65%, transparent 100%)',
                      }} />
                    )}
                  </div>

                  {/* Card */}
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <CommsEntryCard
                      entry={entry}
                      customer={customers[entry.customer_id] || null}
                      expanded={expandedId === entry.id}
                      canEdit={canEdit}
                      onToggle={(id) => setExpandedId((prev) => prev === id ? null : id)}
                      onDelete={(id) => setDeleteId(id)}
                      onEdit={(entry) => setEditEntry(entry)}
                      onView={(e) => setViewEntry(e)}
                      onReply={openReply}
                    />
                  </div>
                </div>
              ))}
            </div>
          )}

        </div>

      </div>

      {/* Customer picker overlay */}
      {custPickerOpen && (
        <div
          style={{ position: 'fixed', inset: 0, zIndex: 500, backgroundColor: 'rgba(0,0,0,0.45)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
          onClick={() => setCustPickerOpen(false)}
        >
          <div
            style={{
              backgroundColor: 'var(--color-bg-surface)',
              border: '1px solid var(--color-border-strong)',
              borderRadius: 'var(--radius-xl)',
              width: 380, maxHeight: 480,
              display: 'flex', flexDirection: 'column',
              boxShadow: 'var(--shadow-lg)',
              overflow: 'hidden',
            }}
            onClick={(e) => e.stopPropagation()}
          >
            <div style={{ padding: 'var(--space-3) var(--space-4)', borderBottom: '1px solid var(--color-border)' }}>
              <input
                ref={custSearchRef}
                value={custSearch}
                onChange={(e) => setCustSearch(e.target.value)}
                placeholder="Search customer…"
                className="input"
                style={{ boxSizing: 'border-box' }}
              />
            </div>
            <div style={{ overflowY: 'auto', flex: 1 }}>
              <div
                className={`cust-picker-row${custFilter === '' ? ' selected-cust' : ''}`}
                onClick={() => { setCustFilter(''); setCustPickerOpen(false) }}
              >
                All customers
              </div>
              {filteredCustOptions.map((c) => (
                <div
                  key={c.id}
                  className={`cust-picker-row${custFilter === c.id ? ' selected-cust' : ''}`}
                  onClick={() => { setCustFilter(c.id); setCustPickerOpen(false) }}
                >
                  <div style={{ fontWeight: 'var(--font-weight-medium)' }}>
                    {c.name}{c.surname ? ` ${c.surname}` : ''}
                  </div>
                  {c.organization && (
                    <div style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)', marginTop: 1 }}>
                      {c.organization}
                    </div>
                  )}
                </div>
              ))}
              {filteredCustOptions.length === 0 && custSearch && (
                <div style={{ padding: 'var(--space-4)', textAlign: 'center', color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)' }}>
                  No customers found
                </div>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Confirm delete */}
      <ConfirmDialog
        open={!!deleteId}
        variant="danger"
        title="Delete communication?"
        message="This entry will be permanently removed."
        confirmLabel="Delete"
        onConfirm={handleDelete}
        onClose={() => setDeleteId(null)}
        loading={deleting}
      />

      <MailViewModal
        entry={viewEntry}
        customers={customers}
        resolveCustomer={(e) => customers[e.customer_id] || null}
        onClose={() => setViewEntry(null)}
        onReply={openReply}
      />

      <ComposeEmailModal
        open={composeOpen}
        defaultTo={composeTo}
        defaultFromAccount={composeFromAccount}
        onClose={() => setComposeOpen(false)}
        onSent={() => { setComposeOpen(false); loadAll() }}
      />
      <EditCommsEntryModal
        open={!!editEntry}
        entry={editEntry}
        onClose={() => setEditEntry(null)}
        onSaved={loadAll}
      />
    </>
  )
}
