// frontend/src/pages/crm/customers/tabs/CommunicationTab.jsx
// Customer-scoped communications log — same card/timeline UI as the global CommsPage,
// but filtered to this customer only. Fetches via GET /crm/comms?customer_id=...

import { useState, useEffect, useCallback } from 'react'
import api from '@/lib/api'
import { useAuth } from '@/hooks/useAuth'
import { useToast } from '@/components/ui/Toast'
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 ConfirmDialog from '@/components/ui/ConfirmDialog'
import MailViewModal from '@/modals/crm/MailViewModal'
import ComposeEmailModal from '@/modals/crm/ComposeEmailModal'
import EditCommsEntryModal from '@/modals/crm/EditCommsEntryModal'
import LogCommsEntryModal from '@/modals/crm/LogCommsEntryModal'
import { fmtRelative, fmtDateTime as fmtDateTimeCentral } from '@/lib/formatters'

// ─── Constants ────────────────────────────────────────────────────────────────

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)' },
}

const COMMS_TYPES = ['email', 'whatsapp', 'call', 'sms', 'note', 'in_person']

// ─── Helpers ──────────────────────────────────────────────────────────────────

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

// ─── SVG icons ────────────────────────────────────────────────────────────────

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>

// ─── Type icon badge ──────────────────────────────────────────────────────────

function TypeIconBadge({ type }) {
  const meta = TYPE_META[type] || TYPE_META.note
  return (
    <div style={{
      width: 44, height: 44,
      borderRadius: 'var(--radius-lg)',
      backgroundColor: meta.bg,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0,
    }}>
      <img src={meta.icon} width={22} height={22} 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={12} height={12} alt={meta.label}
        style={{ filter: 'brightness(0) invert(1)', opacity: 0.5, flexShrink: 0 }} />
      <span style={{ fontSize: 'var(--font-size-xs)', color: meta.color, textTransform: 'capitalize', fontWeight: 'var(--font-weight-medium)' }}>
        {meta.label}
      </span>
    </div>
  )
}

// ─── Entry card ───────────────────────────────────────────────────────────────

function EntryCard({ entry, 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
      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 + actions (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: 24, top: '50%', transform: 'translateY(-50%)',
            display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 12,
            pointerEvents: 'all',
          }}>
            <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 3 }}>
              <span style={{ fontSize: 11, color: 'rgba(255,255,255,0.5)', whiteSpace: 'nowrap' }}>
                {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' }}>
                {formatFull(entry.occurred_at)}
              </span>
            </div>
            <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 }}>
              <Button variant="secondary" size="sm" disabled={entry.type !== 'email'}
                onClick={e => { e.stopPropagation(); if (entry.type === 'email') onView(entry) }}
                style={{ minWidth: 100, justifyContent: 'center' }}>
                <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconExpand />Full view</span>
              </Button>
              <Button variant="ghost" size="sm"
                onClick={e => { e.stopPropagation(); onReply(entry.from_addr || '', entry.mailbox_account) }}
                style={{ minWidth: 100, justifyContent: 'center' }}>
                <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconReply />Reply</span>
              </Button>
            </div>
            {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 }}>
                  <Button variant="warning" size="sm"
                    onClick={e => { e.stopPropagation(); onEdit(entry) }}
                    style={{ minWidth: 100, justifyContent: 'center' }}>
                    <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconEdit />Edit</span>
                  </Button>
                  <Button variant="danger" size="sm"
                    onClick={e => { e.stopPropagation(); onDelete(entry.id) }}
                    style={{ minWidth: 100, justifyContent: 'center' }}>
                    <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconDelete />Delete</span>
                  </Button>
                </div>
              </>
            )}
          </div>
        </div>
      )}

      {/* Card header row */}
      <div
        onClick={() => entry.body && onToggle(entry.id)}
        style={{
          display: 'grid',
          gridTemplateColumns: '44px 1fr auto',
          gap: 'var(--space-4)',
          padding: 'var(--space-4) var(--space-5)',
          cursor: entry.body ? 'pointer' : 'default',
          alignItems: 'flex-start',
        }}
      >
        <TypeIconBadge type={entry.type} />
        <div style={{ minWidth: 0 }}>
          <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)' }}>·</span>
            <DirBadge direction={entry.direction} />
          </div>
          {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>
          )}
          {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>
          )}
          {entry.logged_by && (
            <span style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)', display: 'block', marginTop: 'var(--space-1)' }}>
              by {entry.logged_by}
            </span>
          )}
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 'var(--space-1)', 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-3)', backgroundColor: 'var(--color-bg-surface)' }}>
          <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)', whiteSpace: 'nowrap', marginRight: 'auto' }}>
            {entry.direction === 'inbound' ? 'Received' : entry.direction === 'outbound' ? 'Sent' : 'Logged'} via {meta.label} · {formatFull(entry.occurred_at)}
          </span>
          <Button variant="secondary" size="sm" 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="ghost" size="sm"
            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="sm"
                onClick={e => { e.stopPropagation(); onEdit(entry) }}>
                <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconEdit />Edit</span>
              </Button>
              <Button variant="danger" size="sm"
                onClick={e => { e.stopPropagation(); onDelete(entry.id) }}>
                <span style={{ display: 'flex', alignItems: 'center', gap: 5 }}><IconDelete />Delete</span>
              </Button>
            </>
          )}
        </div>
      )}
    </div>
  )
}

// ─── Main component ───────────────────────────────────────────────────────────

export default function CommunicationTab({ customer, canEdit }) {
  const { toast } = useToast()

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

  const [typeFilter, setTypeFilter] = useState('')
  const [search, setSearch]         = useState('')

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

  const [viewEntry, setViewEntry]           = useState(null)
  const [composeOpen, setComposeOpen]       = useState(false)
  const [composeTo, setComposeTo]           = useState('')
  const [composeAccount, setComposeAccount] = useState('')
  const [editEntry, setEditEntry]           = useState(null)
  const [logOpen, setLogOpen]               = useState(false)

  const load = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const params = new URLSearchParams({ customer_id: customer.id })
      if (typeFilter) params.set('type', typeFilter)
      const data = await api.get(`/crm/comms?${params}`)
      const list = (data.entries || []).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
      })
      setEntries(list)
    } catch (err) {
      setError(err.message || 'Failed to load communications.')
    } finally {
      setLoading(false)
    }
  }, [customer.id, typeFilter])

  useEffect(() => { load() }, [load])

  const handleDelete = async () => {
    if (!deleteId) return
    setDeleting(true)
    try {
      await api.delete(`/crm/comms/${deleteId}`)
      toast.success('Deleted', 'Entry removed.')
      setDeleteId(null)
      await load()
    } catch (err) {
      toast.danger('Error', err.message || 'Failed to delete.')
    } finally {
      setDeleting(false)
    }
  }

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

  // Client-side search filter
  const q = search.trim().toLowerCase()
  const filtered = entries.filter(e => {
    if (!q) return true
    return (
      (e.subject || '').toLowerCase().includes(q) ||
      (e.body || '').replace(/<[^>]*>/g, '').toLowerCase().includes(q) ||
      (e.from_addr || '').toLowerCase().includes(q) ||
      (e.logged_by || '').toLowerCase().includes(q)
    )
  })

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-5)' }}>
      {/* Toolbar */}
      <div style={{ display: 'flex', gap: 'var(--space-3)', alignItems: 'center', flexWrap: 'wrap' }}>
        <div style={{ flex: 1, minWidth: 200, maxWidth: 360 }}>
          <SearchBar value={search} onChange={setSearch} placeholder="Search messages…" />
        </div>
        <Select value={typeFilter} onChange={setTypeFilter} style={{ width: 150 }}>
          <option value="">All types</option>
          {COMMS_TYPES.map(t => (
            <option key={t} value={t}>{TYPE_META[t]?.label || t}</option>
          ))}
        </Select>
        {(search || typeFilter) && (
          <Button variant="ghost" size="sm" onClick={() => { setSearch(''); setTypeFilter('') }}>Clear</Button>
        )}
        <div style={{ marginLeft: 'auto', display: 'flex', gap: 'var(--space-2)' }}>
          <Button variant="secondary" size="md" onClick={() => setLogOpen(true)}>
            + Log Entry
          </Button>
          <Button variant="primary" size="md" onClick={() => { setComposeTo(''); setComposeOpen(true) }}>
            + Compose Email
          </Button>
        </div>
      </div>

      {/* States */}
      {loading && (
        <div style={{ display: 'flex', justifyContent: 'center', padding: 'var(--space-12)' }}>
          <Spinner size="lg" />
        </div>
      )}

      {!loading && error && (
        <div style={{ padding: 'var(--space-5)', 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>
      )}

      {!loading && !error && filtered.length === 0 && (
        <div style={{ padding: 'var(--space-12)', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--space-3)', color: 'var(--color-text-muted)' }}>
          <svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
            <path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" />
          </svg>
          <p style={{ fontSize: 'var(--font-size-base)', fontWeight: 'var(--font-weight-semibold)', color: 'var(--color-text-secondary)', margin: 0 }}>
            {search || typeFilter ? 'No matching communications.' : 'No communications logged yet.'}
          </p>
          {!search && !typeFilter && (
            <p style={{ fontSize: 'var(--font-size-sm)', margin: 0 }}>
              Use "Send Message" from the action menu or Compose Email above to get started.
            </p>
          )}
        </div>
      )}

      {!loading && !error && filtered.length > 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-3)' }}>
          {filtered.map(entry => (
            <EntryCard
              key={entry.id}
              entry={entry}
              expanded={expandedId === entry.id}
              canEdit={canEdit}
              onToggle={id => setExpandedId(prev => prev === id ? null : id)}
              onDelete={id => setDeleteId(id)}
              onEdit={e => setEditEntry(e)}
              onView={e => setViewEntry(e)}
              onReply={openReply}
            />
          ))}
        </div>
      )}

      {/* Modals */}
      <MailViewModal
        open={viewEntry !== null}
        entry={viewEntry}
        onClose={() => setViewEntry(null)}
        onReply={addr => openReply(addr)}
      />

      <ComposeEmailModal
        open={composeOpen}
        defaultTo={composeTo}
        defaultFromAccount={composeAccount}
        customerId={customer?.id}
        onClose={() => setComposeOpen(false)}
        onSent={() => { setComposeOpen(false); load() }}
      />

      <EditCommsEntryModal
        open={editEntry !== null}
        entry={editEntry}
        onClose={() => setEditEntry(null)}
        onSaved={() => { setEditEntry(null); load() }}
      />

      <LogCommsEntryModal
        open={logOpen}
        customerId={customer?.id}
        onClose={() => setLogOpen(false)}
        onSaved={() => { setLogOpen(false); load() }}
      />

      <ConfirmDialog
        open={deleteId !== null}
        variant="danger"
        title="Delete Entry"
        message="Remove this communication entry permanently?"
        confirmLabel={deleting ? 'Deleting…' : 'Delete'}
        onConfirm={handleDelete}
        onCancel={() => setDeleteId(null)}
      />
    </div>
  )
}
