/* WPSiteBeam Scanner — Files & Docs Tab
   Auto-split from Scanner.jsx.
*/
(function () {
  'use strict';
  const ScanEmptyState = window.ScanEmptyState;
  const Icon = window.Icon;

function ScannerFilesTab({ data }) {
  const { useState, useMemo } = React;

  /* Hooks must be called unconditionally before any early returns — see
     PagesTab for the full explanation of this React Rules of Hooks rule. */
  const [selected, setSelected] = useState(() => new Set());
  const [filterType, setFilterType] = useState('all');
  const [filterFlag, setFilterFlag] = useState('all');

  const seed = data?.files?.items || [];

  /* Dynamic empty state — tell the user what was checked, not a generic
     "nothing found". Matches pattern from ScannerContactTab social empty state. */
  if (!seed.length) {
    const pageCount = data?.pages || 0;
    const pagesFetched = Array.isArray(data?.pagesList) ? data.pagesList.length : 0;
    return (
      <div style={{ padding:'40px 24px', maxWidth:600, margin:'0 auto', textAlign:'center' }}>
        <div style={{ fontSize:'2rem', marginBottom:12, opacity:.4 }}>📄</div>
        <div style={{ fontWeight:700, color:'var(--text)', marginBottom:8, fontSize:'.9rem' }}>
          No files &amp; documents found
        </div>
        <div style={{ fontSize:'.8rem', color:'var(--dim)', lineHeight:1.6, marginBottom:16 }}>
          {pageCount > 0
            ? `Scanned ${pageCount} page${pageCount !== 1 ? 's' : ''} — no linked PDFs, Word docs, Excel sheets, or archives were detected. `
            : 'Document discovery runs on the scanned pages. '}
          File links (PDFs, .docx, .xlsx etc.) are extracted from page content during the per-page crawl.
        </div>
        <div style={{ background:'var(--beam-dim)', border:'1px solid var(--beam-dim)', borderRadius:8, padding:'12px 16px', fontSize:'.78rem', color:'var(--text-2)', lineHeight:1.6, textAlign:'left' }}>
          <strong style={{ color:'var(--text)' }}>If you know this site has documents:</strong> run a fresh <strong>Full</strong> or <strong>Deep scan</strong>.
          File detection was recently added and requires a new scan to activate. PDFs and docs linked in page content (Elementor lists, CTA blocks, resource pages) will appear here automatically.
        </div>
        <div style={{ marginTop:14, fontSize:'.72rem', color:'var(--dim)', lineHeight:1.5 }}>
          Checked file types: PDFs · Word (.doc, .docx) · Excel (.xls, .xlsx) · PowerPoint (.ppt, .pptx) · archives (.zip, .rar) · text (.txt, .rtf)
        </div>
      </div>
    );
  }

  const flagMeta = {
    'case':           { lbl:'Uppercase ext',        tone:'warn' },
    'spaces':         { lbl:'Contains spaces',      tone:'warn' },
    'date':           { lbl:'Non-ISO date',         tone:'warn' },
    'diacritics':     { lbl:'Diacritics',           tone:'warn' },
    'revision':       { lbl:'Revision markers',     tone:'warn' },
    'parens':         { lbl:'Parens in name',       tone:'warn' },
    'generic':        { lbl:'Generic filename',     tone:'warn' },
    'oversize':       { lbl:'Oversize (>2MB)',      tone:'warn' },
    'no-alt':         { lbl:'ADA: no alt text',     tone:'err', ada:true },
    'no-ocr':         { lbl:'ADA: no OCR layer',    tone:'err', ada:true },
    'scanned-image':  { lbl:'ADA: scanned image',   tone:'err', ada:true },
    'tags-missing':   { lbl:'ADA: PDF tags missing',tone:'err', ada:true },
    'non-pdf':        { lbl:'ADA: not PDF',         tone:'warn', ada:true },
    'non-accessible-format': { lbl:'ADA: inaccessible format', tone:'err', ada:true },
    'orphan':         { lbl:'Orphan (no page)',     tone:'dim' },
  };

  const filtered = useMemo(() => seed.filter(f => {
    if (filterType !== 'all' && f.type !== filterType) return false;
    if (filterFlag === 'ada')  return f.flags.some(x => flagMeta[x]?.ada);
    if (filterFlag === 'rename') return f.flags.some(x => ['case','spaces','date','diacritics','revision','parens','generic'].includes(x));
    if (filterFlag === 'oversize') return f.flags.includes('oversize');
    if (filterFlag === 'orphan')   return f.flags.includes('orphan');
    return true;
  }), [seed, filterType, filterFlag]);

  const typeCount = (t) => seed.filter(f => t === 'all' || f.type === t).length;
  const adaCount = seed.filter(f => f.flags.some(x => flagMeta[x]?.ada)).length;

  function toggle(id) {
    setSelected(prev => {
      const n = new Set(prev);
      if (n.has(id)) n.delete(id); else n.add(id);
      return n;
    });
  }
  function selectAll() {
    if (selected.size === filtered.length) setSelected(new Set());
    else setSelected(new Set(filtered.map(f => f.id)));
  }

  function sendToFileMap() {
    const count = selected.size || filtered.length;
    window.wpsbToast?.(`${count} file${count===1?'':'s'} queued for File Map — opening Redirects`, 'ok');
    setTimeout(() => window.WPSBD?.switchTab?.('redirects'), 400);
  }
  function exportCsv() {
    window.wpsbDownload?.('scanner-files.csv', seed.map(f => `"${f.url}",${f.type},"${f.size}","${f.page || ''}","${f.flags.join('|')}"`).join('\n'), 'text/csv');
  }

  const typeIcon = { pdf:'📄', image:'🖼️', doc:'📝' };

  return (
    <div>
      {/* Partial results notice — always shown */}
      <div style={{
        display:'flex', gap:10, alignItems:'flex-start',
        padding:'9px 13px', marginBottom:12,
        background:'var(--orange-dim)',
        border:'1px solid var(--orange-dim)',
        borderRadius:7, fontSize:'.76rem', color:'var(--dim)', lineHeight:1.6,
      }}>
        <span style={{ fontSize:'1rem', flexShrink:0, marginTop:1 }}>⚠</span>
        <span>
          <strong style={{ color:'var(--text)', fontWeight:600 }}>Partial results possible.</strong>
          {' '}Files linked only from forms, emails, password-protected pages, or loaded dynamically after page render may not be detected.
          Installing the WPSiteBeam plugin on the source site improves coverage.
        </span>
      </div>
      <div className="box info" style={{ marginBottom:12 }}>
        <Icon name="info" size={14}/>
        <div>
          <strong>{seed.length} files discovered</strong> across {data.pages} crawled pages.
          {' '}Rename-candidate, oversize, ADA-risk, and orphan files are pre-flagged.
          {' '}<strong>{adaCount} ADA-blocking</strong> documents require remediation for WCAG 2.1 AA.
        </div>
      </div>

      {/* Toolbar */}
      <div style={{ display:'flex', gap:8, flexWrap:'wrap', alignItems:'center', marginBottom:12 }}>
        <div className="tw-seg" role="group" aria-label="Filter by file type">
          <button type="button" className={filterType==='all'?'active':''} onClick={()=>setFilterType('all')}>All ({typeCount('all')})</button>
          <button type="button" className={filterType==='pdf'?'active':''} onClick={()=>setFilterType('pdf')}>PDF ({typeCount('pdf')})</button>
          <button type="button" className={filterType==='image'?'active':''} onClick={()=>setFilterType('image')}>Images ({typeCount('image')})</button>
          <button type="button" className={filterType==='doc'?'active':''} onClick={()=>setFilterType('doc')}>Docs ({typeCount('doc')})</button>
        </div>
        <div className="tw-seg" role="group" aria-label="Filter by flag">
          <button type="button" className={filterFlag==='all'?'active':''} onClick={()=>setFilterFlag('all')}>Any</button>
          <button type="button" className={filterFlag==='ada'?'active':''} onClick={()=>setFilterFlag('ada')} title="Accessibility blockers">🛡 ADA ({adaCount})</button>
          <button type="button" className={filterFlag==='rename'?'active':''} onClick={()=>setFilterFlag('rename')}>Rename</button>
          <button type="button" className={filterFlag==='oversize'?'active':''} onClick={()=>setFilterFlag('oversize')}>Oversize</button>
          <button type="button" className={filterFlag==='orphan'?'active':''} onClick={()=>setFilterFlag('orphan')}>Orphan</button>
        </div>
        <span style={{ flex:1 }}/>
        {selected.size > 0 && (
          <span style={{ fontSize:'.76rem', color:'var(--beam)', fontFamily:'var(--font-mono)' }}>
            {selected.size} selected
          </span>
        )}
        <button className="btn btn-primary btn-sm" onClick={sendToFileMap}>
          <Icon name="redirect" size={12}/>Send to File Map
        </button>
        <button className="btn btn-ghost btn-sm" onClick={exportCsv}>
          <Icon name="download" size={12}/>Export CSV
        </button>
      </div>

      {/* Files table */}
      <div className="card">
        <div className="card-body" style={{ padding:0, overflowX:'auto' }}>
          <table className="table">
            <thead>
              <tr>
                <th style={{ width:28 }}>
                  <input type="checkbox"
                         checked={filtered.length > 0 && selected.size === filtered.length}
                         ref={el => { if (el) el.indeterminate = selected.size > 0 && selected.size < filtered.length; }}
                         onChange={selectAll}
                         aria-label="Select all visible files"/>
                </th>
                <th>File</th>
                <th style={{ width:80 }}>Type</th>
                <th style={{ width:80 }}>Size</th>
                <th>Referenced on</th>
                <th>Flags</th>
                <th style={{ width:120 }}></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(f => {
                const hasAda = f.flags.some(x => flagMeta[x]?.ada);
                return (
                  <tr key={f.id} style={{ background: selected.has(f.id) ? 'var(--beam-dim)' : 'transparent' }}>
                    <td>
                      <input type="checkbox" checked={selected.has(f.id)} onChange={() => toggle(f.id)} aria-label={`Select ${f.url}`}/>
                    </td>
                    <td style={{ maxWidth:360 }}>
                      <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                        <span>{typeIcon[f.type] || '📄'}</span>
                        <code style={{ fontSize:'.74rem', wordBreak:'break-all' }}>{f.url}</code>
                      </div>
                    </td>
                    <td><span className="tag" style={{ fontSize:'.64rem' }}>{f.type.toUpperCase()}</span></td>
                    <td style={{ fontFamily:'var(--font-mono)', fontSize:'.74rem', color: f.flags.includes('oversize') ? 'var(--warn)' : 'var(--muted)' }}>{f.sizeLabel || f.size || '—'}</td>
                    <td style={{ fontSize:'.74rem' }}>
                      {f.page ? <code style={{ fontSize:'.72rem' }}>{f.page}</code> : <span style={{ color:'var(--dim)', fontStyle:'italic' }}>— orphan —</span>}
                    </td>
                    <td>
                      <div style={{ display:'flex', gap:4, flexWrap:'wrap' }}>
                        {f.flags.map(fl => {
                          const m = flagMeta[fl] || { lbl:fl, tone:'dim' };
                          const cls = m.tone === 'err' ? 'err' : m.tone === 'warn' ? 'warn' : '';
                          return <span key={fl} className={`tag ${cls}`} style={{ fontSize:'.62rem' }}>{m.ada ? '🛡 ' : ''}{m.lbl}</span>;
                        })}
                        {f.flags.length === 0 && <span style={{ fontSize:'.7rem', color:'var(--dim)' }}>—</span>}
                      </div>
                    </td>
                    <td>
                      <div style={{ display:'flex', gap:4 }}>
                        <button className="btn btn-ghost btn-sm" style={{ padding:'2px 6px', fontSize:'.7rem' }}
                                onClick={() => { setSelected(new Set([f.id])); sendToFileMap(); }}
                                title="Send this file to File Map">
                          <Icon name="redirect" size={11}/>Map
                        </button>
                        {hasAda && (
                          <button className="btn btn-ghost btn-sm" style={{ padding:'2px 6px', fontSize:'.7rem', color:'var(--err)' }}
                                  onClick={() => window.wpsbToast?.('Added to ADA Remediation queue', 'ok')}
                                  title="Queue for ADA remediation">
                            🛡 Fix
                          </button>
                        )}
                      </div>
                    </td>
                  </tr>
                );
              })}
              {filtered.length === 0 && (
                <tr>
                  <td colSpan={7} style={{ padding:'24px 12px', textAlign:'center', color:'var(--dim)', fontSize:'.84rem' }}>
                    No files match the current filters.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>

      {/* Summary row */}
      <div className="grid grid-4" style={{ marginTop:12, gap:10 }}>
        <div className="card"><div className="card-body" style={{ padding:'10px 14px' }}>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', letterSpacing:1, fontFamily:'var(--font-mono)' }}>TOTAL FILES</div>
          <div style={{ fontSize:'1.4rem', fontWeight:700, marginTop:2 }}>{seed.length}</div>
        </div></div>
        <div className="card"><div className="card-body" style={{ padding:'10px 14px' }}>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', letterSpacing:1, fontFamily:'var(--font-mono)' }}>ADA-BLOCKING</div>
          <div style={{ fontSize:'1.4rem', fontWeight:700, marginTop:2, color:'var(--err)' }}>{adaCount}</div>
        </div></div>
        <div className="card"><div className="card-body" style={{ padding:'10px 14px' }}>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', letterSpacing:1, fontFamily:'var(--font-mono)' }}>OVERSIZE</div>
          <div style={{ fontSize:'1.4rem', fontWeight:700, marginTop:2, color:'var(--warn)' }}>{seed.filter(f=>f.flags.includes('oversize')).length}</div>
        </div></div>
        <div className="card"><div className="card-body" style={{ padding:'10px 14px' }}>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', letterSpacing:1, fontFamily:'var(--font-mono)' }}>ORPHANED</div>
          <div style={{ fontSize:'1.4rem', fontWeight:700, marginTop:2, color:'var(--dim)' }}>{seed.filter(f=>f.flags.includes('orphan')).length}</div>
        </div></div>
      </div>
    </div>
  );
}


window.ScannerFilesTab = ScannerFilesTab;
})();
