/* ============================================================
   Student — Documents (master checklist)
   Student-submitted uploads only. Items handled by other modules
   (registration / medical / theory / tests / attendance / RPTO cert)
   live in their own modules, not here.
   ============================================================ */

function StudentDocuments({ ctx, rec }) {
  const { setToast, setRoute } = ctx;
  const [filter, setFilter] = useState('all');
  const [openId, setOpenId] = useState(null);

  const eff = (d) => window.effectiveDocStatus(rec, d);

  const counts = window.DOCUMENTS.reduce((acc, d) => {
    const s = eff(d);
    acc[s] = (acc[s] || 0) + 1;
    acc.all++;
    return acc;
  }, { all: 0 });

  // Pending = anything not yet uploaded AND not yet verified
  // (covers not-started + downloaded + rejected).
  const pendingCount = window.DOCUMENTS.filter(d => {
    const s = eff(d);
    return s !== 'uploaded' && s !== 'verified';
  }).length;

  const filtered = window.DOCUMENTS.filter(d => {
    if (filter === 'all') return true;
    if (filter === 'pending') {
      const s = eff(d);
      return s !== 'uploaded' && s !== 'verified';
    }
    return eff(d) === filter;
  });

  const ix = (id) => window.DOCUMENTS.findIndex(d => d.id === id);

  return (
    <div className="module">
      <ModuleHeader
        crumbs={`DOCUMENTS`}
        title={tr("Document uploads")}
        sub={tr("Documents you submit as a student. Scanned PDF or photo per item, under 2 MB each.")}
        right={
          <div className="row" style={{gap:8}}>
            <div className="pill pill-good"><i className="dotty"/>{counts.verified || 0} {tr('verified')}</div>
            <div className="pill pill-warn"><i className="dotty"/>{counts.uploaded || 0} {tr('awaiting')}</div>
            <div className="pill pill-ghost"><i className="dotty"/>{pendingCount} {tr('to start')}</div>
          </div>
        }
      />

      {/* Tabs */}
      <div className="tabs">
        {[
          { id:'all',         lbl:'All',         c: counts.all },
          { id:'pending',     lbl:'Pending',     c: pendingCount },
          { id:'uploaded',    lbl:'Awaiting verification', c: counts.uploaded || 0 },
          { id:'verified',    lbl:'Verified',    c: counts.verified || 0 },
          { id:'rejected',    lbl:'Rejected',    c: counts.rejected || 0 },
        ].map(t => (
          <button key={t.id} className={cls('tab', filter===t.id && 'active')} onClick={()=>setFilter(t.id)}>
            {tr(t.lbl)}<span className="count">{t.c}</span>
          </button>
        ))}
      </div>

      <div className="grid g-side">
        {/* Documents list */}
        <div className="card" style={{padding:0}}>
          <div className="list">
            {filtered.map(doc => {
              // Legacy student records were created before today's
              // DOCUMENTS list — fall back to a blank cell so the row
              // renders (and the first upload will hydrate the doc).
              const docState = (rec.documents && rec.documents[doc.id]) || {
                status: 'not-started', files: [], rejectionNote: '',
              };
              return (
                <DocRow key={doc.id} doc={doc} state={docState} ix={ix(doc.id)+1}
                        open={openId === doc.id} onToggle={()=>setOpenId(openId === doc.id ? null : doc.id)}
                        rec={rec} setToast={setToast} setRoute={setRoute}/>
              );
            })}
          </div>
        </div>

        {/* Side — tips */}
        <div className="stack">
          <div className="card">
            <div className="card-hd"><h3>{tr('What goes here?')}</h3></div>
            <div className="card-body small muted" style={{lineHeight:1.6}}>
              <p style={{margin:'0 0 8px'}}>{tr('Only the documents you personally submit. Registration, Medical, Theory and progress / attendance / certificate live in their own modules.')}</p>
              <p style={{margin:0}}>{tr('Your instructor reviews each upload here and verifies it.')}</p>
            </div>
          </div>
          <div className="card">
            <div className="card-hd"><h3>{tr('Tips')}</h3></div>
            <div className="card-body">
              <ul style={{margin:0,paddingLeft:18,fontSize:12,color:'var(--ink-2)',lineHeight:1.6}}>
                <li>{tr("Scan, don't photograph. Use a CamScanner-style app.")}</li>
                <li>{tr('Government ID: upload front + back / all pages.')}</li>
                <li>{tr('Under 2 MB each. PDF, JPG or PNG only.')}</li>
                <li>{tr('Black & white scans are fine for IDs.')}</li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------- Row + expanded uploader ---------- */
function DocRow({ doc, state, ix, open, onToggle, rec, setToast, setRoute }) {
  const s = window.effectiveDocStatus(rec, doc);
  // doc.module is the conceptual module; the router id can differ
  // (Progress & skill lives at route "tests", not "progress").
  const moduleRoute = ({ progress: 'tests' })[doc.module] || doc.module;
  const isDigital = doc.source === 'digital' || doc.source === 'digital+upload';
  const isIssued = doc.source === 'issued';
  // Reply draft for the rejection conversation (one per row).
  const [reply, setReply] = useState('');
  const studentName = rec.profile?.fullName || 'Student';

  const upload = (files) => {
    const replyText = (reply || '').trim();
    window.Store.patchStudent(rec.id, (r) => {
      r.documents = r.documents || {};
      const prev = r.documents[doc.id] || { status: 'not-started', files: [] };
      const next = {
        ...prev,
        status: 'uploaded',
        files: [...(prev.files || []), ...files],
        rejectionNote: '',
      };
      // If this is a re-upload after a rejection, append a "Re-uploaded"
      // entry to the message thread so the instructor sees what changed.
      if (prev.status === 'rejected') {
        next.messages = [...(prev.messages || []), {
          ts: new Date().toISOString(),
          from: studentName, role: 'student',
          kind: 'reupload',
          text: replyText || 'Re-uploaded.',
        }];
      }
      r.documents[doc.id] = next;
      return r;
    });
    setReply('');
    setToast(`${doc.title} uploaded · awaiting verification`);
  };
  const removeFile = (i) => {
    const gone = (state.files || [])[i];
    window.Store.patchStudent(rec.id, (r) => {
      r.documents = r.documents || {};
      const cell = r.documents[doc.id] || { status: 'not-started', files: [] };
      cell.files = (cell.files || []).slice();
      cell.files.splice(i, 1);
      if (cell.files.length === 0) cell.status = 'not-started';
      r.documents[doc.id] = cell;
      return r;
    });
    if (gone?.path) window.Store.deleteFile(gone.path);
  };

  return (
    <div style={{borderBottom:'1px solid var(--line)'}}>
      <button className="list-row" onClick={onToggle} style={{borderBottom:0}}>
        <div className={cls('ix', s==='verified' && 'done', (s==='uploaded' || s==='downloaded') && 'warn').replace('list-row ','')}
             style={{
               background: s==='verified' ? 'var(--good-soft)' : s==='rejected' ? 'var(--bad-soft)' : s==='uploaded' ? 'var(--warn-soft)' : 'var(--bg-2)',
               color: s==='verified' ? 'var(--good)' : s==='rejected' ? 'var(--bad)' : s==='uploaded' ? 'var(--warn)' : 'var(--ink-2)',
             }}>
          {s === 'verified' ? '✓' : String(ix).padStart(2,'0')}
        </div>
        <div className="nm">
          <div className="ttl">{tr(doc.title)}</div>
          <div className="desc">{tr(doc.desc)}</div>
        </div>
        <div className="meta">
          {isDigital && <div className="pill pill-info" style={{marginBottom:4}}>{tr('Digital module')}</div>}
          {isIssued && <div className="pill pill-ghost" style={{marginBottom:4}}>{tr('Issued on completion')}</div>}
          {!isDigital && !isIssued && (
            state.files?.length > 0 ?
              <div className="tiny mono muted" style={{marginBottom:4}}>{state.files.length} {state.files.length>1?tr('files'):tr('file')}</div> : null
          )}
          <StatusPill status={s}/>
        </div>
        <div style={{width:14,color:'var(--muted)',marginLeft:4}}>
          <svg width="10" height="10" viewBox="0 0 10 10" fill="none" style={{transform:open?'rotate(90deg)':'',transition:'transform .15s'}}>
            <path d="M3.5 2L6.5 5 3.5 8" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </div>
      </button>

      {open && (
        <div style={{padding:'14px 16px 18px 16px', background:'var(--bg)', borderTop:'1px dashed var(--line-strong)'}}>
          {doc.source === 'digital' && (
            <div>
              <p className="small" style={{margin:'0 0 12px',color:'var(--ink-2)'}}>
                {tr('This document is filled in directly on the dashboard. Open the linked module to continue.')}
              </p>
              <button className="btn btn-primary btn-sm" onClick={()=>setRoute(moduleRoute)}>
                {tr('Go to module')} →
              </button>
            </div>
          )}
          {doc.source === 'digital+upload' && (
            <div>
              <p className="small" style={{margin:'0 0 12px',color:'var(--ink-2)'}}>
                {tr('This is a hybrid document — fill the digital portion and upload the endorsed/signed copy.')}
              </p>
              <button className="btn btn-primary btn-sm" onClick={()=>setRoute(moduleRoute)}>
                {tr('Open module')} →
              </button>
            </div>
          )}
          {doc.source === 'issued' && (
            <div className="banner">
              <div className="body">{tr("This will be issued by IDA after your file is approved. You don't need to upload anything.")}</div>
            </div>
          )}
          {doc.source === 'upload' && (
            <div className="stack-sm" style={{gap:12}}>
              {doc.requiresIdType && (
                <div className="field" style={{maxWidth:320}}>
                  <label>{tr('Which photo ID are you uploading?')}<span className="req">*</span></label>
                  <select className="select" value={state.idType || ''}
                    disabled={s==='verified'}
                    onChange={(e)=>{
                      const v = e.target.value;
                      window.Store.patchStudent(rec.id, (r) => {
                        r.documents = r.documents || {};
                        const cell = r.documents[doc.id] || { status: 'not-started', files: [] };
                        cell.idType = v;
                        r.documents[doc.id] = cell;
                        return r;
                      });
                    }}>
                    <option value="">— {tr('select ID type')} —</option>
                    {(window.PHOTO_ID_TYPES || []).map(t =>
                      <option key={t.id} value={t.id}>{tr(t.label)}</option>)}
                  </select>
                </div>
              )}
              {(state.messages || []).length > 0 && (
                <MessageThread messages={state.messages || []}/>
              )}
              {/* Legacy fallback — older rejected docs may have a
                  rejectionNote but no messages array yet. */}
              {state.rejectionNote && !(state.messages || []).length && (
                <div className="banner bad"><div className="body"><b>{tr('Rejected')}:</b> {state.rejectionNote}</div></div>
              )}
              {state.files?.length > 0 && (
                <div className="row-wrap">
                  {state.files.map((f,i) => (
                    <FileChip key={i} file={f} onRemove={s==='verified'?null:()=>removeFile(i)}/>
                  ))}
                </div>
              )}
              {s === 'rejected' && !(doc.requiresIdType && !state.idType) && (
                <div className="field" style={{margin:'4px 0 0'}}>
                  <label>{tr('Your reply (optional)')}</label>
                  <textarea className="textarea" value={reply}
                    onChange={e=>setReply(e.target.value)}
                    rows={2}
                    placeholder={tr("Note to the instructor — e.g. “Re-scanned at higher resolution.”")}
                    style={{minHeight:50}}/>
                  <div className="input-help">{tr('Posted as a message when you upload your new file below.')}</div>
                </div>
              )}
              {s !== 'verified' && (
                doc.requiresIdType && !state.idType
                  ? <div className="banner warn"><div className="body">{tr('Pick the ID type above before uploading.')}</div></div>
                  : <FileDrop onFiles={upload} studentId={rec.id} docId={doc.id}
                              multiple={!!doc.multiple}/>
              )}
              {s === 'verified' && (
                <div className="banner good">
                  <div className="body"><b>{tr('Verified')}</b> {tr('by')} {state.verifiedBy} {tr('on')} {UI.fmtDate(state.verifiedAt)}. {tr('Your file is locked.')}</div>
                </div>
              )}
              {s === 'uploaded' && (
                <div className="tiny muted">{tr('Uploaded')} {UI.fmtDateTime(state.files?.[0]?.uploadedAt)} · {tr('officer will review shortly.')}</div>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  );
}

/* ============================================================
   MessageThread — small chat-style conversation under a rejected
   document. Used by both the student and the instructor verifier.
   ============================================================ */
function MessageThread({ messages }) {
  if (!messages || !messages.length) return null;
  return (
    <div className="msg-thread" style={{
      border:'1px solid var(--line)', borderRadius:8,
      background:'var(--surface)', padding:'10px 12px',
      display:'flex', flexDirection:'column', gap:8,
    }}>
      <div className="tiny upper muted fw-6">{tr('Conversation')} · {messages.length} {messages.length===1?tr('message'):tr('messages')}</div>
      {messages.map((m, i) => {
        const mine = m.role === 'instructor';
        const align = mine ? 'flex-end' : 'flex-start';
        const bg = m.kind === 'reject' ? 'var(--bad-soft)'
          : m.kind === 'reupload' ? 'var(--accent-soft)'
          : 'var(--bg-2)';
        const bd = m.kind === 'reject' ? 'var(--bad)'
          : m.kind === 'reupload' ? 'var(--accent)'
          : 'var(--line)';
        return (
          <div key={i} style={{
            alignSelf: align, maxWidth: '92%',
            background: bg, border: `1px solid ${bd}`,
            borderRadius: 8, padding: '7px 10px',
          }}>
            <div className="tiny" style={{fontWeight:600, marginBottom:2}}>
              {m.from || (mine ? 'Instructor' : 'Student')}
              <span className="muted" style={{fontWeight:400}}>
                {' · '}{m.kind === 'reject' ? 'rejected' : m.kind === 'reupload' ? 're-uploaded' : ''}
                {m.ts ? ' · ' + (window.UI?.ago ? UI.ago(m.ts) : new Date(m.ts).toLocaleString()) : ''}
              </span>
            </div>
            <div className="small" style={{whiteSpace:'pre-wrap',lineHeight:1.45}}>
              {m.text || (m.kind === 'reupload' ? 'Re-uploaded.' : 'No reason given.')}
            </div>
          </div>
        );
      })}
    </div>
  );
}
window.MessageThread = MessageThread;

window.StudentDocuments = StudentDocuments;
