// `/` — `renderMode: 'ssr'`, fed by the sibling api. This is the SSR-from-a-
// real-backend pattern: the loader runs server-side per request and pulls
// rows from the api BEFORE the HTML is sent, so the first paint + the
// <title> reflect real data (crawlable, no client round-trip). The component
// then upgrades the same data to live with `useSubscription`.

import type { ReactNode } from 'react'
import { useLoaderData, type LoaderFn, type PageMeta } from '@voltro/web'
import { useSubscription } from '@voltro/client'
import { T } from '@voltro/i18n'
import { getCatalog } from '../locales'

// The row shape `notes.list` streams. Kept local so the page is
// self-contained — you can also `import type { Note }` from the api's
// generated types (a type-only cross-app import is browser-safe).
interface Note {
  readonly id: string
  readonly title: string
  readonly body: string
  readonly done: boolean
}

interface HomeData {
  readonly notes: ReadonlyArray<Note>
}

export const renderMode = 'ssr' as const

// `query` is present ONLY server-side (ssr/isr). It invokes the api's rpc
// directly over POST /rpc, forwarding the request's session cookie so the
// SAME Subject + tenant resolve as the WS path. A streaming query is drained
// to its FIRST snapshot — here, the current notes for this tenant. Pass the
// row type so the result is typed without importing the api.
export const loader: LoaderFn<HomeData> = async ({ query }) => ({
  notes: query ? await query<ReadonlyArray<Note>>('notes.list', {}) : [],
})

// `meta` as a function of the loader data AND the active locale → the <title>
// reflects real api data (SEO + social cards) in the visitor's language. It's a
// plain catalog lookup (not ICU-formatted), so the row count is substituted
// into the `{count}` token by hand.
export const meta = ({ locale, loaderData }: { readonly locale: string; readonly loaderData: HomeData }): PageMeta => ({
  title:       getCatalog(locale)['meta.home.title'].replace('{count}', String(loaderData.notes.length)),
  description: getCatalog(locale)['meta.home.description'],
})

export default function Home(): ReactNode {
  // The SSR'd snapshot from the loader — correct on first paint.
  const { notes: initial } = useLoaderData<HomeData>()
  // Live data once the WebSocket connects. `data` is `undefined` during SSR,
  // so the server renders `initial` and the client upgrades to `live` on connect.
  const { data: live } = useSubscription<ReadonlyArray<Note>>('app', 'notes.list')
  const notes = live ?? initial
  const code = (c: ReactNode) => <code>{c}</code>

  return (
    <section>
      <span className="badge"><T id="home.badge" /></span>
      <h1><T id="home.heading" /></h1>
      <p className="lead">
        <T
          id="home.lead"
          values={{ code, queryCall: <code>{"query('notes.list', {})"}</code> }}
        />
      </p>
      {notes.length === 0 ? (
        <p className="empty">
          <T id="home.empty" values={{ code }} />
        </p>
      ) : (
        <ul className="notes">
          {notes.map((note) => (
            <li key={note.id}>
              <span className="title">{note.title}</span>{' '}
              {note.done ? <span className="done"><T id="home.done" /></span> : null}
              {note.body ? <p className="body">{note.body}</p> : null}
            </li>
          ))}
        </ul>
      )}
    </section>
  )
}
