import {
  Button,
  Combobox,
  Form,
  FormControl,
  FormDescription,
  FormItem,
  FormLabel,
  FormMessage
} from "@ai-ui/ui";
import type { Meta, StoryObj } from "@storybook/react";
import { Controller, useForm } from "react-hook-form";
import { useState } from "react";

const teamItems = [
  {
    value: "design",
    label: "Design",
    group: "Primary teams",
    description: "Owns interface quality and review workflows.",
    keywords: ["ux", "ui", "visual"]
  },
  {
    value: "engineering",
    label: "Engineering",
    group: "Primary teams",
    description: "Implements and verifies rollout mechanics.",
    keywords: ["dev", "build", "api"]
  },
  {
    value: "legal",
    label: "Legal",
    group: "Specialist teams",
    description: "Checks policy, compliance, and contractual risk.",
    keywords: ["policy", "compliance"]
  },
  {
    value: "ops",
    label: "Operations",
    group: "Specialist teams",
    description: "Coordinates timing, communications, and monitoring.",
    keywords: ["launch", "support"]
  }
] as const;

function ControlledDemo() {
  const [value, setValue] = useState("design");

  return (
    <div className="grid w-[380px] gap-4">
      <Combobox
        aria-label="Routing team"
        items={[...teamItems]}
        onValueChange={setValue}
        searchPlaceholder="Search teams"
        value={value}
      />
      <div className="rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-card)] px-4 py-3 text-sm text-[var(--color-muted-foreground)] shadow-[var(--shadow-xs)]">
        Current value: <span className="font-medium text-[var(--color-foreground)]">{value}</span>
      </div>
    </div>
  );
}

function RecentAndSuggestedDemo() {
  const [value, setValue] = useState("");

  const items = [
    {
      value: "recent-legal",
      label: "Legal review",
      group: "Recent",
      description: "Last used in yesterday’s policy update."
    },
    {
      value: "recent-design",
      label: "Design review",
      group: "Recent",
      description: "Common pick for UI launches."
    },
    ...teamItems
  ];

  return (
    <div className="grid w-[420px] gap-4">
      <Combobox
        aria-label="Suggested routing team"
        emptyMessage={(query) => `No team named “${query}”. Create a custom routing lane instead.`}
        footer={
          <div className="flex items-center justify-between gap-3">
            <p className="text-xs text-[var(--color-muted-foreground)]">
              Need a specialist lane?
            </p>
            <Button size="sm" variant="ghost">
              Create lane
            </Button>
          </div>
        }
        items={items}
        onValueChange={setValue}
        searchPlaceholder="Search recent and suggested teams"
        value={value}
      />
      <div className="rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-card)] px-4 py-3 text-sm text-[var(--color-muted-foreground)] shadow-[var(--shadow-xs)]">
        Current routing lane:{" "}
        <span className="font-medium text-[var(--color-foreground)]">
          {value || "No lane selected"}
        </span>
      </div>
    </div>
  );
}

function AsyncResultsDemo() {
  const [searchValue, setSearchValue] = useState("");
  const trimmedSearch = searchValue.trim().toLowerCase();

  const isSearching = trimmedSearch.length > 0 && trimmedSearch.length < 3;

  return (
    <div className="grid w-[420px] gap-4">
      <Combobox
        aria-label="Async routing search"
        emptyMessage={(query) =>
          `No routing lane matched “${query}”. Try a broader keyword or create a new lane.`
        }
        items={[...teamItems]}
        loading={isSearching}
        loadingMessage="Searching routing lanes…"
        onSearchValueChange={setSearchValue}
        searchPlaceholder="Type at least 3 characters"
        searchValue={searchValue}
      />
      <p className="m-0 text-sm leading-6 text-[var(--color-muted-foreground)]">
        This pattern is useful when the results come from an API and you need a clear
        transition between loading, empty, and selectable states.
      </p>
    </div>
  );
}

function LaunchRoutingForm() {
  const [submitted, setSubmitted] = useState<Record<string, string> | null>(null);
  const form = useForm<{ team: string }>({
    defaultValues: {
      team: ""
    }
  });

  return (
    <Form {...form}>
      <form
        className="grid w-[560px] gap-5 rounded-[var(--radius-lg)] border border-[var(--color-border)] bg-[var(--color-card)] p-6 shadow-[var(--shadow-sm)]"
        noValidate
        onSubmit={form.handleSubmit((values) => {
          setSubmitted(values);
        })}
      >
        <div className="space-y-2">
          <h2 className="m-0 text-xl font-semibold tracking-[var(--tracking-tight)]">
            Launch routing
          </h2>
          <p className="m-0 text-sm leading-6 text-[var(--color-muted-foreground)]">
            Combobox can live inside <code>FormControl</code> and surface RHF validation state.
          </p>
        </div>

        <Controller
          control={form.control}
          name="team"
          rules={{
            required: "Choose a routing team before submitting."
          }}
          render={({ field }) => (
            <FormItem name="team">
              <FormLabel>Routing team</FormLabel>
              <FormControl>
                <Combobox
                  aria-label="Routing team"
                  items={[...teamItems]}
                  onValueChange={field.onChange}
                  searchPlaceholder="Search teams"
                  value={field.value}
                />
              </FormControl>
              <FormDescription>
                The chosen team becomes the primary owner for approvals and notifications.
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />

        <div className="flex items-center justify-end gap-3">
          <Button
            type="button"
            variant="ghost"
            onClick={() => {
              form.reset();
              setSubmitted(null);
            }}
          >
            Reset
          </Button>
          <Button type="submit">Save routing</Button>
        </div>

        <div className="rounded-[var(--radius-md)] border border-[var(--color-border)] bg-[var(--color-background)] p-4">
          <p className="m-0 text-xs uppercase tracking-[var(--tracking-caps)] text-[var(--color-muted-foreground)]">
            Submitted payload
          </p>
          <pre className="m-0 mt-3 overflow-x-auto text-sm leading-6 text-[var(--color-foreground)]">
            <code>{submitted ? JSON.stringify(submitted, null, 2) : "Submit the form to inspect values."}</code>
          </pre>
        </div>
      </form>
    </Form>
  );
}

const meta = {
  title: "Components/Combobox",
  component: ControlledDemo,
  parameters: {
    docs: {
      description: {
        component:
          "Combobox is the searchable single-select surface for longer option sets, recent picks, and async lookup flows. The list should feel gently staged as results appear, with active rows gliding into place instead of snapping."
      }
    },
    layout: "centered"
  },
  tags: ["autodocs"]
} satisfies Meta<typeof ControlledDemo>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Controlled: Story = {
  render: () => <ControlledDemo />
};

export const RecentAndSuggested: Story = {
  render: () => <RecentAndSuggestedDemo />
};

export const AsyncResults: Story = {
  parameters: {
    docs: {
      description: {
        story:
          "Async comboboxes should crossfade between loading, empty, and result states. Keep the motion short and directional so the user understands the state change without losing the current context."
      }
    }
  },
  render: () => <AsyncResultsDemo />
};

export const WithForm: Story = {
  render: () => <LaunchRoutingForm />
};
