/* Papelería / expediente documental — portal alumno + preview admin */

function getStudentDocumentPublicUrl (doc) {
  if (!doc?.file_path || typeof getStoragePublicUrl !== 'function') return null;
  const v = doc.uploaded_at || doc.id || doc.file_path;
  const base = getStoragePublicUrl('gallery', doc.file_path);
  return base ? `${base}${base.includes('?') ? '&' : '?'}v=${encodeURIComponent(String(v))}` : null;
}

function isStudentDocumentPdf (doc) {
  const mime = (doc?.mime_type || '').toLowerCase();
  const name = (doc?.file_name || doc?.file_path || '').toLowerCase();
  return mime.includes('pdf') || name.endsWith('.pdf');
}

function computeStudentDocumentsStatus (docs, types, requirements) {
  const allTypes = types || STUDENT_DOCUMENT_TYPES || [];
  const req = typeof mergeDocumentRequirements === 'function'
    ? mergeDocumentRequirements(requirements)
    : (requirements || null);
  const applicable = req
    ? allTypes.filter((t) => req[t.id] !== false)
    : allTypes;
  const map = {};
  (docs || []).forEach((d) => { if (d?.doc_type) map[d.doc_type] = d; });
  const loaded = applicable.filter((t) => map[t.id]?.file_path).length;
  const total = applicable.length;
  const pending = Math.max(0, total - loaded);
  const complete = total > 0 && loaded >= total;
  const waived = allTypes.length - applicable.length;
  return { loaded, total, pending, complete, byType: map, applicable, waived, requirements: req };
}

const StudentDocPreviewModal = ({ open, onClose, theme, doc, title }) => {
  if (!open || !doc) return null;
  const url = getStudentDocumentPublicUrl(doc);
  const isPdf = isStudentDocumentPdf(doc);
  const label = title || doc.file_name || doc.doc_type || 'Documento';

  return (
    <Modal open={open} onClose={onClose} theme={theme} title={`Vista previa — ${label}`} width={isPdf ? 520 : 720}>
      <div style={{ padding: '8px 24px 24px' }}>
        {!url ? (
          <p style={{ color: theme.danger, fontFamily: 'Inter, sans-serif', fontSize: 13 }}>No se pudo cargar el archivo.</p>
        ) : isPdf ? (
          <div style={{ display: 'grid', gap: 14 }}>
            <p style={{ margin: 0, fontSize: 13, color: theme.textDim, fontFamily: 'Inter, sans-serif', lineHeight: 1.5 }}>
              El PDF se abrirá en una pestaña nueva para revisarlo con mayor comodidad.
            </p>
            <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              <Btn theme={theme} icon="eye" onClick={() => window.open(url, '_blank', 'noopener,noreferrer')}>Abrir PDF</Btn>
              <Btn theme={theme} kind="ghost" icon="download" onClick={() => {
                const a = document.createElement('a');
                a.href = url;
                a.download = doc.file_name || 'documento.pdf';
                a.target = '_blank';
                a.rel = 'noopener';
                a.click();
              }}>Descargar</Btn>
            </div>
            <iframe title="Vista previa PDF" src={url} style={{
              width: '100%', height: 420, border: `1px solid ${theme.border}`, borderRadius: 10, background: theme.bgInput,
            }} />
          </div>
        ) : (
          <div style={{ textAlign: 'center' }}>
            <img src={url} alt={label} style={{
              maxWidth: '100%', maxHeight: '70vh', borderRadius: 10,
              border: `1px solid ${theme.border}`, objectFit: 'contain',
            }} />
          </div>
        )}
        <p style={{ marginTop: 12, fontSize: 11, color: theme.textMute, fontFamily: 'Inter, sans-serif' }}>
          {doc.file_name || doc.file_path}
          {doc.uploaded_at && ` · ${new Date(doc.uploaded_at).toLocaleString('es-MX')}`}
        </p>
      </div>
    </Modal>
  );
};

const StudentDocumentsChecklist = ({
  theme, docs, types, requirements, canUpload, canRemove, canEditRequirements,
  studentCode, studentId, onUploaded, readOnlyHint, onUploadFile, onRemoveDoc, onRequirementsChange,
}) => {
  const allTypes = types || STUDENT_DOCUMENT_TYPES || [];
  const [reqState, setReqState] = React.useState(() => (
    typeof mergeDocumentRequirements === 'function'
      ? mergeDocumentRequirements(requirements)
      : defaultDocumentRequirements()
  ));
  const [savingReq, setSavingReq] = React.useState(null);
  const status = computeStudentDocumentsStatus(docs, allTypes, reqState);
  const [uploading, setUploading] = React.useState(null);
  const [err, setErr] = React.useState('');
  const [previewDoc, setPreviewDoc] = React.useState(null);

  React.useEffect(() => {
    setReqState(typeof mergeDocumentRequirements === 'function'
      ? mergeDocumentRequirements(requirements)
      : defaultDocumentRequirements());
  }, [requirements, studentId]);

  const applies = (docType) => reqState[docType] !== false;

  const toggleApplies = async (docType, checked) => {
    const next = { ...reqState, [docType]: !!checked };
    setReqState(next);
    if (!canEditRequirements || !studentId) return;
    setSavingReq(docType);
    setErr('');
    try {
      if (typeof saveStudentDocumentRequirements === 'function') {
        await saveStudentDocumentRequirements(studentId, next);
      } else if (typeof onRequirementsChange === 'function') {
        await onRequirementsChange(next);
      }
      onUploaded?.();
    } catch (e) {
      setErr(e.message || 'No se pudo guardar');
      setReqState(reqState);
    } finally {
      setSavingReq(null);
    }
  };

  const upload = async (docType, file) => {
    if (!file || !applies(docType)) return;
    if (!onUploadFile && !studentCode) return;
    setUploading(docType);
    setErr('');
    try {
      if (typeof onUploadFile === 'function') {
        await onUploadFile(docType, file);
      } else if (typeof uploadStudentDocumentByCode === 'function') {
        await uploadStudentDocumentByCode({ studentCode, docType, file });
      } else {
        throw new Error('Subida no disponible. Recarga la página (F5).');
      }
      onUploaded?.();
    } catch (e) {
      setErr(e.message || 'No se pudo subir');
    } finally {
      setUploading(null);
    }
  };

  const displayTypes = canEditRequirements
    ? allTypes
    : status.applicable;

  return (
    <div style={{ display: 'grid', gap: 10 }}>
      <div style={{
        padding: '10px 14px', borderRadius: 10,
        background: status.complete ? `${theme.success}14` : `${theme.warning}12`,
        border: `1px solid ${status.complete ? theme.success : theme.warning}44`,
        display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 8,
      }}>
        <span style={{ fontSize: 13, fontWeight: 700, color: theme.text, fontFamily: 'Inter, sans-serif' }}>
          {status.loaded} de {status.total} documentos cargados
          {status.waived > 0 && (
            <span style={{ fontWeight: 500, color: theme.textDim }}> · {status.waived} no aplican</span>
          )}
        </span>
        <Badge theme={theme} color={status.complete ? 'success' : (status.loaded > 0 ? 'warning' : 'danger')}>
          {status.complete ? 'Completo' : (status.loaded > 0 ? 'Incompleto' : 'Sin archivos')}
        </Badge>
      </div>
      {canEditRequirements && (
        <p style={{ fontSize: 12, color: theme.textDim, margin: 0, fontFamily: 'Inter, sans-serif', lineHeight: 1.45 }}>
          Marca <strong>Aplica</strong> en cada documento que este alumno debe entregar. Si no aplica, no se le pedirá en su portal y no cuenta en el total (ej. 8/8).
        </p>
      )}
      {readOnlyHint && (
        <p style={{ fontSize: 12, color: theme.textDim, margin: 0, fontFamily: 'Inter, sans-serif' }}>{readOnlyHint}</p>
      )}
      {err && (
        <div style={{ padding: 10, borderRadius: 8, background: `${theme.danger}18`, color: theme.danger, fontSize: 12, fontFamily: 'Inter, sans-serif' }}>
          {err}
        </div>
      )}
      {displayTypes.map((dt) => {
        const row = status.byType[dt.id];
        const loaded = !!row?.file_path;
        const docApplies = applies(dt.id);
        return (
          <div key={dt.id} style={{
            padding: 14, borderRadius: 10,
            border: `1px solid ${!docApplies ? theme.border : (loaded ? `${theme.success}55` : theme.border)}`,
            background: !docApplies ? `${theme.bgElev}` : theme.bgInput,
            display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap',
            opacity: docApplies ? 1 : 0.72,
          }}>
            <div style={{ flex: 1, minWidth: 160 }}>
              <div style={{ fontWeight: 700, fontSize: 14, color: theme.text, fontFamily: 'Inter, sans-serif' }}>{dt.label}</div>
              {!docApplies ? (
                <div style={{ fontSize: 11, color: theme.textMute, marginTop: 4, fontFamily: 'Inter, sans-serif' }}>
                  No aplica para este alumno
                </div>
              ) : loaded ? (
                <div style={{ fontSize: 11, color: theme.textDim, marginTop: 4, fontFamily: 'Inter, sans-serif' }}>
                  {row.file_name || 'Archivo cargado'} · {new Date(row.uploaded_at).toLocaleDateString('es-MX')}
                </div>
              ) : (
                <div style={{ fontSize: 11, color: theme.textMute, marginTop: 4, fontFamily: 'Inter, sans-serif' }}>Pendiente de subir</div>
              )}
            </div>
            {canEditRequirements && (
              <label style={{
                display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12, fontWeight: 700,
                color: docApplies ? theme.primary : theme.textMute, fontFamily: 'Inter, sans-serif',
                cursor: savingReq === dt.id ? 'wait' : 'pointer', userSelect: 'none',
              }}>
                <input
                  type="checkbox"
                  checked={docApplies}
                  disabled={!!savingReq}
                  onChange={(e) => toggleApplies(dt.id, e.target.checked)}
                  style={{ accentColor: theme.primary, width: 16, height: 16 }}
                />
                Aplica
              </label>
            )}
            {!docApplies ? (
              <Badge theme={theme} color="info" soft>N/A</Badge>
            ) : (
              <Badge theme={theme} color={loaded ? 'success' : 'danger'}>{loaded ? 'Cargado' : 'Pendiente'}</Badge>
            )}
            {docApplies && loaded && (
              <Btn theme={theme} kind="soft" size="sm" icon="eye" onClick={() => setPreviewDoc({ ...row, _label: dt.label })}>
                Ver
              </Btn>
            )}
            {canRemove && docApplies && loaded && typeof onRemoveDoc === 'function' && (
              <Btn theme={theme} kind="ghost" size="sm" icon="trash" disabled={!!uploading}
                onClick={async () => {
                  if (!confirm(`¿Eliminar ${dt.label}?`)) return;
                  setErr('');
                  try {
                    await onRemoveDoc(row);
                    onUploaded?.();
                  } catch (e) {
                    setErr(e.message || 'No se pudo eliminar');
                  }
                }} />
            )}
            {canUpload && docApplies && (
              <label style={{
                display: 'inline-flex', alignItems: 'center', gap: 6, padding: '8px 12px',
                borderRadius: 8, border: `1px solid ${theme.border}`, fontSize: 12, fontWeight: 600,
                color: theme.text, background: theme.bgElev, cursor: uploading ? 'wait' : 'pointer',
                opacity: uploading ? 0.6 : 1, fontFamily: 'Inter, sans-serif',
              }}>
                <input type="file" accept="image/jpeg,image/png,image/webp,application/pdf" hidden
                  disabled={!!uploading}
                  onChange={(e) => { upload(dt.id, e.target.files?.[0]); e.target.value = ''; }} />
                <Icon name="upload" size={14} />
                {uploading === dt.id ? 'Subiendo…' : (loaded ? 'Reemplazar' : 'Subir')}
              </label>
            )}
          </div>
        );
      })}
      <StudentDocPreviewModal
        open={!!previewDoc}
        onClose={() => setPreviewDoc(null)}
        theme={theme}
        doc={previewDoc}
        title={previewDoc?._label}
      />
    </div>
  );
};

Object.assign(window, {
  getStudentDocumentPublicUrl,
  isStudentDocumentPdf,
  computeStudentDocumentsStatus,
  StudentDocPreviewModal,
  StudentDocumentsChecklist,
});
