import { useState, useEffect, useCallback, useRef } from 'react'
import { useServerEvents } from '../hooks/useServerEvents'
import type { Note, NoteFilters } from '../api/notes'
import { fetchNotes, createNote, updateNote, deleteNote, addAttachment, deleteAttachment } from '../api/notes'
import Modal from '../components/Modal'
import NoteForm from '../components/notes/NoteForm'
import { useActionButton } from '../contexts/ActionButtonContext'

const noSelect: React.CSSProperties = { userSelect: 'none' }

const inputStyle: React.CSSProperties = {
  background: 'var(--bg-3)',
  border: '1px solid var(--bg-5)',
  borderRadius: 8,
  padding: '6px 10px',
  color: 'var(--ink-1)',
  fontFamily: 'var(--font-ui)',
  fontSize: 13,
}

const actionBtnStyle: React.CSSProperties = {
  padding: '5px 10px',
  borderRadius: 6,
  border: '1px solid var(--bg-5)',
  background: 'var(--bg-4)',
  color: 'var(--ink-3)',
  cursor: 'pointer',
  fontSize: 13,
  minHeight: 32,
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
}

function formatDate(iso: string) {
  return new Date(iso).toLocaleDateString('fr-FR', { day: '2-digit', month: 'short', year: 'numeric' })
}

// Formate le texte inline : **gras**, *italique*, `code`
function inlineFmt(text: string): React.ReactNode {
  const parts = text.split(/(\*\*[^*]+\*\*|\*[^*]+\*|`[^`]+`)/)
  return (
    <>
      {parts.map((p, i) => {
        if (p.startsWith('**') && p.endsWith('**')) return <strong key={i}>{p.slice(2, -2)}</strong>
        if (p.startsWith('*') && p.endsWith('*')) return <em key={i} style={{ color: 'var(--ink-3)' }}>{p.slice(1, -1)}</em>
        if (p.startsWith('`') && p.endsWith('`')) return <code key={i} style={{ background: 'var(--bg-4)', borderRadius: 3, padding: '0 4px', fontFamily: 'var(--font-mono)', fontSize: '0.88em' }}>{p.slice(1, -1)}</code>
        return p || null
      })}
    </>
  )
}

// Renderer pseudo-markdown ligne par ligne
function renderMarkdown(text: string): React.ReactNode {
  const lines = text.split('\n')
  const nodes: React.ReactNode[] = []
  let i = 0
  while (i < lines.length) {
    const line = lines[i]
    if (line.startsWith('```')) {
      const lang = line.slice(3).trim()
      const code: string[] = []
      i++
      while (i < lines.length && !lines[i].startsWith('```')) { code.push(lines[i]); i++ }
      nodes.push(
        <pre key={i} style={{ background: 'var(--bg-4)', border: '1px solid var(--bg-5)', borderRadius: 6, padding: '8px 12px', margin: '6px 0', fontFamily: 'var(--font-mono)', fontSize: 12, overflowX: 'auto', color: 'var(--ink-1)', whiteSpace: 'pre' }}>
          {lang && <div style={{ color: 'var(--ink-4)', fontSize: 10, marginBottom: 4, textTransform: 'uppercase', letterSpacing: 0.5 }}>{lang}</div>}
          {code.join('\n')}
        </pre>
      )
    } else if (line.startsWith('# ')) {
      nodes.push(<div key={i} style={{ fontWeight: 700, fontSize: 15, color: 'var(--accent)', marginTop: 10, marginBottom: 2, fontFamily: 'var(--font-ui)' }}>{inlineFmt(line.slice(2))}</div>)
    } else if (line.startsWith('## ')) {
      nodes.push(<div key={i} style={{ fontWeight: 700, fontSize: 14, color: 'var(--ink-1)', marginTop: 8, marginBottom: 2, paddingBottom: 3, borderBottom: '1px solid var(--bg-5)', fontFamily: 'var(--font-ui)' }}>{inlineFmt(line.slice(3))}</div>)
    } else if (line.startsWith('### ')) {
      nodes.push(<div key={i} style={{ fontWeight: 600, fontSize: 13, color: 'var(--ink-1)', marginTop: 6, marginBottom: 1, fontFamily: 'var(--font-ui)' }}>{inlineFmt(line.slice(4))}</div>)
    } else if (line.startsWith('- ') || line.startsWith('* ')) {
      nodes.push(
        <div key={i} style={{ display: 'flex', gap: 6, color: 'var(--ink-2)', lineHeight: 1.6, fontFamily: 'var(--font-ui)', fontSize: 13 }}>
          <span style={{ color: 'var(--accent)', flexShrink: 0 }}>•</span>
          <span>{inlineFmt(line.slice(2))}</span>
        </div>
      )
    } else if (/^\d+\.\s/.test(line)) {
      const m = line.match(/^(\d+)\.\s(.*)/)
      nodes.push(
        <div key={i} style={{ display: 'flex', gap: 6, color: 'var(--ink-2)', lineHeight: 1.6, fontFamily: 'var(--font-ui)', fontSize: 13 }}>
          <span style={{ color: 'var(--accent)', flexShrink: 0, minWidth: 18, textAlign: 'right' }}>{m?.[1]}.</span>
          <span>{inlineFmt(m?.[2] ?? '')}</span>
        </div>
      )
    } else if (line.startsWith('> ')) {
      nodes.push(
        <div key={i} style={{ borderLeft: '3px solid var(--accent)', paddingLeft: 10, color: 'var(--ink-3)', fontStyle: 'italic', margin: '4px 0', lineHeight: 1.6, fontFamily: 'var(--font-ui)', fontSize: 13 }}>
          {inlineFmt(line.slice(2))}
        </div>
      )
    } else if (line === '---' || line === '***') {
      nodes.push(<div key={i} style={{ borderBottom: '1px solid var(--bg-5)', margin: '8px 0' }} />)
    } else if (line.trim() === '') {
      nodes.push(<div key={i} style={{ height: 5 }} />)
    } else {
      nodes.push(
        <div key={i} style={{ color: 'var(--ink-2)', lineHeight: 1.6, fontFamily: 'var(--font-ui)', fontSize: 13 }}>
          {inlineFmt(line)}
        </div>
      )
    }
    i++
  }
  return <>{nodes}</>
}

type NoteState = 'semi' | 'expanded' | 'collapsed'

function NoteCard({ note, onEdit, onDelete, onAddPhoto, onAddAudio, onAddVideo, onDeleteAtt }: {
  note: Note
  onEdit: () => void
  onDelete: () => void
  onAddPhoto: (file: File) => void
  onAddAudio: (file: File) => void
  onAddVideo: (file: File) => void
  onDeleteAtt: (attId: string) => void
}) {
  const [state, setState] = useState<NoteState>('semi')
  const photoRef = useRef<HTMLInputElement>(null)
  const audioRef = useRef<HTMLInputElement>(null)
  const videoRef = useRef<HTMLInputElement>(null)
  const [recording, setRecording] = useState(false)
  const recorderRef = useRef<MediaRecorder | null>(null)
  const chunksRef = useRef<Blob[]>([])

  const images = note.attachments.filter(a => a.file_type === 'image')
  const audios = note.attachments.filter(a => a.file_type === 'audio')
  const videos = note.attachments.filter(a => a.file_type === 'video')

  function cycleState() {
    setState(s => s === 'semi' ? 'expanded' : s === 'expanded' ? 'collapsed' : 'semi')
  }

  const stateIcon = state === 'semi' ? 'fa-chevron-down' : state === 'expanded' ? 'fa-minus' : 'fa-chevron-right'
  const stateTitle = state === 'semi' ? 'Tout afficher' : state === 'expanded' ? 'Réduire' : 'Développer'

  async function startRecord() {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
      const mimeType = ['audio/webm', 'audio/mp4', 'audio/ogg'].find(t => MediaRecorder.isTypeSupported(t)) ?? ''
      const recorder = mimeType ? new MediaRecorder(stream, { mimeType }) : new MediaRecorder(stream)
      chunksRef.current = []
      recorder.ondataavailable = e => { if (e.data.size > 0) chunksRef.current.push(e.data) }
      recorder.onstop = () => {
        stream.getTracks().forEach(t => t.stop())
        const type = recorder.mimeType || mimeType || 'audio/webm'
        const ext = type.includes('mp4') ? 'm4a' : 'webm'
        const blob = new Blob(chunksRef.current, { type })
        onAddAudio(new File([blob], `enregistrement.${ext}`, { type }))
      }
      recorder.start()
      recorderRef.current = recorder
      setRecording(true)
    } catch { /* micro non disponible */ }
  }

  function stopRecord() {
    recorderRef.current?.stop()
    setRecording(false)
  }

  const toggleBtn = (
    <button
      onClick={cycleState}
      title={stateTitle}
      style={{ background: 'transparent', border: 'none', color: 'var(--ink-4)', cursor: 'pointer', padding: '2px 6px', borderRadius: 4, fontSize: 13, flexShrink: 0, ...noSelect }}
    >
      <i className={`fa-solid ${stateIcon}`} />
    </button>
  )

  const metaLine = (
    <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center', ...noSelect }}>
      <span style={{ color: 'var(--ink-4)', fontSize: 11, fontFamily: 'var(--font-mono)' }}>{formatDate(note.created_at)}</span>
      {note.category && <span style={{ background: 'var(--bg-4)', color: 'var(--info)', fontSize: 11, fontFamily: 'var(--font-ui)', borderRadius: 999, padding: '1px 7px' }}>{note.category}</span>}
      {note.tags.map(t => <span key={t} style={{ background: 'var(--bg-5)', color: 'var(--ink-3)', fontSize: 11, fontFamily: 'var(--font-ui)', borderRadius: 999, padding: '1px 7px' }}>{t}</span>)}
      {images.length > 0 && <i className="fa-solid fa-image" style={{ color: 'var(--ink-4)', fontSize: 11 }} title={`${images.length} photo(s)`} />}
      {audios.length > 0 && <i className="fa-solid fa-microphone" style={{ color: 'var(--ink-4)', fontSize: 11 }} title={`${audios.length} audio(s)`} />}
      {videos.length > 0 && <i className="fa-solid fa-video" style={{ color: 'var(--ink-4)', fontSize: 11 }} title={`${videos.length} vidéo(s)`} />}
      {note.gps_lat != null && (
        <i className="fa-solid fa-location-dot" style={{ color: 'var(--ok)', fontSize: 12 }} title={`${note.gps_lat.toFixed(4)}, ${note.gps_lon?.toFixed(4)}`} />
      )}
    </div>
  )

  const mediaSection = (
    <>
      {images.length > 0 && (
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          {images.map(img => (
            <div key={img.id} style={{ position: 'relative' }}>
              <img src={`/media/${img.thumbnail_path ?? img.file_path}`} alt="" style={{ width: 80, height: 80, objectFit: 'cover', borderRadius: 6 }} />
              <button onClick={() => onDeleteAtt(img.id)} style={{ position: 'absolute', top: 2, right: 2, background: 'rgba(0,0,0,0.65)', border: 'none', color: '#fff', borderRadius: '50%', width: 20, height: 20, cursor: 'pointer', fontSize: 10, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 0 }}>✕</button>
            </div>
          ))}
        </div>
      )}
      {audios.length > 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
          {audios.map(aud => (
            <div key={aud.id} style={{ display: 'flex', alignItems: 'center', gap: 6, background: 'var(--bg-4)', borderRadius: 6, padding: '4px 8px', minWidth: 0 }}>
              <audio
                src={`/media/${aud.file_path}`}
                controls
                style={{ height: 32, flex: 1, minWidth: 0, width: '100%' }}
                onLoadedMetadata={e => { (e.target as HTMLAudioElement).volume = 0.5 }}
              />
              <button onClick={() => onDeleteAtt(aud.id)} style={{ background: 'transparent', border: 'none', color: 'var(--err)', cursor: 'pointer', fontSize: 14, flexShrink: 0 }}>✕</button>
            </div>
          ))}
        </div>
      )}
      {videos.length > 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {videos.map(vid => (
            <div key={vid.id} style={{ position: 'relative' }}>
              <video src={`/media/${vid.file_path}`} controls playsInline style={{ width: '100%', maxHeight: 220, borderRadius: 6, background: '#000', display: 'block' }} />
              <button onClick={() => onDeleteAtt(vid.id)} style={{ position: 'absolute', top: 6, right: 6, background: 'rgba(0,0,0,0.65)', border: 'none', color: '#fff', borderRadius: '50%', width: 22, height: 22, cursor: 'pointer', fontSize: 11, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 0 }}>✕</button>
            </div>
          ))}
        </div>
      )}
    </>
  )

  const actionButtons = (
    <div style={{ display: 'flex', gap: 6 }}>
      <input ref={photoRef} type="file" accept="image/*" style={{ display: 'none' }} onChange={e => { const f = e.target.files?.[0]; if (f) onAddPhoto(f); e.target.value = '' }} />
      <button onClick={() => photoRef.current?.click()} title="Photo" style={actionBtnStyle}><i className="fa-solid fa-camera" /></button>

      <input ref={audioRef} type="file" accept="audio/*" style={{ display: 'none' }} onChange={e => { const f = e.target.files?.[0]; if (f) onAddAudio(f); e.target.value = '' }} />
      <button
        onClick={recording ? stopRecord : startRecord}
        title={recording ? "Arrêter" : "Enregistrer"}
        style={{ ...actionBtnStyle, background: recording ? 'var(--err)' : actionBtnStyle.background, color: recording ? '#fff' : actionBtnStyle.color, border: recording ? 'none' : actionBtnStyle.border }}
      ><i className={`fa-solid fa-${recording ? 'stop' : 'microphone'}`} /></button>

      <input ref={videoRef} type="file" accept="video/*" style={{ display: 'none' }} onChange={e => { const f = e.target.files?.[0]; if (f) onAddVideo(f); e.target.value = '' }} />
      <button onClick={() => videoRef.current?.click()} title="Vidéo" style={actionBtnStyle}><i className="fa-solid fa-video" /></button>

      <div style={{ flex: 1 }} />
      <button onClick={onEdit} title="Éditer" style={{ ...actionBtnStyle, background: 'var(--bg-5)', border: 'none' }}><i className="fa-solid fa-pen" /></button>
      <button onClick={onDelete} title="Supprimer" style={{ ...actionBtnStyle, background: 'transparent', color: 'var(--err)' }}><i className="fa-solid fa-xmark" /></button>
    </div>
  )

  // ─── COLLAPSED ───────────────────────────────────────────────────────────────
  if (state === 'collapsed') {
    return (
      <div className="glass" style={{ borderRadius: 10, padding: '8px 14px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <div style={{ flex: 1, minWidth: 0, ...noSelect }}>
            <span style={{ color: 'var(--ink-2)', fontFamily: 'var(--font-ui)', fontSize: 13, fontWeight: note.title ? 600 : 400 }}>
              {note.title || note.content.slice(0, 60).replace(/\n/g, ' ')}
            </span>
            <span style={{ color: 'var(--ink-4)', fontFamily: 'var(--font-mono)', fontSize: 11, marginLeft: 8 }}>
              {formatDate(note.created_at)}
            </span>
          </div>
          {toggleBtn}
        </div>
      </div>
    )
  }

  // ─── SEMI (défaut) ───────────────────────────────────────────────────────────
  if (state === 'semi') {
    return (
      <div className="glass" style={{ borderRadius: 10, padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>
          <div style={{ flex: 1, minWidth: 0, ...noSelect }}>
            {note.title && (
              <div style={{ color: 'var(--ink-1)', fontFamily: 'var(--font-ui)', fontWeight: 600, fontSize: 14, marginBottom: 4 }}>
                {note.title}
              </div>
            )}
            <div style={{
              color: 'var(--ink-2)', fontFamily: 'var(--font-ui)', fontSize: 13, lineHeight: 1.5,
              display: '-webkit-box', WebkitLineClamp: 3, WebkitBoxOrient: 'vertical', overflow: 'hidden',
            } as React.CSSProperties}>
              {note.content}
            </div>
          </div>
          {toggleBtn}
        </div>
        {metaLine}
        {actionButtons}
      </div>
    )
  }

  // ─── EXPANDED ────────────────────────────────────────────────────────────────
  return (
    <div className="glass" style={{ borderRadius: 10, padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 10 }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, ...noSelect }}>
        <div style={{ flex: 1, minWidth: 0 }}>
          {note.title && (
            <div style={{ color: 'var(--ink-1)', fontFamily: 'var(--font-ui)', fontWeight: 700, fontSize: 15 }}>
              {note.title}
            </div>
          )}
        </div>
        {toggleBtn}
      </div>
      <div>{renderMarkdown(note.content)}</div>
      {mediaSection}
      {metaLine}
      {actionButtons}
    </div>
  )
}

// ─── PAGE ─────────────────────────────────────────────────────────────────────

export default function NotesPage() {
  const [notes, setNotes] = useState<Note[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [showForm, setShowForm] = useState(false)
  const [editingNote, setEditingNote] = useState<Note | null>(null)
  const [filters, setFilters] = useState<NoteFilters>({})
  const [searchInput, setSearchInput] = useState('')
  const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null)

  const { setActionButton } = useActionButton()
  useEffect(() => {
    setActionButton(
      <button
        onClick={() => setShowForm(true)}
        aria-label="Nouvelle note"
        style={{ width: 56, height: 56, borderRadius: '50%', background: 'var(--accent)', color: '#1d2021', border: 'none', fontSize: 24, cursor: 'pointer', boxShadow: '0 4px 16px rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
      >+</button>
    )
    return () => setActionButton(null)
  }, [setActionButton])

  const load = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      setNotes(await fetchNotes(filters))
    } catch {
      setError('Erreur de chargement')
    } finally {
      setLoading(false)
    }
  }, [filters])

  useEffect(() => { void load() }, [load])
  useServerEvents({ notes_changed: () => void load() })

  function handleSearchChange(val: string) {
    setSearchInput(val)
    if (searchTimer.current) clearTimeout(searchTimer.current)
    searchTimer.current = setTimeout(() => {
      setFilters(f => ({ ...f, q: val || undefined }))
    }, 300)
  }

  async function handleCreate(data: Parameters<typeof createNote>[0]) {
    await createNote(data)
    setShowForm(false)
    void load()
  }

  async function handleUpdate(id: string, data: Parameters<typeof updateNote>[1]) {
    await updateNote(id, data)
    setEditingNote(null)
    void load()
  }

  async function handleDelete(id: string) {
    if (!confirm('Supprimer cette note ?')) return
    try { await deleteNote(id); void load() }
    catch { setError('Erreur lors de la suppression') }
  }

  async function handleAddPhoto(noteId: string, file: File) {
    try { await addAttachment(noteId, file); void load() }
    catch { setError('Erreur upload photo') }
  }

  async function handleAddAudio(noteId: string, file: File) {
    try { await addAttachment(noteId, file); void load() }
    catch { setError('Erreur upload audio') }
  }

  async function handleAddVideo(noteId: string, file: File) {
    try { await addAttachment(noteId, file); void load() }
    catch { setError('Erreur upload vidéo') }
  }

  async function handleDeleteAtt(noteId: string, attId: string) {
    try { await deleteAttachment(noteId, attId); void load() }
    catch { setError('Erreur suppression pièce jointe') }
  }

  const hasActiveFilters = filters.has_photo || filters.has_audio || filters.has_video || filters.has_gps

  const noteGrid = (cols: string) => (
    <div style={{ display: 'grid', gridTemplateColumns: cols, gap: 10, alignItems: 'start' }}>
      {notes.map(note => (
        <NoteCard
          key={note.id}
          note={note}
          onEdit={() => setEditingNote(note)}
          onDelete={() => void handleDelete(note.id)}
          onAddPhoto={f => void handleAddPhoto(note.id, f)}
          onAddAudio={f => void handleAddAudio(note.id, f)}
          onAddVideo={f => void handleAddVideo(note.id, f)}
          onDeleteAtt={attId => void handleDeleteAtt(note.id, attId)}
        />
      ))}
    </div>
  )

  return (
    <div className="p-4">
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 16 }}>
        <h1 style={{ color: 'var(--accent)', fontFamily: 'var(--font-mono)', margin: 0, flex: 1, ...noSelect }}>Notes</h1>
        {/* Bouton ajout visible sur laptop uniquement */}
        <button
          className="hidden lg:flex"
          onClick={() => setShowForm(true)}
          style={{ alignItems: 'center', gap: 8, padding: '8px 16px', borderRadius: 8, border: 'none', background: 'var(--accent)', color: '#1d2021', fontFamily: 'var(--font-ui)', fontSize: 13, fontWeight: 600, cursor: 'pointer', ...noSelect }}
        >
          <i className="fa-solid fa-plus" /> Nouvelle note
        </button>
      </div>

      {/* Barre recherche + filtres */}
      <div style={{ display: 'flex', gap: 8, marginBottom: 12, flexWrap: 'wrap', alignItems: 'center' }}>
        <input
          style={{ ...inputStyle, flex: 1, minWidth: 160 }}
          placeholder="Rechercher…"
          value={searchInput}
          onChange={e => handleSearchChange(e.target.value)}
        />
        {([
          { key: 'has_photo', icon: 'fa-image', label: 'Photo' },
          { key: 'has_audio', icon: 'fa-microphone', label: 'Audio' },
          { key: 'has_video', icon: 'fa-video', label: 'Vidéo' },
          { key: 'has_gps', icon: 'fa-location-dot', label: 'GPS' },
        ] as const).map(({ key, icon, label }) => {
          const active = filters[key] === true
          return (
            <button
              key={key}
              onClick={() => setFilters(f => ({ ...f, [key]: active ? undefined : true }))}
              style={{ padding: '5px 10px', borderRadius: 999, border: 'none', background: active ? 'var(--accent)' : 'var(--bg-3)', color: active ? '#1d2021' : 'var(--ink-3)', cursor: 'pointer', fontFamily: 'var(--font-ui)', fontSize: 12, display: 'flex', alignItems: 'center', gap: 5, ...noSelect }}
            >
              <i className={`fa-solid ${icon}`} style={{ fontSize: 11 }} />{label}
            </button>
          )
        })}
        {hasActiveFilters && (
          <button
            onClick={() => setFilters(f => ({ ...f, has_photo: undefined, has_audio: undefined, has_video: undefined, has_gps: undefined }))}
            style={{ padding: '5px 10px', borderRadius: 999, border: 'none', background: 'transparent', color: 'var(--err)', cursor: 'pointer', fontSize: 12, ...noSelect }}
          ><i className="fa-solid fa-xmark" /> Filtres</button>
        )}
      </div>

      {error && (
        <p style={{ color: 'var(--err)', background: 'var(--bg-3)', borderRadius: 8, padding: '8px 12px', marginBottom: 12, fontFamily: 'var(--font-ui)', fontSize: 13 }}>{error}</p>
      )}

      {showForm && (
        <Modal title="Nouvelle note" onClose={() => setShowForm(false)}>
          <NoteForm onSubmit={handleCreate} onCancel={() => setShowForm(false)} />
        </Modal>
      )}
      {editingNote && (
        <Modal title="Modifier la note" onClose={() => setEditingNote(null)}>
          <NoteForm initialValues={editingNote} onSubmit={data => handleUpdate(editingNote.id, data)} onCancel={() => setEditingNote(null)} submitLabel="Enregistrer" />
        </Modal>
      )}

      {loading && <p style={{ color: 'var(--ink-3)', textAlign: 'center', padding: 24, ...noSelect }}>Chargement…</p>}

      {!loading && notes.length === 0 && (
        <p style={{ color: 'var(--ink-3)', textAlign: 'center', marginTop: 40, ...noSelect }}>Aucune note</p>
      )}

      <div className="block lg:hidden">
        {noteGrid('1fr')}
      </div>
      <div className="hidden lg:block">
        {noteGrid('repeat(3, 1fr)')}
      </div>
    </div>
  )
}
