// Primus IQ — Project Detail Screen

const PROJECT_FILES_PAGE_SIZE = 50;   // rows rendered per "page" — windowed like Library so a big project doesn't mount every file at once

const ScreenProjectDetail = ({ setRoute, onStartChat, chatSessions = [], onOpenChat, openTagging, openSharePoint, openTextInput, openUrlInput, openInvite, openEditProject, onDeleteProject, uploadedFiles, removeFile, downloadFile, editFile, viewFile, activeProject, projectMembers, maintenance = false }) => {
  const [dragHover, setDragHover] = React.useState(false);
  const [pendingCount, setPendingCount] = React.useState(0);
  const [tab, setTab] = React.useState('chats');             // 'chats' | 'sources'
  const [composerVal, setComposerVal] = React.useState('');
  const [composerFocused, setComposerFocused] = React.useState(false);
  const [composerFile, setComposerFile] = React.useState(null);   // doc attached to the launching chat
  const composerFileRef = React.useRef(null);
  const [filter, setFilter] = React.useState('');
  const [visibleFiles, setVisibleFiles] = React.useState(PROJECT_FILES_PAGE_SIZE);
  const [menuOpen, setMenuOpen] = React.useState(false);     // project actions dropdown
  const menuRef = React.useRef(null);

  React.useEffect(() => {
    if (!menuOpen) return;
    const handler = (e) => { if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false); };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [menuOpen]);

  const projectName = activeProject?.name || 'Project';
  const projectPractice = activeProject?.practice || '';

  const fq = filter.trim().toLowerCase();
  // Real chat sessions scoped to this project (single source of truth = app sidebar list).
  const projectChats = chatSessions.filter(s => s.project_id === activeProject?.id);
  const filteredChats = fq ? projectChats.filter(c => (c.title || '').toLowerCase().includes(fq)) : projectChats;
  const filteredFiles = fq ? uploadedFiles.filter(f => (f.name || '').toLowerCase().includes(fq)) : uploadedFiles;
  // Windowed rendering — reset to the first page whenever the file search changes.
  React.useEffect(() => { setVisibleFiles(PROJECT_FILES_PAGE_SIZE); }, [fq]);
  const shownFiles = filteredFiles.slice(0, visibleFiles);
  const hasMoreFiles = filteredFiles.length > visibleFiles;

  React.useEffect(() => {
    if (!activeProject?.id) return;
    PrimusAPI.listJoinRequests(activeProject.id)
      .then(data => setPendingCount((data || []).length))
      .catch(() => setPendingCount(0));
  }, [activeProject?.id]);

  const submitComposer = () => {
    if (maintenance) return;               // chat is greyed out in maintenance mode
    const q = composerVal.trim();
    if (!q) return;
    const file = composerFile;
    setComposerVal('');
    setComposerFile(null);
    // Open a real, project-scoped chat in the main chat screen (sends project_id) and
    // carry any attached doc so it's saved to that new session as chat context.
    onStartChat && onStartChat(activeProject?.id, q, file);
  };
  const canSend = !maintenance && !!composerVal.trim();

  return (
    <div style={{ ...contentArea, overflowY: 'auto' }}>
      <div className="mobile-p-16" style={{ padding: '32px 40px 32px', maxWidth: 1440, margin: '0 auto', display: 'flex', flexDirection: 'column' }}>
        {/* Crumb */}
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: 'var(--mute)', marginBottom: 14 }}>
          <button onClick={() => setRoute('projects')} style={crumbBtn}>Projects</button>
          <span>/</span>
          <span style={{ color: 'var(--ink)', fontWeight: 500 }}>{projectName}</span>
        </div>

        {/* Header */}
        <div className="mobile-stack" style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 24, marginBottom: 22 }}>
          <div className="mobile-stack" style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>
            <div style={{
              width: 52, height: 52, borderRadius: 13,
              background: 'var(--maroon)', color: 'white',
              display: 'grid', placeItems: 'center',
              boxShadow: '0 8px 20px rgba(122,28,28,0.2)',
            }}>
              <PIcon name="folder" size={22} color="white" />
            </div>
            <div>
              <h1 className="serif" style={{ fontSize: 28, fontWeight: 500, margin: 0, letterSpacing: '-0.02em', lineHeight: 1.1 }}>{projectName}</h1>
              <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6, display: 'flex', alignItems: 'center', gap: 10 }}>
                {projectPractice && <span className="tag-pill">{projectPractice}</span>}
                <span>· {uploadedFiles.length} files</span>
              </div>
            </div>
          </div>
          <div className="mobile-stack" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {projectMembers && projectMembers.length > 0 && (
              <div style={{ display: 'flex' }}>
                {projectMembers.slice(0, 3).map((m, i) => (
                  <div key={m.user_id} className="avatar" style={{ marginLeft: i ? -7 : 0, width: 28, height: 28, fontSize: 11 }}>
                    {(m.full_name || '?')[0].toUpperCase()}
                  </div>
                ))}
                {projectMembers.length > 3 && (
                  <div className="avatar muted" style={{ marginLeft: -7, width: 28, height: 28, fontSize: 10 }}>+{projectMembers.length - 3}</div>
                )}
              </div>
            )}
            <button className="btn-primary" onClick={openInvite} style={{ position: 'relative' }}>
              <PIcon name="plus" size={14} color="white" /> Invite
              {pendingCount > 0 && (
                <span style={{
                  position: 'absolute', top: -5, right: -5,
                  width: 16, height: 16, borderRadius: 8,
                  background: 'var(--bg-card)', color: 'var(--maroon)',
                  fontSize: 10, fontWeight: 700,
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  border: '1.5px solid var(--maroon)',
                }}>{pendingCount}</span>
              )}
            </button>
            <div ref={menuRef} style={{ position: 'relative' }}>
              <button className="btn-ghost" style={{ width: 40, justifyContent: 'center' }} onClick={() => setMenuOpen(o => !o)}>
                <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"><circle cx="3" cy="8" r="1.4"/><circle cx="8" cy="8" r="1.4"/><circle cx="13" cy="8" r="1.4"/></svg>
              </button>
              {menuOpen && (
                <div style={{
                  position: 'absolute', right: 0, top: '100%', marginTop: 6, width: 160,
                  background: 'var(--bg-card)', border: '1px solid var(--line-2)', borderRadius: 10,
                  boxShadow: 'var(--shadow-md)', zIndex: 40, overflow: 'hidden',
                }}>
                  <button onClick={() => { setMenuOpen(false); openEditProject(); }} style={fileMenuItemStyle}>
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M11.5 2.5l2 2L6 12l-2.5.5L4 10l7.5-7.5z" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>
                    Edit project
                  </button>
                  <div style={{ height: 1, background: 'var(--line)' }} />
                  <button onClick={() => { setMenuOpen(false); onDeleteProject && onDeleteProject(); }} style={{ ...fileMenuItemStyle, color: 'var(--maroon)' }}>
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M3 5h10M6 5V3h4v2M7 8v4M9 8v4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/><path d="M5 5l.5 8h5l.5-8" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/></svg>
                    Delete project
                  </button>
                </div>
              )}
            </div>
          </div>
        </div>

        {/* TOP ROW: New chat composer (left) + Add sources (right) — sized to content */}
        <div className="pi-grid-2" style={{ gap: 20, marginBottom: 18 }}>
          {/* LEFT: New chat in <project> */}
          <div style={panelCard}>
            <div style={panelHeader}>
              <div>
                <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>New chat in {projectName}</div>
                <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 2 }}>Ask anything — this project's files are referenced automatically.</div>
              </div>
            </div>
            <div style={{ padding: 20, display: 'flex', flexDirection: 'column', gap: 14 }}>
              <div style={{
                background: 'var(--bg-card)', borderRadius: 14,
                border: `1px solid ${composerFocused ? 'var(--maroon-20)' : 'var(--line-2)'}`,
                boxShadow: composerFocused ? '0 0 0 4px var(--maroon-06)' : 'none',
                transition: 'all 0.15s',
                padding: '12px 12px 10px 14px',
              }}>
                <textarea
                  value={composerVal}
                  onChange={e => setComposerVal(e.target.value)}
                  onFocus={() => setComposerFocused(true)}
                  onBlur={() => setComposerFocused(false)}
                  onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); submitComposer(); } }}
                  disabled={maintenance}
                  rows={3}
                  placeholder={maintenance ? 'Chat is temporarily unavailable.' : `Ask Primus IQ about ${projectName}…`}
                  style={{
                    width: '100%', border: 'none', resize: 'none',
                    fontFamily: 'inherit', fontSize: 14, color: 'var(--ink)',
                    background: 'transparent', lineHeight: 1.5, padding: '2px 0',
                    outline: 'none',
                  }}
                />
                {composerFile && (
                  <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 6 }}>
                    <div style={{
                      display: 'inline-flex', alignItems: 'center', gap: 6,
                      padding: '4px 10px', borderRadius: 8,
                      background: 'var(--bg-soft)', border: '1px solid var(--line-2)',
                      fontSize: 12, color: 'var(--ink-2)', maxWidth: 280,
                    }}>
                      <svg width="12" height="12" viewBox="0 0 16 16" fill="none">
                        <path d="M4 2h6l4 4v8a1 1 0 01-1 1H3a1 1 0 01-1-1V3a1 1 0 011-1z" stroke="currentColor" strokeWidth="1.4"/>
                        <path d="M10 2v4h4" stroke="currentColor" strokeWidth="1.4"/>
                      </svg>
                      <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{composerFile.name}</span>
                      <button onClick={() => setComposerFile(null)} style={{
                        background: 'none', border: 'none', cursor: 'pointer',
                        color: 'var(--mute)', padding: 0, lineHeight: 1, flexShrink: 0,
                      }}>×</button>
                    </div>
                  </div>
                )}
                <input
                  ref={composerFileRef} type="file" style={{ display: 'none' }}
                  onChange={e => { const f = e.target.files?.[0]; if (f) setComposerFile(f); e.target.value = ''; }}
                />
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
                  <button onClick={() => composerFileRef.current?.click()} title="Attach a document" style={pdComposerIconBtn}>
                    <PIcon name="plus" size={14} color="var(--ink-2)" />
                  </button>
                  <button style={pdComposerChip}>
                    <span style={{ width: 6, height: 6, borderRadius: 3, background: 'var(--maroon)' }} />
                    Primus IQ
                  </button>
                  <div style={{ flex: 1 }} />
                  <button
                    onClick={submitComposer}
                    disabled={!canSend}
                    style={{
                      width: 32, height: 32, borderRadius: 9,
                      background: canSend ? 'var(--maroon)' : 'var(--bg-soft)',
                      color: canSend ? 'white' : 'var(--mute-2)',
                      border: 'none', cursor: canSend ? 'pointer' : 'default',
                      display: 'grid', placeItems: 'center', transition: 'all 0.15s',
                    }}>
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
                      <path d="M8 12V4M4 8l4-4 4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
                    </svg>
                  </button>
                </div>
              </div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                {['Summarize the latest doc', 'Compare these proposals', 'Draft a status memo'].map(s => (
                  <button key={s} onClick={() => setComposerVal(s)} disabled={maintenance}
                    style={maintenance ? { ...pdChip, opacity: 0.5, cursor: 'default' } : pdChip}>{s}</button>
                ))}
              </div>
              {maintenance && (
                <div style={{ fontSize: 12, color: 'var(--mute)', textAlign: 'center' }}>
                  Chat is coming soon — temporarily unavailable.
                </div>
              )}
            </div>
          </div>

          {/* RIGHT: dropzone + source quick-buttons */}
          <div style={panelCard}>
            <div style={panelHeader}>
              <div>
                <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>Add to this project</div>
                <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 2 }}>Upload or connect a source. You'll set confidentiality and practice next.</div>
              </div>
            </div>
            <div style={{ padding: 20, display: 'flex', flexDirection: 'column', gap: 14 }}>
              <label
                onDragEnter={e => { e.preventDefault(); setDragHover(true); }}
                onDragOver={e => { e.preventDefault(); setDragHover(true); }}
                onDragLeave={() => setDragHover(false)}
                onDrop={e => { e.preventDefault(); setDragHover(false); openTagging(Array.from(e.dataTransfer.files)); }}
                style={{
                  height: 150, borderRadius: 14,
                  border: `1.5px dashed ${dragHover ? 'var(--maroon)' : 'var(--line-2)'}`,
                  background: dragHover ? 'var(--maroon-wash)' : 'var(--bg-soft)',
                  display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
                  cursor: 'pointer', transition: 'all 0.15s', gap: 8, padding: 16, textAlign: 'center',
                  position: 'relative',
                }}>
                <input type="file" multiple onChange={e => { openTagging(Array.from(e.target.files)); e.target.value = ''; }} style={{
                  position: 'absolute', inset: 0, opacity: 0, cursor: 'pointer',
                }}/>
                <div style={{
                  width: 40, height: 40, borderRadius: 11,
                  background: 'var(--bg-card)', border: '1px solid var(--line)',
                  display: 'grid', placeItems: 'center', boxShadow: 'var(--shadow-xs)',
                }}>
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
                    <path d="M12 16V5M7 10l5-5 5 5" stroke="var(--maroon)" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/>
                    <path d="M4 16v2.5A1.5 1.5 0 0 0 5.5 20h13a1.5 1.5 0 0 0 1.5-1.5V16" stroke="var(--maroon)" strokeWidth="1.7" strokeLinecap="round"/>
                  </svg>
                </div>
                <div>
                  <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>Drop files here</div>
                  <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 3 }}>
                    or <span style={{ color: 'var(--maroon)', fontWeight: 600 }}>click to browse</span>
                  </div>
                </div>
                <div style={{ fontSize: 11, color: 'var(--mute-2)' }}>
                  PDF, DOCX, PPTX, XLSX, MP4, images · 100 MB each
                </div>
              </label>

              <div>
                <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--mute)', letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 10 }}>
                  Or add from
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 8 }}>
                  <SourceBtn icon={<UploadIcon/>} label="Upload" onClick={() => {
                    const inp = document.createElement('input');
                    inp.type = 'file'; inp.multiple = true;
                    inp.onchange = e => openTagging(Array.from(e.target.files));
                    inp.click();
                  }}/>
                  <SourceBtn icon={<TextIcon/>}        label="Text input" onClick={() => openTextInput && openTextInput()}/>
                  <SourceBtn icon={<UrlIcon/>}         label="URL"        onClick={() => openUrlInput && openUrlInput()}/>
                  <SourceBtn icon={<SharepointIcon/>}  label="SharePoint" onClick={() => openSharePoint && openSharePoint()}/>
                </div>
              </div>
            </div>
          </div>
        </div>

        {/* TABS + LIST PANEL — bounded height, scrolls internally */}
        <div className="mobile-h-auto" style={{ height: 'calc(100vh - 480px)', minHeight: 320, display: 'flex', flexDirection: 'column' }}>
          <div className="mobile-stack" style={{ display: 'flex', gap: 4, marginBottom: 12, alignItems: 'center' }}>
            <PdTab active={tab === 'chats'}   onClick={() => setTab('chats')}   count={projectChats.length}>Chats</PdTab>
            <PdTab active={tab === 'sources'} onClick={() => setTab('sources')} count={uploadedFiles.length}>Sources</PdTab>
            <div style={{ flex: 1 }} />
            <div className="search-input" style={{ width: 260, height: 34 }}>
              <PIcon name="search" size={14} color="var(--mute)" />
              <input
                value={filter}
                onChange={e => setFilter(e.target.value)}
                placeholder={tab === 'chats' ? 'Filter chats' : 'Filter files'}
              />
              {filter && (
                <button onClick={() => setFilter('')} title="Clear" style={{
                  background: 'transparent', border: 'none', cursor: 'pointer',
                  color: 'var(--mute)', padding: 0, display: 'grid', placeItems: 'center',
                  width: 18, height: 18,
                }}>
                  <svg width="12" height="12" viewBox="0 0 16 16" fill="none">
                    <path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/>
                  </svg>
                </button>
              )}
            </div>
          </div>

          <div style={{ ...panelCard, flex: 1, minHeight: 320 }}>
            {tab === 'chats' ? (
              <div style={{ padding: '8px 10px 12px', flex: 1, overflow: 'auto' }}>
                {filteredChats.length === 0 ? (
                  <div style={{ padding: '64px 20px 56px', textAlign: 'center' }}>
                    <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>{projectChats.length === 0 ? 'No chats yet' : 'No chats match your search'}</div>
                    <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6 }}>
                      {projectChats.length === 0
                        ? <>Start one from the composer above — chats in <span style={{ color: 'var(--ink-2)', fontWeight: 500 }}>{projectName}</span> live here.</>
                        : <>Try a different term.</>}
                    </div>
                  </div>
                ) : filteredChats.map(c => (
                  <button key={c.session_id} onClick={() => onOpenChat && onOpenChat(c.session_id)} style={pdChatRow}
                    onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <div style={{
                      width: 32, height: 32, borderRadius: 9,
                      background: 'var(--maroon-wash)', display: 'grid', placeItems: 'center', flexShrink: 0,
                    }}>
                      <PIcon name="chat" size={14} color="var(--maroon)" />
                    </div>
                    <div style={{ flex: 1, minWidth: 0, textAlign: 'left' }}>
                      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{c.title || 'Untitled chat'}</div>
                      <div style={{ fontSize: 12, color: 'var(--mute)', marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{(c.message_count || 0)} message{c.message_count === 1 ? '' : 's'}</div>
                    </div>
                    <div style={{ fontSize: 11, color: 'var(--mute-2)', flexShrink: 0 }}>{c.last_message_at ? new Date(c.last_message_at).toLocaleDateString() : ''}</div>
                  </button>
                ))}
              </div>
            ) : (
              <React.Fragment>
                <div style={{ padding: '6px 10px 12px', flex: 1, overflow: 'auto', display: 'flex', flexDirection: 'column' }}>
                  {uploadedFiles.length === 0 ? (
                    <div style={{ padding: '64px 20px 56px', textAlign: 'center' }}>
                      <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>No files yet</div>
                      <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6 }}>Drop or pick a source on the right to begin.</div>
                    </div>
                  ) : filteredFiles.length === 0 ? (
                    <div style={{ padding: '64px 20px 56px', textAlign: 'center' }}>
                      <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)' }}>No files match your search</div>
                      <div style={{ fontSize: 13, color: 'var(--mute)', marginTop: 6 }}>Try a different term.</div>
                    </div>
                  ) : shownFiles.map(f => (
                    <FileRow key={f.id} f={f}
                      onRemove={() => removeFile(f.id)}
                      onDownload={downloadFile ? () => downloadFile(f.id) : null}
                      onEdit={editFile ? () => editFile(f) : null}
                      onView={viewFile ? () => viewFile(f) : null}
                    />
                  ))}
                  {hasMoreFiles && (
                    <div style={{ padding: '14px 18px', textAlign: 'center' }}>
                      <button onClick={() => setVisibleFiles(v => v + PROJECT_FILES_PAGE_SIZE)} className="btn-secondary" style={{ height: 34 }}>
                        Load more · showing {shownFiles.length} of {filteredFiles.length}
                      </button>
                    </div>
                  )}
                </div>
                <div style={{
                  padding: '10px 18px', borderTop: '1px solid var(--line)',
                  fontSize: 12, color: 'var(--mute)',
                  display: 'flex', justifyContent: 'space-between', alignItems: 'center',
                }}>
                  <span>{fq ? `${filteredFiles.length} of ${uploadedFiles.length}` : uploadedFiles.length} files in this project</span>
                </div>
              </React.Fragment>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

const panelCard = {
  background: 'var(--bg-card)', border: '1px solid var(--line)', borderRadius: 16,
  display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0,
};
const panelHeader = {
  padding: '14px 20px', borderBottom: '1px solid var(--line)',
  display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
};

// ── Project Detail — supporting bits ──────────────────────────────────────────
const PdTab = ({ active, onClick, children, count }) => (
  <button onClick={onClick} style={{
    padding: '8px 14px', borderRadius: 999,
    background: active ? 'var(--bg-soft)' : 'transparent',
    border: '1px solid', borderColor: active ? 'var(--line-2)' : 'transparent',
    fontSize: 13, fontWeight: active ? 600 : 500,
    color: active ? 'var(--ink)' : 'var(--mute)',
    cursor: 'pointer', fontFamily: 'inherit',
    transition: 'all 0.15s',
    display: 'inline-flex', alignItems: 'center', gap: 6,
  }}>
    {children}
    <span style={{ color: active ? 'var(--mute)' : 'var(--mute-2)', fontWeight: 500, fontSize: 12 }}>· {count}</span>
  </button>
);

const pdComposerIconBtn = {
  width: 28, height: 28, borderRadius: 7,
  background: 'transparent', border: '1px solid var(--line-2)',
  cursor: 'pointer', display: 'grid', placeItems: 'center',
};
const pdComposerChip = {
  height: 28, padding: '0 10px', borderRadius: 7,
  background: 'transparent', border: '1px solid var(--line-2)',
  cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 6,
  fontSize: 12, color: 'var(--ink-2)', fontFamily: 'inherit', fontWeight: 500,
};
const pdChip = {
  padding: '6px 12px', borderRadius: 999,
  background: 'var(--bg-card)', border: '1px solid var(--line)',
  fontSize: 12, color: 'var(--ink-2)', fontFamily: 'inherit', fontWeight: 500,
  cursor: 'pointer',
};
const pdChatRow = {
  display: 'flex', alignItems: 'center', gap: 12,
  padding: '12px 14px', borderRadius: 10,
  background: 'transparent', border: 'none', cursor: 'pointer',
  width: '100%', fontFamily: 'inherit',
  transition: 'background 0.15s',
};

// ── Full-screen chat view, opened from inside a project ──────────────────────
const ProjectChatView = ({ chat, projectName, onBack, onSend }) => {
  const [val, setVal] = React.useState('');
  const [focused, setFocused] = React.useState(false);
  const scrollRef = React.useRef(null);
  React.useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  }, [chat?.messages?.length]);

  const send = () => {
    const t = val.trim();
    if (!t) return;
    onSend(t);
    setVal('');
  };

  return (
    <div style={contentArea}>
      <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
        {/* Header: back arrow + project crumb signalling the chat origin */}
        <div style={{
          padding: '16px 32px', borderBottom: '1px solid var(--line)',
          display: 'flex', alignItems: 'center', gap: 14, background: 'var(--bg)',
        }}>
          <button onClick={onBack} title="Back to project" style={{
            width: 34, height: 34, borderRadius: 9,
            background: 'var(--bg-soft)', border: '1px solid var(--line)',
            cursor: 'pointer', display: 'grid', placeItems: 'center', flexShrink: 0,
          }}>
            <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
              <path d="M10 12L6 8l4-4" stroke="var(--ink)" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>

          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            padding: '6px 12px', borderRadius: 999,
            background: 'var(--maroon-wash)', border: '1px solid var(--maroon-20)',
            cursor: 'pointer',
          }}
            onClick={onBack}
            title={`Chat opened from ${projectName}`}
          >
            <PIcon name="folder" size={13} color="var(--maroon)" />
            <span style={{ fontSize: 12, color: 'var(--maroon)', fontWeight: 600 }}>From {projectName}</span>
          </div>

          <div style={{ fontSize: 14, color: 'var(--ink)', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', flex: 1, minWidth: 0 }}>
            {chat.title}
          </div>
        </div>

        {/* Messages */}
        <div ref={scrollRef} style={{ flex: 1, overflow: 'auto', padding: '28px 0' }}>
          <div style={{ maxWidth: 760, margin: '0 auto', padding: '0 32px', display: 'flex', flexDirection: 'column', gap: 14 }}>
            {(chat.messages || []).map((m, i) => (
              <div key={i} style={{
                alignSelf: m.role === 'user' ? 'flex-end' : 'flex-start',
                maxWidth: '82%',
                background: m.role === 'user' ? 'var(--maroon)' : 'transparent',
                color: m.role === 'user' ? 'white' : 'var(--ink)',
                padding: m.role === 'user' ? '12px 16px' : '12px 0px', borderRadius: 14,
                border: 'none',
                fontSize: 14, lineHeight: 1.55, whiteSpace: 'pre-wrap',
              }}>{m.text}</div>
            ))}
            {(chat.messages || []).length === 1 && (
              <div style={{ alignSelf: 'flex-start', maxWidth: '82%', color: 'var(--mute)', fontSize: 13, padding: '4px 4px', fontStyle: 'italic' }}>
                Primus IQ is offline in this preview — responses won't generate. UI shell only.
              </div>
            )}
          </div>
        </div>

        {/* Composer */}
        <div style={{ padding: '0 0 24px' }}>
          <div style={{ maxWidth: 760, margin: '0 auto', padding: '0 32px' }}>
            <div style={{
              background: 'var(--bg-card)', borderRadius: 16,
              border: `1px solid ${focused ? 'var(--maroon-20)' : 'var(--line-2)'}`,
              boxShadow: focused ? '0 0 0 4px var(--maroon-06)' : '0 2px 10px rgba(60,30,20,0.04)',
              transition: 'all 0.15s',
              padding: '12px 12px 10px 16px',
            }}>
              <textarea
                value={val}
                onChange={e => setVal(e.target.value)}
                onFocus={() => setFocused(true)}
                onBlur={() => setFocused(false)}
                onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }}
                rows={2}
                placeholder={`Reply in ${projectName}`}
                style={{
                  width: '100%', border: 'none', resize: 'none',
                  fontFamily: 'inherit', fontSize: 15, color: 'var(--ink)',
                  background: 'transparent', lineHeight: 1.5, padding: '2px 0', outline: 'none',
                }}
              />
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
                <div style={{ flex: 1 }} />
                <button onClick={send} disabled={!val.trim()} style={{
                  width: 34, height: 34, borderRadius: 10,
                  background: val.trim() ? 'var(--maroon)' : 'var(--bg-soft)',
                  color: val.trim() ? 'white' : 'var(--mute-2)',
                  border: 'none', cursor: val.trim() ? 'pointer' : 'default',
                  display: 'grid', placeItems: 'center',
                }}>
                  <svg width="14" height="14" viewBox="0 0 16 16" fill="none">
                    <path d="M8 12V4M4 8l4-4 4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

const FileRow = ({ f, onRemove, onDownload, onEdit, onView }) => {
  const [menuOpen, setMenuOpen] = React.useState(false);
  const menuRef = React.useRef(null);

  React.useEffect(() => {
    if (!menuOpen) return;
    const handler = (e) => {
      if (menuRef.current && !menuRef.current.contains(e.target)) setMenuOpen(false);
    };
    document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [menuOpen]);

  return (
    <div onClick={() => onView && onView()} style={{
      padding: '10px 12px', borderRadius: 10, display: 'flex', alignItems: 'center', gap: 12,
      cursor: onView ? 'pointer' : 'default', transition: 'background 0.15s',
    }}
    onMouseEnter={e => e.currentTarget.style.background = 'var(--bg-soft)'}
    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
    >
      <FileBadge ext={f.ext} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13, color: 'var(--ink)', fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
          {f.name}
        </div>
        <div style={{ fontSize: 11, color: 'var(--mute)', marginTop: 3, display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
          <span>{f.size}</span>
          <span>·</span>
          <span>{f.added || 'just now'}</span>

          {f.status && (
            <>
              <span>·</span>
              <span className={`status-text ${f.status}`}>
                {
                  f.status === 'graph_complete' ? 'Published to AI'
                  : f.status === 'dirty_ready'  ? 'AI Search Ready'
                  : f.status === 'complete'     ? 'File Saved'
                  : f.status === 'failed'       ? 'Save Failed'
                  : f.status
                }
              </span>
            </>
          )}
        </div>
      </div>
      {f.conf && <span className={`conf ${f.conf} mobile-hide`}> {CONF_LABELS[f.conf] || f.conf} </span>}
      <div ref={menuRef} style={{ position: 'relative' }}>
        <button onClick={(e) => { e.stopPropagation(); setMenuOpen(o => !o); }} style={{
          width: 28, height: 28, borderRadius: 7, background: 'transparent', border: 'none',
          cursor: 'pointer', color: 'var(--mute)', display: 'grid', placeItems: 'center',
        }}
        onMouseEnter={e => { e.currentTarget.style.background = 'var(--bg-soft)'; e.currentTarget.style.color = 'var(--ink)'; }}
        onMouseLeave={e => { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = 'var(--mute)'; }}
        >
          <svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><circle cx="3" cy="8" r="1.4"/><circle cx="8" cy="8" r="1.4"/><circle cx="13" cy="8" r="1.4"/></svg>
        </button>
        {menuOpen && (
          <div style={{
            position: 'absolute', right: 0, top: '100%', marginTop: 4, width: 140,
            background: 'var(--bg-card)', border: '1px solid var(--line-2)', borderRadius: 10,
            boxShadow: 'var(--shadow-md)', zIndex: 30, overflow: 'hidden',
          }}>
            {onDownload && (
              <button onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onDownload(); }} style={fileMenuItemStyle}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M8 3v8M4 8l4 4 4-4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/><path d="M3 13h10" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/></svg>
                Download
              </button>
            )}
            {onEdit && (
              <button onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onEdit(); }} style={fileMenuItemStyle}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M11 2l3 3-8 8-3.5.5.5-3.5 8-8z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>
                Edit tags &amp; visibility
              </button>
            )}
            {onRemove && (
              <button onClick={(e) => { e.stopPropagation(); setMenuOpen(false); onRemove(); }} style={{ ...fileMenuItemStyle, color: 'var(--maroon)' }}>
                <svg width="13" height="13" viewBox="0 0 16 16" fill="none"><path d="M3 5h10M6 5V3h4v2M7 8v4M9 8v4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/><path d="M5 5l.5 8h5l.5-8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                Delete
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
};

const crumbBtn = {
  background: 'transparent', border: 'none', cursor: 'pointer',
  fontSize: 13, fontFamily: 'inherit', color: 'var(--mute)', padding: 0,
};

Object.assign(window, {
  ScreenProjectDetail,
  ProjectChatView,
  FileRow,
  crumbBtn,
});
