// A pure client-side SPA — a bill splitter.
//
// `renderMode = 'spa'` tells `voltro build` NOT to pre-render this page:
// the client renders it on load. That is the right choice here because the
// whole page is interactive and its state lives in the browser
// (localStorage) — an SSR'd first paint would just be discarded on
// hydration, so rendering it on the server buys nothing.
//
// No backend, no rpc client, no loader. Just React + the browser.

import type { ReactNode } from 'react'
import { useEffect, useState } from 'react'
import type { PageMeta } from '@voltro/web'
import { T } from '@voltro/i18n'
import { getCatalog } from '../locales'

// Locale-aware tab title: @voltro/web resolves meta({ locale }) from the
// active locale (the `voltro:locale` cookie in this cookie-i18n app).
export const meta = ({ locale }: { readonly locale: string }): PageMeta => ({
  title: getCatalog(locale)['meta.home.title'],
})

export const renderMode = 'spa' as const
// `interactive` defaults to 'full' — every component hydrates. That is
// correct for an SPA where the whole tree is interactive (don't reach for
// islands here; islands only help when most of the page is static).

const TIP_PRESETS = [10, 15, 18, 20] as const
const STORAGE_KEY = '{{appName}}:last-tip'

const money = (n: number): string =>
  Number.isFinite(n) ? n.toLocaleString(undefined, { style: 'currency', currency: 'USD' }) : '—'

export default function BillSplitter(): ReactNode {
  const [bill, setBill] = useState('')
  const [tipPct, setTipPct] = useState(18)
  const [people, setPeople] = useState(2)

  // Restore the last tip % from localStorage — client-only, so read it in
  // an effect (it never runs on the server).
  useEffect(() => {
    const saved = Number(window.localStorage.getItem(STORAGE_KEY))
    if (Number.isFinite(saved) && saved > 0) setTipPct(saved)
  }, [])

  useEffect(() => {
    window.localStorage.setItem(STORAGE_KEY, String(tipPct))
  }, [tipPct])

  const billNum = Math.max(0, Number(bill) || 0)
  const headcount = Math.max(1, people)
  const tip = billNum * (tipPct / 100)
  const total = billNum + tip
  const perPerson = total / headcount

  return (
    <div className="card">
      <h1><T id="home.heading" /></h1>
      <p className="muted"><T id="home.subtitle" /></p>

      <label htmlFor="bill"><T id="field.bill" /></label>
      <input
        id="bill"
        type="number"
        inputMode="decimal"
        min="0"
        step="0.01"
        placeholder="0.00"
        value={bill}
        onChange={(e) => setBill(e.target.value)}
      />

      <label><T id="field.tip" /></label>
      <div className="presets">
        {TIP_PRESETS.map((p) => (
          <button
            key={p}
            type="button"
            className={p === tipPct ? 'active' : ''}
            onClick={() => setTipPct(p)}
          >
            {p}%
          </button>
        ))}
      </div>

      <div className="row">
        <div>
          <label htmlFor="custom"><T id="field.custom" /></label>
          <input
            id="custom"
            type="number"
            min="0"
            max="100"
            value={tipPct}
            onChange={(e) => setTipPct(Math.max(0, Number(e.target.value) || 0))}
          />
        </div>
        <div>
          <label htmlFor="people"><T id="field.people" /></label>
          <input
            id="people"
            type="number"
            min="1"
            value={people}
            onChange={(e) => setPeople(Math.max(1, Math.floor(Number(e.target.value) || 1)))}
          />
        </div>
      </div>

      <div className="result">
        <div className="col">
          <span className="line"><span className="muted"><T id="result.tip" /></span><span>{money(tip)}</span></span>
          <span className="line"><span className="muted"><T id="result.total" /></span><span>{money(total)}</span></span>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div className="muted"><T id="result.perPerson" /></div>
          <div className="big">{money(perPerson)}</div>
        </div>
      </div>
    </div>
  )
}
