TAG API — SPACE CHAT  (EDIT, REACT, MEDIA UPLOAD)
===================================================
Base URL : https://tag.nsamaandcompany.com/tag_api
Auth     : Authorization: Bearer <token>  required on all endpoints

This file documents the space chat endpoints that are NOT covered in
TAG_API_DOCS.txt or CHAT_SEARCH_DOCS.txt.

Pre-condition: caller must have joined the space (active session).
               Messages are identified by the sender's space_tag_code (anonymous).


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
EDIT A CHAT MESSAGE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

PATCH /api/v1/tag-spaces/{uuid}/chat/{msgId}    [AUTH]
  Edit the text body of a message you sent. Sender only. Text messages only.
  Path params:
    uuid   — the space's UUID
    msgId  — the numeric id of the message to edit
  Body (JSON): { "body": "corrected message text" }
  Response 200:
    { "id": 42, "body": "corrected message text", "edited_at": "2026-06-07T12:00:00Z" }
  Side effect: writes to Firebase RTDB
    chats/spaces/{uuid}/last_event
    { edited_message_id, preview, edited_at }
    Listening clients should re-fetch the message or update it in-place.
  Errors:
    422 — body missing or empty
    404 — message not found, not yours, or not a text message
    403 — you are not a member of the space


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
REACT TO A CHAT MESSAGE
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

POST /api/v1/tag-spaces/{uuid}/chat/{msgId}/react  [AUTH]
  Toggle an emoji reaction on a chat message.
  Sending the same emoji again removes the reaction (toggle behaviour).
  Sending a different emoji replaces the existing one.
  Path params:
    uuid   — the space's UUID
    msgId  — the numeric id of the message
  Body (JSON): { "emoji": "👍" }
    Any unicode emoji string is accepted (truncated to 10 chars).
  Response 200:
    {
      "message_id": 42,
      "my_reaction": "👍",   (null if reaction was removed)
      "reactions": [
        { "emoji": "👍", "count": 3, "is_mine": true },
        { "emoji": "🔥", "count": 1, "is_mine": false }
      ]
    }
  Side effect: writes to Firebase RTDB
    chats/spaces/{uuid}/reactions/{msgId}
    { updated_at }
    Listening clients should re-fetch reactions for that message.
  Errors:
    422 — emoji missing or empty
    404 — message not found or deleted
    403 — you are not a member of the space


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
MEDIA UPLOAD ALIAS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

POST /api/v1/tag-spaces/{uuid}/chat/media       [AUTH]
  Alias route for sending a media message to the space chat.
  Identical behaviour to POST /api/v1/tag-spaces/{uuid}/chat.
  Use this URL when the frontend sends multipart/form-data with a file,
  as some HTTP clients route file uploads to a separate path.
  Body: multipart/form-data
    type  = "image" | "audio" | "video" | "document"
    media = <file>
  Response and side effects are the same as the base /chat POST endpoint.


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
COMPLETE SPACE CHAT ENDPOINT SUMMARY
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

GET    /api/v1/tag-spaces/{uuid}/chat            — list messages (paginated)
POST   /api/v1/tag-spaces/{uuid}/chat            — send text or media message
POST   /api/v1/tag-spaces/{uuid}/chat/media      — alias for media upload
PATCH  /api/v1/tag-spaces/{uuid}/chat/read       — mark all as read
PATCH  /api/v1/tag-spaces/{uuid}/chat/{id}       — edit a text message  ← NEW
DELETE /api/v1/tag-spaces/{uuid}/chat/{id}       — delete a message
POST   /api/v1/tag-spaces/{uuid}/chat/{id}/react — toggle emoji reaction ← NEW

Real-time events at Firebase RTDB: chats/spaces/{uuid}/last_event
  On new message:  { message_id, sender_code, preview, sent_at }
  On edit:         { edited_message_id, preview, edited_at }

Reaction events at Firebase RTDB: chats/spaces/{uuid}/reactions/{msgId}
  On change:       { updated_at }
