import type { Meta, StoryObj } from "@storybook/react";
import { useEffect } from "react";
import {
	SearchPalette,
	SearchProvider,
	SearchTrigger,
	useSearchContext,
} from "./index";
import type { SearchResult } from "./searchbox-types";

/**
 * Mock documents copied verbatim from app/demo/searchbox/page.tsx
 */
const mockDocuments: SearchResult[] = [
	{
		id: "1",
		title: "What is Functions.do",
		url: "/docs/apis/functions",
		breadcrumbs: ["APIs", "Functions"],
		matches: [
			{
				type: "content",
				snippet:
					"Introducing Functions.do, a serverless function platform that you can scale.",
			},
			{
				type: "content",
				snippet:
					"Most serverless platforms can already suffice the needs of simple functions.",
			},
			{
				type: "section",
				heading: "Getting Started",
				snippet:
					"Functions.do provides serverless function execution with automatic scaling...",
			},
			{
				type: "section",
				heading: "Authentication",
				snippet:
					"Use Bearer tokens to authenticate API requests to Functions.do...",
			},
		],
	},
	{
		id: "2",
		title: "Workflows.do",
		url: "/docs/apis/workflows",
		breadcrumbs: ["APIs", "Workflows"],
		matches: [
			{
				type: "content",
				snippet:
					"Workflows.do enables complex multi-step automation pipelines...",
			},
			{
				type: "section",
				heading: "Triggers",
				snippet: "Configure triggers to start your workflows automatically...",
			},
		],
	},
	{
		id: "3",
		title: "Authentication",
		url: "/docs/guides/authentication",
		breadcrumbs: ["Guides", "Authentication"],
		matches: [
			{
				type: "content",
				snippet:
					"Configure authentication for your application using OAuth 2.0, API keys, or JWT.",
			},
			{
				type: "section",
				heading: "OAuth 2.0",
				snippet: "Configure OAuth 2.0 authentication for your application...",
			},
			{
				type: "section",
				heading: "API Keys",
				snippet: "Generate and manage API keys from the dashboard...",
			},
		],
	},
	{
		id: "4",
		title: "Database.do",
		url: "/docs/apis/database",
		breadcrumbs: ["APIs", "Database"],
		matches: [
			{
				type: "content",
				snippet: "A fully managed database with automatic backups and scaling.",
			},
			{
				type: "section",
				heading: "Queries",
				snippet: "Execute SQL queries with Database.do's query builder...",
			},
		],
	},
	{
		id: "5",
		title: "Deployment",
		url: "/docs/guides/deployment",
		breadcrumbs: ["Guides", "Deployment"],
		matches: [
			{
				type: "section",
				heading: "Vercel",
				snippet: "Deploy to Vercel with zero configuration...",
			},
			{
				type: "section",
				heading: "Docker",
				snippet: "Containerize your application with Docker...",
			},
		],
	},
	{
		id: "6",
		title: "LLM.do",
		url: "/docs/apis/llm",
		breadcrumbs: ["APIs", "LLM"],
		matches: [
			{
				type: "content",
				snippet: "Access powerful language models through a simple API.",
			},
			{
				type: "section",
				heading: "Chat Completions",
				snippet: "Generate chat completions using LLM.do...",
			},
			{
				type: "section",
				heading: "Streaming",
				snippet: "Stream responses in real-time for better UX...",
			},
		],
	},
];

/**
 * Wrapper that renders the trigger button
 */
function TriggerWrapper() {
	const { setIsOpen } = useSearchContext();
	return (
		<div className="w-64">
			<SearchTrigger onClick={() => setIsOpen(true)} />
		</div>
	);
}

/**
 * Wrapper that opens the palette automatically
 */
function AutoOpenWrapper({ initialQuery = "" }: { initialQuery?: string }) {
	const { setIsOpen, setQuery } = useSearchContext();

	useEffect(() => {
		setIsOpen(true);
		if (initialQuery) {
			setQuery(initialQuery);
		}
	}, [setIsOpen, setQuery, initialQuery]);

	return null;
}

/**
 * Story wrapper component that combines provider, palette, and optional trigger
 */
function SearchBoxStory({
	documents = mockDocuments,
	placeholder,
	showTrigger = true,
	autoOpen = false,
	initialQuery = "",
}: {
	documents?: SearchResult[];
	placeholder?: string;
	showTrigger?: boolean;
	autoOpen?: boolean;
	initialQuery?: string;
}) {
	return (
		<SearchProvider documents={documents}>
			{showTrigger && <TriggerWrapper />}
			{autoOpen && <AutoOpenWrapper initialQuery={initialQuery} />}
			<SearchPalette placeholder={placeholder} />
		</SearchProvider>
	);
}

const meta: Meta<typeof SearchBoxStory> = {
	title: "Widgets/SearchBox",
	component: SearchBoxStory,
	parameters: {
		layout: "centered",
		docs: {
			description: {
				component: `
Command palette-style search widget for documentation and content search.

Features:
- **Keyboard Shortcut** - Opens with ⌘K / Ctrl+K
- **Fuzzy Search** - Matches across titles, headings, and content
- **Breadcrumbs** - Shows document path for context
- **Highlighted Matches** - Query text highlighted in results

\`\`\`tsx
import { SearchProvider, SearchPalette, SearchTrigger, useSearchContext } from '@mdxui/widgets'

<SearchProvider documents={docs}>
  <SearchTrigger onClick={() => setIsOpen(true)} />
  <SearchPalette placeholder="Search documentation..." />
</SearchProvider>
\`\`\`
        `,
			},
		},
	},
	tags: ["autodocs"],
	argTypes: {
		documents: { control: false },
		placeholder: { control: "text" },
		showTrigger: { control: "boolean" },
		autoOpen: { control: "boolean" },
		initialQuery: { control: "text" },
	},
};

export default meta;
type Story = StoryObj<typeof meta>;

/**
 * Default state showing the search trigger button.
 * Click the button or press ⌘K to open the command palette.
 */
export const Default: Story = {
	args: {
		documents: mockDocuments,
		placeholder: "Search documentation...",
		showTrigger: true,
		autoOpen: false,
	},
};

/**
 * Command palette open and ready for search.
 * Type to search through the documentation.
 */
export const PaletteOpen: Story = {
	args: {
		documents: mockDocuments,
		placeholder: "Search documentation...",
		showTrigger: false,
		autoOpen: true,
	},
};

/**
 * Shows search results for the query "functions".
 * Results are ranked by relevance with query text highlighted.
 */
export const WithResults: Story = {
	args: {
		documents: mockDocuments,
		placeholder: "Search documentation...",
		showTrigger: false,
		autoOpen: true,
		initialQuery: "functions",
	},
};

/**
 * Shows the empty state when no results match the query.
 */
export const NoResults: Story = {
	args: {
		documents: mockDocuments,
		placeholder: "Search documentation...",
		showTrigger: false,
		autoOpen: true,
		initialQuery: "xyznonexistent",
	},
};

/**
 * Shows the palette with no documents provided.
 * Useful for testing the empty/loading state.
 */
export const NoDocuments: Story = {
	args: {
		documents: [],
		placeholder: "Search documentation...",
		showTrigger: false,
		autoOpen: true,
		initialQuery: "test",
	},
};

/**
 * Shows a custom placeholder text in the search input.
 */
export const CustomPlaceholder: Story = {
	args: {
		documents: mockDocuments,
		placeholder: "Search APIs, guides, and more...",
		showTrigger: true,
		autoOpen: false,
	},
};
