import { createFileRoute, useRouter } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { prisma } from '#/db'

const getTodos = createServerFn({
  method: 'GET',
}).handler(async () => {
  return await prisma.todo.findMany({
    orderBy: { createdAt: 'desc' },
  })
})

const createTodo = createServerFn({
  method: 'POST',
})
  .validator((data: { title: string }) => data)
  .handler(async ({ data }) => {
    return await prisma.todo.create({
      data,
    })
  })

export const Route = createFileRoute('/demo/prisma')({
  component: DemoPrisma,
  loader: async () => await getTodos(),
})

function DemoPrisma() {
  const router = useRouter()
  const todos = Route.useLoaderData()

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    const form = e.currentTarget
    const title = new FormData(form).get('title')

    if (typeof title !== 'string' || !title) return

    try {
      await createTodo({ data: { title } })
      router.invalidate()
      form.reset()
    } catch (error) {
      console.error('Failed to create todo:', error)
    }
  }

  return (
    <main className="demo-page demo-center">
      <section className="demo-panel w-full max-w-2xl">
        <header className="mb-8 flex items-center gap-4">
          <span className="demo-card flex h-14 w-14 items-center justify-center p-3">
            <img src="/prisma.svg" alt="Prisma Logo" className="h-8 w-8" />
          </span>
          <div>
            <p className="island-kicker mb-2">Database</p>
            <h1 className="demo-title">Prisma Demo</h1>
          </div>
        </header>

        <h2 className="demo-section-title mb-4">Todos</h2>

        <ul className="space-y-3 mb-6">
          {todos.map((todo) => (
            <li
              key={todo.id}
              className="demo-list-item"
            >
              <div className="flex items-center justify-between">
                <span className="font-medium">{todo.title}</span>
                <span className="demo-muted text-xs">#{todo.id}</span>
              </div>
            </li>
          ))}
          {todos.length === 0 && (
            <li className="demo-list-item text-center demo-muted">
              No todos yet. Create one below!
            </li>
          )}
        </ul>

        <form onSubmit={handleSubmit} className="flex flex-col gap-2 sm:flex-row">
          <input
            type="text"
            name="title"
            placeholder="Add a new todo..."
            className="demo-input min-w-0 flex-1"
          />
          <button
            type="submit"
            className="demo-button whitespace-nowrap"
          >
            Add Todo
          </button>
        </form>

        <div className="demo-card mt-8">
          <h3 className="demo-section-title mb-2">
            Powered by Prisma ORM
          </h3>
          <p className="demo-muted mb-4 text-sm">
            Next-generation ORM for Node.js & TypeScript with <%= addOnOption.prisma.database === 'postgres' ? 'PostgreSQL' : addOnOption.prisma.database === 'mysql' ? 'MySQL' : 'SQLite' %>
          </p>
          <div className="space-y-2 text-sm">
            <p className="font-medium">Setup Instructions:</p>
            <ol className="demo-muted list-inside list-decimal space-y-2">
              <li>
                Configure your{' '}
                <code>DATABASE_URL</code>{' '}
                in .env.local
              </li>
              <li>
                Run:{' '}
                <code>
                  <%- getPackageManagerRunScript('db:generate') %>
                </code>
              </li>
              <li>
                Run:{' '}
                <code>
                  <%- getPackageManagerRunScript('db:push') %>
                </code>
              </li>
              <li>
                Optional:{' '}
                <code>
                  <%- getPackageManagerRunScript('db:studio') %>
                </code>
              </li>
            </ol>
          </div>
        </div>
      </section>
    </main>
  )
}
