/**
 * Example UI component showing the read + write patterns customers should
 * use throughout the rest of the app:
 *
 *   - Reads use `useQuery`. The result is reactive — when any row matched
 *     by the query changes (locally or via a sync push from another client),
 *     the component re-renders automatically. There's no `useEffect`, no
 *     manual subscription, no fetch on mount.
 *   - Writes go straight to the local DB via `db.execute`. The call resolves
 *     as soon as the row is in local SQLite (milliseconds), and the upload
 *     to the server happens asynchronously in the background. The UI never
 *     waits on the network.
 *
 * IDs are generated client-side with `uuid()`. This is intentional: it lets
 * the row exist locally before the server has heard about it, which is what
 * makes offline-first work. The server upserts on the id we send.
 */

import { useQuery } from '@powersync/react';
import { useState } from 'react';
import { v4 as uuid } from 'uuid';
import { db } from './lib/sync';

export default function App() {
  // The SQL is plain SQLite. Joins, aggregates, ORDER BY — anything SQLite
  // understands is fair game. Parameters can be passed as a second argument:
  // `useQuery('SELECT * FROM items WHERE done = ?', [0])`.
  const { data: items } = useQuery<{ id: string; text: string; done: number }>(
    'SELECT * FROM items ORDER BY created_at DESC',
  );
  const [draft, setDraft] = useState('');

  const addItem = async (event: React.FormEvent) => {
    event.preventDefault();
    const text = draft.trim();
    if (!text) return;
    // INSERT writes to local SQLite. The connector's upload loop picks it
    // up on the next tick and POSTs it to /sync.
    await db.execute(
      'INSERT INTO items (id, text, done, created_at) VALUES (?, ?, ?, ?)',
      [uuid(), text, 0, Date.now()],
    );
    setDraft('');
  };

  const toggle = async (id: string, done: number) => {
    await db.execute('UPDATE items SET done = ? WHERE id = ?', [done ? 0 : 1, id]);
  };

  return (
    <div className="page">
      <h1>{{APP_NAME}}</h1>
      {/* `add-form` / `add-input` are stable hooks used by the template smoke
          test; styling comes from the `.row` / `.input` / `.btn` primitives. */}
      <form className="add-form row" onSubmit={addItem}>
        <input
          className="add-input input flex-1"
          value={draft}
          onChange={event => setDraft(event.target.value)}
          placeholder="Add an item"
        />
        <button className="btn btn-primary" type="submit">Add item</button>
      </form>
      <ul className="stack m-0 list-none p-0">
        {items.map(item => (
          <li
            key={item.id}
            className={`item card cursor-pointer ${item.done ? 'item-done muted line-through' : ''}`}
            onClick={() => toggle(item.id, item.done)}
          >
            {item.text}
          </li>
        ))}
      </ul>
    </div>
  );
}
