// Shared small components: Tile, Pill, Icon, etc.
const { useState, useEffect, useMemo, useRef, useCallback } = React;

const Icon = ({ name, size = 14, stroke = "currentColor" }) => {
  const paths = {
    search: <><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></>,
    home:   <><path d="M3 10.5 12 3l9 7.5"/><path d="M5 9v11h14V9"/></>,
    inbox:  <><path d="M3 13h6l2 3h2l2-3h6"/><path d="M3 13V6a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v7"/><path d="M3 13v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6"/></>,
    flag:   <><path d="M4 22V4"/><path d="M4 4h13l-2 4 2 4H4"/></>,
    export: <><path d="M12 3v12"/><path d="m7 8 5-5 5 5"/><path d="M5 21h14"/></>,
    settings: <><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3h.1a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1Z"/></>,
    check:  <polyline points="4 12 10 18 20 6"/>,
    x:      <><path d="m6 6 12 12"/><path d="m18 6-12 12"/></>,
    chevR:  <polyline points="9 6 15 12 9 18"/>,
    chevL:  <polyline points="15 6 9 12 15 18"/>,
    chevD:  <polyline points="6 9 12 15 18 9"/>,
    ext:    <><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5"/></>,
    filter: <><path d="M3 5h18"/><path d="M6 12h12"/><path d="M10 19h4"/></>,
    ban:    <><circle cx="12" cy="12" r="9"/><path d="m5 5 14 14"/></>,
    dot:    <circle cx="12" cy="12" r="4"/>,
    clock:  <><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 16 14"/></>,
    user:   <><circle cx="12" cy="8" r="4"/><path d="M4 21a8 8 0 0 1 16 0"/></>,
    lock:   <><rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V8a4 4 0 1 1 8 0v3"/></>,
    bolt:   <path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/>,
    clock:  <><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></>,
    edit:   <><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 1 1 3 3L7 19l-4 1 1-4Z"/></>,
    help:   <><circle cx="12" cy="12" r="9"/><path d="M9.1 9a3 3 0 0 1 5.8 1c0 2-3 2.5-3 4"/><circle cx="12" cy="17" r="0.6" fill="currentColor" stroke="none"/></>,
    plus:   <><path d="M12 5v14"/><path d="M5 12h14"/></>,
    trash:  <><path d="M4 7h16"/><path d="M10 11v6"/><path d="M14 11v6"/><path d="M6 7l1 13a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2l1-13"/><path d="M9 7V5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2"/></>,
    copy:   <><rect x="8" y="8" width="12" height="12" rx="2"/><path d="M16 8V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h2"/></>,
    logout: <><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><path d="m21 12-9 0"/></>,
    alert:  <><path d="m21 16-4-4m0 0l-4-4m4 4l-4-4m4 4l4-4"/><circle cx="12" cy="12" r="10"/><path d="M12 7v5"/><path d="M12 16h.01"/></>,
    loader: <><path d="M12 3v3m6.366-.366l-2.12 2.12M21 12h-3m.366 6.366l-2.12-2.12M12 21v-3m-6.366.366l2.12-2.12M3 12h3m-.366-6.366l2.12 2.12"/></>,
    refresh: <><path d="M21.5 2v6h-6M2.5 22v-6h6"/><path d="M2 11.5a10 10 0 0 1 18.8-4.3M22 12.5a10 10 0 0 1-18.8 4.2"/></>,
    login:  <><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><path d="m15 12-15 0"/></>,
    click: <><path d="m3 3 7.07 16.97 2.51-7.39 7.39-2.51L3 3z"/><path d="m13 13 6 6m5-8 3-1m-10 8-1 3"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
         stroke={stroke} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      {paths[name]}
    </svg>
  );
};

const TILE_LABELS = {
  instagram: 'IG', youtube: 'YT', tiktok: 'TK', x: 'X', facebook: 'FB', twitch: 'TH', web: 'WW',
};

const Tile = ({ platform, status, size = '', selected = false, onClick, title }) => (
  <div
    className={`tile ${status} ${size} ${selected ? 'selected' : ''}`}
    onClick={onClick}
    title={title || `${platform}: ${status}`}
    role={onClick ? 'button' : 'presentation'}
  >
    <div className="tile-lbl">{TILE_LABELS[platform]}</div>
    <div className="tile-bar" />
    {status === 'qc' && (
      <div style={{
        position: 'absolute', top: 2, right: 2,
        width: 8, height: 8, borderRadius: 2,
        background: '#16A34A',
      }}/>
    )}
    {status === 'verified' && (
      <div style={{
        position: 'absolute', top: 2, right: 2,
        width: 4, height: 4, borderRadius: 2,
        background: '#16A34A',
      }}/>
    )}
  </div>
);

const Pill = ({ kind = 'neutral', dot = false, children }) => (
  <span className={`pill ${kind}`}>
    {dot && <span className="dot" style={{background: 'currentColor'}}/>}
    {children}
  </span>
);

// Status helpers
const STATUS_META = {
  missing:       { label: 'Missing',          color: '#A8A29E',  pill: 'neutral' },
  unverified:    { label: 'Needs review',     color: '#D97706',  pill: 'warn' },
  verified:      { label: 'Verified',         color: '#84CC16',  pill: 'info' },
  qc:            { label: 'QC passed',        color: '#16A34A',  pill: 'ok' },
  trusted:       { label: 'Trusted',          color: '#059669',  pill: 'ok' },
};

// Compute counts per person (now handles arrays of handles per platform)
function computeCounts(person, platforms) {
  const c = { missing: 0, unverified: 0, verified: 0, qc: 0 };
  let totalHandles = 0;
  for (const p of platforms) {
    const handles = person.handles[p.id];
    if (Array.isArray(handles)) {
      totalHandles += handles.length;
      for (const h of handles) {
        c[h.status] = (c[h.status] || 0) + 1;
      }
    } else {
      // Backwards compatibility for single handle structure
      totalHandles += 1;
      c[handles.status] = (c[handles.status] || 0) + 1;
    }
  }
  const done = c.qc;
  const complete = done === totalHandles;
  return { ...c, done, total: totalHandles, complete };
}

function overallStatus(counts) {
  if (counts.complete) return { kind: 'ok', label: 'Complete' };
  if (counts.unverified > 0 || counts.missing > 0) return { kind: 'warn', label: `${counts.unverified + counts.missing} to review` };
  if (counts.verified > 0) return { kind: 'info', label: `${counts.verified} for QC` };
  return { kind: 'neutral', label: '—' };
}

// Profile (country + category) counts — same status vocabulary as platforms,
// but only for the person-attribute rows. Used in the detail view's progress.
// Trusted attributes (where tool and ES match) are excluded from verification workflow.
function computeProfileCounts(person) {
  const c = { unverified: 0, verified: 0, qc: 0, trusted: 0 };
  if (!person.profile) return { ...c, done: 0, total: 0 };
  let totalCount = 0;
  for (const k of ['country', 'category']) {
    const st = person.profile[k]?.status || 'unverified';
    c[st] = (c[st] || 0) + 1;
    if (st !== 'trusted') totalCount++; // Don't count trusted items in progress
  }
  return { ...c, done: c.qc, total: totalCount };
}

// Active "soft locks": who else has opened a person in the last 5 minutes.
// Returns { [personId]: { id, name, initials, role, activity, since, status, openedAt } }.
function getActiveLocks(team, currentUser) {
  const map = {};
  const fiveMinutesMs = 5 * 60 * 1000;
  const now = Date.now();

  const parseApiTimestamp = (value) => {
    if (!value || typeof value !== 'string') return NaN;
    let s = value.trim();
    // API can return microseconds (e.g., .254000). JS Date prefers milliseconds.
    s = s.replace(/\.(\d{3})\d+/, '.$1');

    const hasTimezone = /[zZ]$|[+-]\d{2}:\d{2}$/.test(s);
    if (hasTimezone) return Date.parse(s);

    // Some endpoints return naive timestamps that are effectively UTC,
    // others behave like local time. Evaluate both and choose the closer one.
    const utcTs = Date.parse(`${s}Z`);
    const localTs = Date.parse(s);
    const utcDiff = Number.isFinite(utcTs) ? Math.abs(now - utcTs) : Number.POSITIVE_INFINITY;
    const localDiff = Number.isFinite(localTs) ? Math.abs(now - localTs) : Number.POSITIVE_INFINITY;

    if (!Number.isFinite(utcTs) && !Number.isFinite(localTs)) return NaN;
    return utcDiff <= localDiff ? utcTs : localTs;
  };

  const currentUserIds = new Set([
    currentUser?.id,
    currentUser?._id,
    currentUser?.user_id,
    currentUser?.email,
  ].filter(Boolean));

  const toInitials = (name) => {
    if (!name) return '?';
    return name
      .split(' ')
      .map(n => n.charAt(0))
      .join('')
      .toUpperCase()
      .slice(0, 2);
  };

  const formatSince = (openedAt) => {
    const diffMs = Math.max(0, now - openedAt);
    const minutes = Math.floor(diffMs / 60000);
    if (minutes <= 0) return 'just now';
    if (minutes === 1) return '1 minute ago';
    return `${minutes} minutes ago`;
  };

  for (const t of team || []) {
    const actorId = t?.id || t?.user_id || t?.email;
    if (actorId && currentUserIds.has(actorId)) continue;

    const personIdRaw = t?.personId || t?.current_person_id || t?.last_viewed_person?.id;
    const personId = personIdRaw != null ? String(personIdRaw) : '';
    const openedAtRaw = t?.last_viewed_person?.at || t?.current_person_at || t?.last_active;
    const openedAt = parseApiTimestamp(openedAtRaw || '');
    if (!personId || !Number.isFinite(openedAt)) continue;

    if (now - openedAt > fiveMinutesMs) continue;

    const normalized = {
      ...t,
      personId,
      initials: t?.initials || toInitials(t?.name),
      activity: t?.activity || 'review',
      since: t?.since || formatSince(openedAt),
      status: t?.status || 'online',
      openedAt,
    };

    const existing = map[personId];
    if (!existing || normalized.openedAt > existing.openedAt) {
      map[personId] = normalized;
    }
  }
  return map;
}

// Small presence chip — avatar + activity dot — for list rows.
const LockChip = ({ lock, size = 18 }) => {
  if (!lock) return null;
  const verb = lock.activity === 'qc' ? 'QC' : 'reviewing';
  return (
    <span
      className={`lock-chip ${lock.status}`}
      title={`${lock.name} (${lock.role}) · ${verb} · ${lock.since}`}
      onClick={(e) => e.stopPropagation()}
    >
      <span className="avatar xs" style={{width: size, height: size, fontSize: Math.round(size*0.45)}}>
        {lock.initials}
      </span>
      <span className={`presence ${lock.status}`}/>
    </span>
  );
};

// Notes component — display and manage notes for a person
function Notes({ notes = [], onAdd, onEdit, onDelete, currentUser, usersMap = {} }) {
  const [newNoteContent, setNewNoteContent] = useState('');
  const [editingNoteId, setEditingNoteId] = useState(null);
  const [editingContent, setEditingContent] = useState('');
  const [isExpanded, setIsExpanded] = useState(() => (notes?.length || 0) > 0);

  // Auto-expand when notes are added
  useEffect(() => {
    if ((notes?.length || 0) > 0) {
      setIsExpanded(true);
    }
  }, [notes?.length]);

  const handleAddNote = () => {
    if (newNoteContent.trim()) {
      onAdd({ content: newNoteContent });
      setNewNoteContent('');
    }
  };

  const handleEditNote = (noteId) => {
    if (editingContent.trim()) {
      onEdit({ note_id: noteId, content: editingContent });
      setEditingNoteId(null);
      setEditingContent('');
    }
  };

  const startEdit = (note) => {
    setEditingNoteId(note.id);
    setEditingContent(note.content);
  };

  const cancelEdit = () => {
    setEditingNoteId(null);
    setEditingContent('');
  };

  const formatDateTime = (dateString) => {
    try {
      const date = new Date(dateString);
      return date.toLocaleString('en-US', {
        month: 'short',
        day: 'numeric',
        year: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
      });
    } catch {
      return dateString;
    }
  };

  const getUserName = (userId) => {
    if (!userId) return 'Unknown';
    return usersMap[userId] || 'Unknown User';
  };

  const noteCount = notes?.length || 0;

  return (
    <div className="notes-section">
      <div className="notes-header">
        <button
          className="notes-toggle"
          onClick={() => setIsExpanded(!isExpanded)}
        >
          <Icon name={isExpanded ? 'chevD' : 'chevL'} size={12}/>
          <Icon name="edit" size={12}/>
          <span>Notes <Pill kind="neutral">{noteCount}</Pill></span>
        </button>
      </div>

      {isExpanded && (
        <div className="notes-content">
          {/* Display notes list */}
          <div className="notes-list">
            {noteCount === 0 ? (
              <div className="notes-empty">No notes yet. Add one to get started.</div>
            ) : (
              notes.map((note) => (
                <div key={note.id} className={`note-item ${note._updating ? 'updating' : ''}`}>
                  {editingNoteId === note.id ? (
                    /* Edit mode */
                    <div className="note-edit">
                      <textarea
                        value={editingContent}
                        onChange={(e) => setEditingContent(e.target.value)}
                        className="notes-input"
                        rows="3"
                      />
                      <div style={{display: 'flex', gap: 10, justifyContent: 'flex-end', marginTop: 10}}>
                        <button
                          className="btn ghost sm"
                          onClick={cancelEdit}
                        >
                          Cancel
                        </button>
                        <button
                          className="btn ok sm"
                          onClick={() => handleEditNote(note.id)}
                          disabled={!editingContent.trim()}
                        >
                          <Icon name="check" size={12}/> Save
                        </button>
                      </div>
                    </div>
                  ) : (
                    /* Display mode */
                    <>
                      <div className="note-content">
                        <p className="note-text">{note.content}</p>
                        <div className="note-meta">
                          <span className="note-author">by {getUserName(note.created_by)}</span>
                          <span className="note-separator">·</span>
                          <span className="note-time">{formatDateTime(note.created_at)}</span>
                          {note.updated_at !== note.created_at && (
                            <>
                              <span className="note-separator">·</span>
                              <span className="note-edited">edited {formatDateTime(note.updated_at)}</span>
                            </>
                          )}
                        </div>
                      </div>
                      <div className="note-actions">
                        {note.created_by === (currentUser?.id || currentUser?._id) ? (
                          <>
                            <button
                              className="btn ghost xs"
                              onClick={() => startEdit(note)}
                              disabled={note._updating}
                              title="Edit this note"
                            >
                              <Icon name="edit" size={12}/>
                            </button>
                            <button
                              className="btn ghost xs"
                              onClick={() => onDelete({ note_id: note.id })}
                              disabled={note._updating}
                              title="Delete this note"
                            >
                              <Icon name="trash" size={12}/>
                            </button>
                          </>
                        ) : (
                          <span style={{fontSize: 11, color: 'var(--muted)'}}>Read-only</span>
                        )}
                      </div>
                    </>
                  )}
                </div>
              ))
            )}
          </div>

          {/* Add note form */}
          <div className="notes-add">
            <textarea
              value={newNoteContent}
              onChange={(e) => setNewNoteContent(e.target.value)}
              placeholder="Add a note..."
              className="notes-input"
              rows="3"
              onKeyDown={(e) => {
                if (e.key === 'Enter' && e.ctrlKey) {
                  handleAddNote();
                }
              }}
            />
            <div style={{display: 'flex', gap: 10, justifyContent: 'flex-end', marginTop: 10}}>
              <button
                className="btn ghost sm"
                onClick={() => setNewNoteContent('')}
                disabled={!newNoteContent}
              >
                Clear
              </button>
              <button
                className="btn ok sm"
                onClick={handleAddNote}
                disabled={!newNoteContent.trim()}
              >
                <Icon name="plus" size={12}/> Add Note
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// Helper function to get the lowest status from multiple handles
// Shows the status that needs the most attention (lowest priority in workflow)
// Status priority: missing < unverified < verified < qc
function getMostAdvancedStatus(handles) {
  if (!Array.isArray(handles) || handles.length === 0) {
    return { status: 'missing', sports: '', panel: '', merged: '' };
  }
  
  const priorities = {
    'missing': 1,        // Highest priority to show (needs most attention)
    'unverified': 2,
    'verified': 3,
    'qc': 4             // Lowest priority to show (completed)
  };
  
  return handles.reduce((worst, current) => {
    const currentPriority = priorities[current.status] || 1;
    const worstPriority = priorities[worst.status] || 1;
    return currentPriority < worstPriority ? current : worst;
  });
}

Object.assign(window, { Icon, Tile, Pill, TILE_LABELS, STATUS_META, computeCounts, overallStatus, computeProfileCounts, getActiveLocks, LockChip, getMostAdvancedStatus });
