// frontend/src/pages/crm/comms/helpdesk/IssuesTab.jsx
// Global Issues list — all open/researching/resolved issues across all entities.

import { useState, useEffect, useCallback } 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 usePreferences from '@/hooks/usePreferences'
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 EntryFormModal from '@/modals/crm/helpdesk/EntryFormModal'
import { fmtDateMedium, fmtRelative } from '@/lib/formatters'

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

const STATUS_META = {
  open:        { label: 'Open',        color: 'var(--color-danger)',  bg: 'var(--color-danger-bg)',  dot: 'var(--color-danger)'  },
  researching: { label: 'Researching', color: 'var(--color-warning)', bg: 'var(--color-warning-bg)', dot: 'var(--color-warning)' },
  resolved:    { label: 'Resolved',    color: 'var(--color-success)', bg: 'var(--color-success-bg)', dot: 'var(--color-success)' },
}

const SEVERITY_META = {
  low:      { label: 'Low',      color: 'var(--color-info)',    bars: 1 },
  medium:   { label: 'Medium',   color: 'var(--color-warning)', bars: 2 },
  high:     { label: 'High',     color: 'var(--color-danger)',  bars: 3 },
  critical: { label: 'Critical', color: 'var(--color-danger)',  bars: 4, breathe: true },
}

const CATEGORY_META = {
  technical:       { label: 'Technical Issue'  },
  install_support: { label: 'Install Support'  },
  general:         { label: 'General'          },
}

const ENTITY_LINKS = {
  device:   { label: 'Device',   href: (id) => `/devices/${id}`,       bg: 'rgba(186,230,253,0.10)', border: 'rgba(186,230,253,0.20)', color: 'rgb(186,230,253)' },
  app_user: { label: 'User',     href: (id) => `/users/${id}`,         bg: 'rgba(147,197,253,0.10)', border: 'rgba(147,197,253,0.20)', color: 'rgb(147,197,253)' },
  customer: { label: 'Customer', href: (id) => `/crm/customers/${id}`, bg: 'rgba(96,165,250,0.12)',  border: 'rgba(96,165,250,0.25)',  color: 'rgb(96,165,250)'  },
}

// ─── Sub-components ───────────────────────────────────────────────────────────

function StatusPill({ status }) {
  const m = STATUS_META[status] || { label: status, color: 'var(--color-text-muted)', bg: 'var(--color-bg-elevated)', dot: 'var(--color-text-muted)' }
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '3px 10px',
      borderRadius: 'var(--radius-full)',
      backgroundColor: m.bg,
      border: `1px solid ${m.color}33`,
      fontSize: 'var(--font-size-xs)',
      fontWeight: 'var(--font-weight-semibold)',
      color: m.color,
      whiteSpace: 'nowrap',
    }}>
      <span style={{ width: 6, height: 6, borderRadius: '50%', backgroundColor: m.dot, flexShrink: 0 }} />
      {m.label}
    </span>
  )
}

function SeverityBars({ severity }) {
  if (!severity) return <span style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-xs)' }}>—</span>
  const m = SEVERITY_META[severity] || { label: severity, color: 'var(--color-text-muted)', bars: 1 }
  return (
    <span
      className={m.breathe ? 'severity-critical' : undefined}
      style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}
    >
      {/* 4-bar signal icon — filled bars match severity */}
      <span style={{ display: 'flex', alignItems: 'flex-end', gap: 2, height: 14 }}>
        {[1, 2, 3, 4].map(b => (
          <span key={b} style={{
            width: 3,
            height: 3 + b * 2.5,
            borderRadius: 1,
            backgroundColor: b <= m.bars ? m.color : 'var(--color-bg-island)',
            display: 'block',
          }} />
        ))}
      </span>
      <span style={{ fontSize: 'var(--font-size-xs)', fontWeight: 'var(--font-weight-medium)', color: m.color }}>
        {m.label}
      </span>
    </span>
  )
}

const LINKED_TO_CAP = 3

function EntityChips({ links, nameMap }) {
  const [overflowOpen, setOverflowOpen] = useState(false)

  if (!links || links.length === 0) return <span style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-xs)' }}>—</span>

  const visible  = links.slice(0, LINKED_TO_CAP)
  const overflow = links.slice(LINKED_TO_CAP)

  const renderChip = (l) => {
    const meta = ENTITY_LINKS[l.entity_type]
    if (!meta) return null
    const name = nameMap?.[l.entity_id] || l.entity_id.slice(0, 8) + '…'
    return (
      <Link
        key={l.id}
        to={meta.href(l.entity_id)}
        onClick={e => e.stopPropagation()}
        style={{
          display: 'inline-flex', alignItems: 'center', gap: 4,
          padding: '2px 8px',
          borderRadius: 'var(--radius-sm)',
          backgroundColor: meta.bg,
          border: `1px solid ${meta.border}`,
          fontSize: 'var(--font-size-xs)',
          color: meta.color,
          fontWeight: 'var(--font-weight-medium)',
          textDecoration: 'none',
          whiteSpace: 'nowrap',
          alignSelf: 'flex-start',
        }}
      >
        {name}
      </Link>
    )
  }

  return (
    <>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
        {visible.map(renderChip)}
        {overflow.length > 0 && (
          <button
            onClick={e => { e.stopPropagation(); setOverflowOpen(true) }}
            style={{
              display: 'inline-flex', alignItems: 'center',
              padding: '2px 8px',
              borderRadius: 'var(--radius-sm)',
              backgroundColor: 'var(--color-bg-island)',
              border: '1px solid var(--color-border-strong)',
              fontSize: 'var(--font-size-xs)',
              color: 'var(--color-text-secondary)',
              fontWeight: 'var(--font-weight-medium)',
              cursor: 'pointer',
              whiteSpace: 'nowrap',
              alignSelf: 'flex-start',
              fontFamily: 'var(--font-family-base)',
              transition: 'background 0.1s, color 0.1s',
            }}
            onMouseEnter={e => { e.currentTarget.style.backgroundColor = 'var(--color-bg-elevated)'; e.currentTarget.style.color = 'var(--color-text-primary)' }}
            onMouseLeave={e => { e.currentTarget.style.backgroundColor = 'var(--color-bg-island)'; e.currentTarget.style.color = 'var(--color-text-secondary)' }}
          >
            +{overflow.length + 0} more
          </button>
        )}
      </div>

      {/* Overflow mini-modal */}
      {overflowOpen && (
        <div
          onClick={e => e.stopPropagation()}
          style={{
            position: 'fixed', inset: 0, zIndex: 9999,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            backgroundColor: 'rgba(10,14,20,0.65)',
            backdropFilter: 'blur(4px)',
            WebkitBackdropFilter: 'blur(4px)',
          }}
          onMouseDown={e => { if (e.target === e.currentTarget) setOverflowOpen(false) }}
        >
          <div style={{
            minWidth: 260, maxWidth: 400,
            backgroundColor: 'var(--color-bg-card)',
            border: '1px solid var(--color-border)',
            borderRadius: 'var(--radius-xl)',
            boxShadow: 'var(--shadow-modal)',
            overflow: 'hidden',
          }}>
            <div style={{
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              padding: 'var(--space-4) var(--space-5)',
              borderBottom: '1px solid var(--color-border)',
              backgroundColor: 'rgba(28,32,38,0.50)',
            }}>
              <span style={{ fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-semibold)', color: 'var(--color-text-primary)' }}>
                {links.length} linked entities
              </span>
              <button
                onClick={() => setOverflowOpen(false)}
                style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--color-text-muted)', lineHeight: 1, padding: 4 }}
              >
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
                </svg>
              </button>
            </div>
            <div style={{ padding: 'var(--space-4) var(--space-5)', display: 'flex', flexDirection: 'column', gap: 6 }}>
              {links.map(renderChip)}
            </div>
          </div>
        </div>
      )}
    </>
  )
}

// ─── IssuesTab ────────────────────────────────────────────────────────────────

const PAGE_SIZE_OPTIONS = [10, 25, 50]

// gridTemplateColumns shared by header and every row
// "Researching" pill + padding ≈ 126px → 130px. Longest chip ≈ 130px → 140px.
const GRID_COLS = '130px 1fr 140px 120px 180px 120px 110px'

export default function IssuesTab({ onOpenCreate }) {
  const { hasPermission } = useAuth()
  const { toast } = useToast()
  const canEdit   = hasPermission('crm', 'edit')
  const canAdd    = hasPermission('crm', 'add')
  const canDelete = hasPermission('crm', 'delete')

  const { prefs, setPref, setPrefBatch, ready } = usePreferences('helpdesk_issues')

  const [issues,   setIssues]   = useState([])
  const [total,    setTotal]    = useState(0)
  const [loading,  setLoading]  = useState(true)
  const [error,    setError]    = useState('')

  // entity ID → display name lookup for the Linked To column
  const [nameMap, setNameMap] = useState({})

  const [search,   setSearch]   = useState('')
  const [status,   setStatus]   = useState('')
  const [severity, setSeverity] = useState('')
  const [category, setCategory] = useState('')

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

  const [prefsLoaded, setPrefsLoaded] = useState(false)

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

  // When parent increments openTrigger, open the create form
  useEffect(() => {
    if (onOpenCreate && onOpenCreate > 0) openCreate()
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [onOpenCreate])

  // ── Load preferences once ready ──
  useEffect(() => {
    if (!ready || prefsLoaded) return
    if (prefs.status   !== undefined) setStatus(prefs.status)
    if (prefs.severity !== undefined) setSeverity(prefs.severity)
    if (prefs.category !== undefined) setCategory(prefs.category)
    if (prefs.page_size !== undefined) setPageSize(prefs.page_size)
    setPrefsLoaded(true)
  }, [ready, prefs, prefsLoaded])

  // ── Persist filter changes ──
  useEffect(() => {
    if (!prefsLoaded) return
    setPrefBatch({ status, severity, category, page_size: pageSize })
  }, [status, severity, category, pageSize]) // eslint-disable-line react-hooks/exhaustive-deps

  // ── Fetch entity display names for all links in the current page ──
  const resolveNames = useCallback(async (rows) => {
    // Collect unique IDs by type
    const byType = { device: new Set(), app_user: new Set(), customer: new Set() }
    for (const issue of rows) {
      for (const l of issue.links || []) {
        if (byType[l.entity_type]) byType[l.entity_type].add(l.entity_id)
      }
    }

    const map = {}
    await Promise.all([
      // Devices — fetch individually (no bulk ID endpoint)
      ...[...byType.device].map(async (id) => {
        try {
          const d = await api.get(`/devices/${id}`)
          map[id] = d.device_name || id
        } catch { map[id] = id }
      }),
      // App users
      ...[...byType.app_user].map(async (id) => {
        try {
          const d = await api.get(`/users/${id}`)
          map[id] = d.display_name || d.email || id
        } catch { map[id] = id }
      }),
      // Customers
      ...[...byType.customer].map(async (id) => {
        try {
          const d = await api.get(`/crm/customers/${id}`)
          const name = [d.name, d.surname].filter(Boolean).join(' ') || d.organization
          map[id] = name || id
        } catch { map[id] = id }
      }),
    ])
    setNameMap(prev => ({ ...prev, ...map }))
  }, [])

  // ── Fetch ──
  const load = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const params = new URLSearchParams({ type: 'issue', page, limit: pageSize })
      if (status)   params.set('status', status)
      if (severity) params.set('severity', severity)
      if (category) params.set('category', category)
      const data = await api.get(`/notes?${params}`)
      const rows = data.data || []
      setIssues(rows)
      setTotal(data.pagination?.total ?? 0)
      resolveNames(rows)
    } catch (err) {
      setError(err.message || 'Failed to load issues')
    } finally {
      setLoading(false)
    }
  }, [page, pageSize, status, severity, category, resolveNames])

  useEffect(() => { load() }, [load])
  useEffect(() => { setPage(1) }, [status, severity, category, search])

  // ── Client-side search filter (title + author) ──
  const q = search.trim().toLowerCase()
  const displayed = q
    ? issues.filter(i =>
        i.title.toLowerCase().includes(q) ||
        (i.author_name || '').toLowerCase().includes(q) ||
        (i.body || '').toLowerCase().includes(q)
      )
    : issues

  // ── Delete ──
  const handleDelete = useCallback(async () => {
    if (!deleteId) return
    setDeleting(true)
    try {
      await api.delete(`/notes/${deleteId}`)
      toast.success('Deleted', 'Issue removed.')
      setDeleteId(null)
      load()
    } catch (err) {
      toast.danger('Delete failed', err.message)
    } finally {
      setDeleting(false)
    }
  }, [deleteId, toast, load])

  const openCreate = () => { setEditEntry(null); setFormOpen(true) }
  const openEdit   = (e) => { setEditEntry(e);   setFormOpen(true) }

  const hasFilters = status || severity || category || search

  return (
    <>
      <style>{`
        .issue-row { transition: background 0.12s; }
        .issue-row:hover { background: rgba(49,53,60,0.50) !important; }

        @keyframes severity-glow {
          0%, 100% { filter: drop-shadow(0 0 0px var(--color-danger)); }
          50%       { filter: drop-shadow(0 0 6px var(--color-danger)); }
        }
        .severity-critical {
          animation: severity-glow 0.9s ease-in-out infinite;
        }

        .issues-toolbar .btn {
          padding-top: var(--space-3) !important;
          padding-bottom: var(--space-3) !important;
          line-height: var(--line-height-base) !important;
          font-size: var(--font-size-sm) !important;
        }
      `}</style>

      {/* Toolbar — single row, SearchBar expands */}
      <div className="issues-toolbar" style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)', flexWrap: 'nowrap' }}>
        <SearchBar
          value={search}
          onChange={setSearch}
          placeholder="Search issues…"
          style={{ flex: 1, minWidth: 0 }}
        />

        <div style={{ flexShrink: 0, minWidth: 136 }}>
          <Select value={status} onChange={e => setStatus(e.target.value)} placeholder="All statuses">
            <option value="">All statuses</option>
            {Object.entries(STATUS_META).map(([k, v]) => (
              <option key={k} value={k}>{v.label}</option>
            ))}
          </Select>
        </div>

        <div style={{ flexShrink: 0, minWidth: 136 }}>
          <Select value={severity} onChange={e => setSeverity(e.target.value)} placeholder="All severities">
            <option value="">All severities</option>
            {Object.entries(SEVERITY_META).map(([k, v]) => (
              <option key={k} value={k}>{v.label}</option>
            ))}
          </Select>
        </div>

        <div style={{ flexShrink: 0, minWidth: 152 }}>
          <Select value={category} onChange={e => setCategory(e.target.value)} placeholder="All categories">
            <option value="">All categories</option>
            {Object.entries(CATEGORY_META).map(([k, v]) => (
              <option key={k} value={k}>{v.label}</option>
            ))}
          </Select>
        </div>

        {hasFilters && (
          <Button variant="ghost" size="sm" onClick={() => { setStatus(''); setSeverity(''); setCategory(''); setSearch('') }}>
            Clear
          </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>
      )}

      {/* Table */}
      <div style={{
        borderRadius: 'var(--radius-xl)',
        border: '1px solid var(--color-border)',
        overflow: 'hidden',
        backgroundColor: 'rgba(28,32,38,0.30)',
        backdropFilter: 'var(--blur-modal)',
        WebkitBackdropFilter: 'var(--blur-modal)',
        boxShadow: 'var(--shadow-card)',
      }}>
        {/* Table header */}
        <div style={{
          display: 'grid',
          gridTemplateColumns: GRID_COLS,
          padding: '0 var(--space-5)',
          borderBottom: '1px solid var(--color-border)',
          backgroundColor: 'rgba(28,32,38,0.40)',
          backdropFilter: 'var(--blur-modal)',
          WebkitBackdropFilter: 'var(--blur-modal)',
        }}>
          {['Status', 'Issue', 'Category', 'Severity', 'Linked To', 'Reported By', 'Date'].map(h => (
            <div key={h} style={{
              padding: 'var(--space-3) 0',
              paddingRight: h === 'Linked To' ? 'var(--space-4)' : 0,
              fontSize: 'var(--font-size-xs)',
              fontWeight: 'var(--font-weight-semibold)',
              color: 'var(--color-text-muted)',
              textTransform: 'uppercase',
              letterSpacing: 'var(--tracking-wide)',
            }}>
              {h}
            </div>
          ))}
        </div>

        {/* Body */}
        {loading ? (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 'var(--space-3)', padding: 'var(--space-12)' }}>
            <Spinner size="md" />
            <span style={{ color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)' }}>Loading issues…</span>
          </div>
        ) : displayed.length === 0 ? (
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 'var(--space-3)', padding: 'var(--space-12)', color: 'var(--color-text-muted)' }}>
            <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" style={{ opacity: 0.4 }}>
              <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
            </svg>
            <p style={{ margin: 0, fontSize: 'var(--font-size-base)' }}>
              {hasFilters ? 'No issues match your filters.' : 'No issues recorded yet.'}
            </p>
            {canAdd && !hasFilters && (
              <Button variant="secondary" size="sm" onClick={openCreate}>Record first issue</Button>
            )}
          </div>
        ) : (
          displayed.map((issue, idx) => (
            <div
              key={issue.id}
              className="issue-row"
              style={{
                display: 'grid',
                gridTemplateColumns: GRID_COLS,
                padding: '0 var(--space-5)',
                borderBottom: idx < displayed.length - 1 ? '1px solid var(--color-border)' : 'none',
                cursor: canEdit ? 'pointer' : 'default',
                alignItems: 'center',
              }}
              onClick={() => canEdit && openEdit(issue)}
            >
              {/* Status */}
              <div style={{ padding: 'var(--space-4) 0' }}>
                <StatusPill status={issue.status} />
              </div>

              {/* Title + body preview */}
              <div style={{ padding: 'var(--space-4) var(--space-3) var(--space-4) 0', minWidth: 0 }}>
                <p style={{ margin: 0, fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)', fontSize: 'var(--font-size-base)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {issue.title}
                </p>
                {issue.body && (
                  <p style={{ margin: '2px 0 0', color: 'var(--color-text-muted)', fontSize: 'var(--font-size-xs)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {issue.body.replace(/<[^>]*>/g, '').slice(0, 100)}
                  </p>
                )}
              </div>

              {/* Category */}
              <div style={{ padding: 'var(--space-4) 0', fontSize: 'var(--font-size-xs)', color: 'var(--color-text-secondary)' }}>
                {CATEGORY_META[issue.category]?.label || '—'}
              </div>

              {/* Severity */}
              <div style={{ padding: 'var(--space-4) 0' }}>
                <SeverityBars severity={issue.severity} />
              </div>

              {/* Linked entities */}
              <div style={{ padding: 'var(--space-4) var(--space-4) var(--space-4) 0' }}>
                <EntityChips links={issue.links} nameMap={nameMap} />
              </div>

              {/* Author */}
              <div style={{ padding: 'var(--space-4) 0', fontSize: 'var(--font-size-xs)', color: 'var(--color-text-secondary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {issue.author_name || '—'}
              </div>

              {/* Date */}
              <div style={{ padding: 'var(--space-4) 0' }} title={fmtDateMedium(issue.created_at)}>
                <span style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)' }}>
                  {fmtRelative(issue.created_at)}
                </span>
              </div>
            </div>
          ))
        )}

        {/* Footer: count + pagination */}
        {!loading && displayed.length > 0 && (
          <div style={{
            display: 'flex', alignItems: 'center', justifyContent: 'space-between',
            padding: 'var(--space-3) var(--space-5)',
            borderTop: '1px solid var(--color-border)',
            backgroundColor: 'rgba(28,32,38,0.40)',
            backdropFilter: 'var(--blur-modal)',
            WebkitBackdropFilter: 'var(--blur-modal)',
          }}>
            <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)' }}>
              {total} issue{total !== 1 ? 's' : ''}{hasFilters ? ' (filtered)' : ''}
            </span>
            <Pagination
              page={page}
              pageSize={pageSize}
              total={total}
              onPageChange={setPage}
              onSizeChange={s => { setPageSize(s); setPage(1) }}
              pageSizes={PAGE_SIZE_OPTIONS}
            />
          </div>
        )}
      </div>

      {/* Modals */}
      <EntryFormModal
        open={formOpen}
        entry={editEntry}
        defaultType="issue"
        onClose={() => { setFormOpen(false); setEditEntry(null) }}
        onSaved={() => { setFormOpen(false); setEditEntry(null); load() }}
        onDelete={canDelete ? (id) => { setFormOpen(false); setDeleteId(id) } : null}
      />

      <ConfirmDialog
        open={!!deleteId}
        variant="danger"
        title="Delete issue?"
        message="This issue and all its entity links will be permanently removed."
        confirmLabel="Delete"
        onConfirm={handleDelete}
        onClose={() => setDeleteId(null)}
        loading={deleting}
      />
    </>
  )
}
