import { useEffect, useMemo, useState } from "react"
import { Boxes, Plus, Search, Trash2 } from "lucide-react"
import { useToast } from "@crema/notification-ui"

import { AppShell } from "~/components/layout/app-shell"
import { PageHeader } from "~/components/layout/page-header"
import { ConfirmDialog } from "~/components/confirm-dialog"
import { ListSkeleton } from "~/components/loading"
import { EmptyState, ErrorState } from "~/components/states"
import { Button } from "~/components/ui/button"
import { Card, CardContent } from "~/components/ui/card"
import { Input } from "~/components/ui/input"
import {
  createResource,
  deleteResource,
  seedResourcesIfEmpty,
  updateResource,
  useResources,
  type Resource,
} from "~/lib/resources"
import { pageTitle } from "~/lib/page-meta"

export const meta = () => pageTitle("Resources")

const statuses: Resource["status"][] = ["active", "paused", "archived"]

export default function ResourcesRoute() {
  const items = useResources()
  const { toast } = useToast()
  const [query, setQuery] = useState("")
  const [draftName, setDraftName] = useState("")
  // Load-state grammar: skeleton → error → empty → content. The store here
  // is synchronous localStorage, so `loading` just gates the first frame;
  // a fork swapping `useResources()` for an async `api.get` drives these
  // two flags off the real request instead.
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    try {
      seedResourcesIfEmpty()
    } catch (e) {
      setError(e instanceof Error ? e.message : String(e))
    } finally {
      setLoading(false)
    }
  }, [])

  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase()
    return q
      ? items.filter(
          (r) =>
            r.name.toLowerCase().includes(q) ||
            r.owner.toLowerCase().includes(q) ||
            r.status.includes(q),
        )
      : items
  }, [items, query])

  const create = () => {
    const name = draftName.trim()
    if (!name) return
    createResource({ name, owner: "You" })
    setDraftName("")
    toast({ title: "Resource added", description: name, tone: "success" })
  }

  return (
    <AppShell title="Resources">
      <PageHeader
        title="Resources"
        description={
          <>
            Example domain entity. CRUD goes through{" "}
            <code className="font-mono text-xs">~/lib/resources.ts</code> — swap
            that file's calls for{" "}
            <code className="font-mono text-xs">api.get/post/put/del</code> from{" "}
            <code className="font-mono text-xs">~/lib/api.ts</code> when you have
            a backend.
          </>
        }
      />

      {loading ? (
        <ListSkeleton />
      ) : error ? (
        <ErrorState
          message={error}
          action={
            <Button
              data-action="resources-retry"
              variant="outline"
              size="sm"
              onClick={() => {
                setError(null)
                setLoading(true)
                queueMicrotask(() => setLoading(false))
              }}
            >
              Retry
            </Button>
          }
        />
      ) : (
        <Card>
          <CardContent className="flex flex-col gap-4 pt-6">
            <div className="flex flex-wrap items-center gap-2">
              <div className="relative flex-1 min-w-48">
                <Search className="pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground" />
                <Input
                  data-action="resources-search"
                  value={query}
                  onChange={(e) => setQuery(e.target.value)}
                  placeholder="Search name, owner, status…"
                  className="pl-8"
                />
              </div>
              <Input
                data-action="resources-new-name"
                value={draftName}
                onChange={(e) => setDraftName(e.target.value)}
                onKeyDown={(e) => {
                  if (e.key === "Enter") create()
                }}
                placeholder="New resource name…"
                className="max-w-64"
              />
              <Button
                data-action="resources-create"
                onClick={create}
                disabled={!draftName.trim()}
              >
                <Plus className="size-4" /> Add
              </Button>
            </div>

            {items.length === 0 ? (
              <EmptyState
                icon={<Boxes className="size-6" />}
                title="No resources yet"
                description="Add your first resource with the field above. Everything here is backed by ~/lib/resources.ts."
              />
            ) : (
              <div className="overflow-hidden rounded-lg border bg-card/40">
                <table className="w-full text-sm">
                  <thead className="bg-muted/50 text-xs uppercase tracking-wide text-muted-foreground">
                    <tr>
                      <th className="px-3 py-2 text-left font-medium">Name</th>
                      <th className="px-3 py-2 text-left font-medium">Owner</th>
                      <th className="px-3 py-2 text-left font-medium">Status</th>
                      <th className="px-3 py-2 text-left font-medium">Updated</th>
                      <th className="w-10 px-3 py-2"></th>
                    </tr>
                  </thead>
                  <tbody>
                    {filtered.length === 0 ? (
                      <tr>
                        <td
                          colSpan={5}
                          className="px-3 py-8 text-center text-muted-foreground"
                        >
                          No matches.
                        </td>
                      </tr>
                    ) : (
                      filtered.map((r) => (
                        <tr
                          key={r.id}
                          className="border-t transition-colors hover:bg-accent/30"
                        >
                          <td className="px-3 py-2 font-medium">{r.name}</td>
                          <td className="px-3 py-2 text-muted-foreground">
                            {r.owner}
                          </td>
                          <td className="px-3 py-2">
                            <select
                              data-action={`resources-status-${r.id}`}
                              value={r.status}
                              onChange={(e) =>
                                updateResource(r.id, {
                                  status: e.target.value as Resource["status"],
                                })
                              }
                              className="rounded-md border bg-background px-1.5 py-0.5 text-xs"
                            >
                              {statuses.map((s) => (
                                <option key={s} value={s}>
                                  {s}
                                </option>
                              ))}
                            </select>
                          </td>
                          <td className="px-3 py-2 text-xs text-muted-foreground tabular-nums">
                            {new Date(r.updatedAt).toLocaleDateString()}
                          </td>
                          <td className="px-2 py-2 text-right">
                            <ConfirmDialog
                              trigger={
                                <Button
                                  data-action={`resources-delete-${r.id}`}
                                  variant="ghost"
                                  size="icon-sm"
                                  aria-label="Delete"
                                >
                                  <Trash2 className="size-4 text-destructive" />
                                </Button>
                              }
                              title="Delete resource?"
                              description={`"${r.name}" will be permanently removed. This can't be undone.`}
                              confirmLabel="Delete"
                              destructive
                              onConfirm={() => {
                                deleteResource(r.id)
                                toast({
                                  title: "Resource deleted",
                                  description: r.name,
                                  tone: "success",
                                })
                              }}
                            />
                          </td>
                        </tr>
                      ))
                    )}
                  </tbody>
                </table>
              </div>
            )}

            <p className="text-xs text-muted-foreground">
              {items.length} total · {filtered.length} shown
            </p>
          </CardContent>
        </Card>
      )}
    </AppShell>
  )
}
