import type { ModuleManifest, WidgetContext } from "../_core/module";
import { z } from "zod";
import { listLists, listWidgetItems, searchItems, searchLists } from "./server/queries";
import { canShareList, loadListForShare, type ListShareData } from "./server/share-queries";
import { ListSharedView } from "./components/shared-view";
import { ListWidget } from "./components/list-widget";

const listIdsSchema = z.union([z.literal("all"), z.array(z.string().uuid())]);

const listWidgetConfigSchema = z.object({
  listIds: listIdsSchema,
  showCompleted: z.boolean(),
  limit: z.number().int().min(1).max(50).optional(),
});

async function ListWidgetServer({ config }: { config: unknown; ctx: WidgetContext }) {
  const parsed = listWidgetConfigSchema.parse(config);
  const items = await listWidgetItems({
    listIds: parsed.listIds,
    showCompleted: parsed.showCompleted,
    limit: parsed.limit ?? 10,
  });
  return <ListWidget initialItems={items} />;
}

const manifest: ModuleManifest = {
  id: "lists",
  name: "Lists",
  nav: { href: "/lists", label: "Lists", icon: "list" },
  entities: [
    {
      type: "lists.list",
      label: { singular: "List", plural: "Lists" },
      share: { canShare: true, defaultCapabilities: ["read", "write"] },
      search: { search: searchLists },
      resolveUrl: (id) => `/lists/${id}`,
      canShareEntity: canShareList,
      loadForShare: loadListForShare,
      renderSharedView: ({ data, capabilities, token }) => (
        <ListSharedView data={data as ListShareData} canWrite={capabilities.write} token={token} />
      ),
      renderActivity: (entry) => {
        const name = entry.payload?.name as string | undefined;
        if (entry.action === "create") return `Created list${name ? ` "${name}"` : ""}`;
        if (entry.action === "archive") return `Archived list${name ? ` "${name}"` : ""}`;
        if (entry.action === "delete") return "Deleted list";
        return `Updated list${name ? ` "${name}"` : ""}`;
      },
    },
    {
      type: "lists.item",
      label: { singular: "List item", plural: "List items" },
      share: { canShare: false },
      search: { search: searchItems },
      resolveUrl: (id) => `/lists/items/${id}`,
      renderActivity: (entry) => {
        const text = entry.payload?.text as string | undefined;
        if (entry.action === "create") return `Added${text ? ` "${text}"` : " item"}`;
        if (entry.action === "delete") return `Removed${text ? ` "${text}"` : " item"}`;
        if (entry.action === "toggle") {
          const done = entry.payload?.done as boolean | undefined;
          const label = text ? ` "${text}"` : " item";
          return done ? `Checked off${label}` : `Unchecked${label}`;
        }
        return `Updated${text ? ` "${text}"` : " item"}`;
      },
    },
  ],
  dashboardWidgets: [
    {
      id: "lists.list",
      title: "List items",
      description: "Open or completed items from selected lists.",
      category: "Lists",
      defaultSize: { w: 4, h: 3 },
      minSize: { w: 3, h: 2 },
      defaultPriority: 30,
      configSchema: listWidgetConfigSchema,
      defaultConfig: { listIds: "all", showCompleted: false },
      resolveConfigOptions: async () => ({
        lists: (await listLists()).map((list) => ({
          id: list.id,
          type: list.type,
          name: list.name,
        })),
      }),
      render: (props) => <ListWidgetServer {...props} />,
    },
  ],
  quickAdds: [
    {
      id: "lists.add-shopping",
      label: "Add to shopping",
      icon: "shopping-cart",
      url: "/lists",
    },
    {
      id: "lists.add-task",
      label: "Add to tasks",
      icon: "list-checks",
      url: "/lists",
    },
    {
      id: "lists.new-list",
      label: "New list",
      icon: "list-plus",
      url: "/lists",
    },
  ],
};

export default manifest;
