import type { Meta, StoryObj } from '@storybook/vue3-vite';
import { onMounted, ref } from 'vue';
import { UiIcon } from '@/components/UiIcon';
import { RouterLink, RouterView, useRouter } from 'vue-router';
import UiSidebar from './UiSidebar.vue';
import UiSidebarContent from './UiSidebarContent.vue';
import UiSidebarHeader from './UiSidebarHeader.vue';
import UiSidebarInset from './UiSidebarInset.vue';
import UiSidebarMenu from './UiSidebarMenu.vue';
import UiSidebarMenuButton from './UiSidebarMenuButton.vue';
import UiSidebarMenuItem from './UiSidebarMenuItem.vue';
import UiSidebarProvider from './UiSidebarProvider.vue';

type MenuButtonStoryConfig = {
  label: string;
  subtitle?: string;
  startIcon?: string;
  endIcon?: string;
  badge?: string;
  bigIcon?: boolean;
  checkbox?: boolean;
  endIconClickable?: boolean;
};

const meta: Meta<typeof UiSidebarMenuButton> = {
  title: 'Patterns/UiSidebar/UiSidebarMenuButton',
  component: UiSidebarMenuButton,
  tags: ['autodocs'],
  parameters: {
    layout: 'padded',
    docs: {
      description: {
        component:
          'Primary navigation row: start icon, label, optional subtitle, end icon or badge, and token-backed active/hover overlays. Use **`tooltip`** for collapsed sidebar affordance. Stories below demonstrate common compositions (chevron, badge, two-line, checkbox).',
      },
    },
  },
  argTypes: {
    tooltip: {
      control: 'text',
      description:
        'Tooltip when the shell is collapsed (string or Vue component).',
    },
    variant: {
      control: 'select',
      options: ['default', 'outline'],
      description: 'Passes through to the core menu button variant.',
    },
    size: {
      control: 'select',
      options: ['default', 'sm', 'lg'],
      description: 'Height and typography tier for the row.',
    },
    isActive: {
      control: 'boolean',
      description:
        'Whether the row shows the active rail and accent treatment.',
    },
    endIconClickable: {
      control: 'boolean',
      description:
        'When true, the end slot renders as a separate control and emits `end-icon-click`.',
    },
    endIconAriaLabel: {
      control: 'text',
      description:
        'Accessible name for the end icon action when `endIconClickable` is true.',
    },
  },
};

export default meta;

type Story = StoryObj<typeof UiSidebarMenuButton>;

const renderMode = (mode: MenuButtonStoryConfig) => ({
  components: {
    UiIcon,
    UiSidebar,
    UiSidebarContent,
    UiSidebarHeader,
    UiSidebarMenu,
    UiSidebarMenuButton,
    UiSidebarMenuItem,
    UiSidebarProvider,
  },
  setup() {
    const actionCount = ref(0);

    function handleEndIconClick() {
      actionCount.value += 1;
    }

    return { actionCount, handleEndIconClick, mode };
  },
  template: `
    <div class="bg-background-surface-primary p-4">
      <UiSidebarProvider :default-open="true">
        <UiSidebar collapsible="icon" class="w-72">
          <UiSidebarHeader tooltip="Toggle sidebar">Preview</UiSidebarHeader>
          <UiSidebarContent class="p-0">
            <UiSidebarMenu class="gap-y-1 p-2">
              <UiSidebarMenuItem>
                <UiSidebarMenuButton
                  :tooltip="mode.label"
                  :end-icon-clickable="mode.endIconClickable"
                  @end-icon-click="handleEndIconClick"
                >
                  <template #start-icon>
                    <span
                      v-if="mode.checkbox"
                      class="flex size-4 items-center justify-center rounded-[4px] bg-background-accent-default text-content-on-accent-default"
                    >
                      <UiIcon name="check" size="s" />
                    </span>
                    <span
                      v-else-if="mode.bigIcon"
                      class="flex size-8 items-center justify-center rounded-full bg-background-surface-muted text-content-on-surface-primary"
                    >
                      <UiIcon name="bot" size="s" />
                    </span>
                    <UiIcon :name="mode.startIcon ?? 'folder'" size="s" v-else />
                  </template>
                  {{ mode.label }}
                  <template v-if="mode.subtitle" #subtitle>
                    {{ mode.subtitle }}
                  </template>
                  <template v-if="mode.endIcon || mode.badge" #end-icon>
                    <span
                      v-if="mode.badge"
                      class="min-w-6 rounded-sm bg-background-surface-muted px-1.5 py-0.5 text-center text-xs text-content-on-surface-primary"
                    >
                      {{ mode.badge }}
                    </span>
                    <UiIcon :name="mode.endIcon" size="s" v-else />
                  </template>
                </UiSidebarMenuButton>
              </UiSidebarMenuItem>

              <UiSidebarMenuItem>
                <UiSidebarMenuButton
                  :tooltip="mode.label"
                  :end-icon-clickable="mode.endIconClickable"
                  is-active
                  @end-icon-click="handleEndIconClick"
                >
                  <template #start-icon>
                    <span
                      v-if="mode.checkbox"
                      class="flex size-4 items-center justify-center rounded-[4px] bg-background-accent-default text-content-on-accent-default"
                    >
                      <UiIcon name="check" size="s" />
                    </span>
                    <span
                      v-else-if="mode.bigIcon"
                      class="flex size-8 items-center justify-center rounded-full bg-background-surface-muted text-content-on-surface-primary"
                    >
                      <UiIcon name="bot" size="s" />
                    </span>
                    <UiIcon :name="mode.startIcon ?? 'folder'" size="s" v-else />
                  </template>
                  {{ mode.label }}
                  <template v-if="mode.subtitle" #subtitle>
                    {{ mode.subtitle }}
                  </template>
                  <template v-if="mode.endIcon || mode.badge" #end-icon>
                    <span
                      v-if="mode.badge"
                      class="min-w-6 rounded-sm bg-background-surface-muted px-1.5 py-0.5 text-center text-xs text-content-on-surface-primary"
                    >
                      {{ mode.badge }}
                    </span>
                    <UiIcon :name="mode.endIcon" size="s" v-else />
                  </template>
                </UiSidebarMenuButton>
              </UiSidebarMenuItem>
            </UiSidebarMenu>
          </UiSidebarContent>
        </UiSidebar>
      </UiSidebarProvider>
      <p v-if="mode.endIconClickable" class="mt-3 text-xs text-content-on-surface-muted">
        End icon clicks: {{ actionCount }}
      </p>
    </div>
  `,
});

export const Simple: Story = {
  render: () =>
    renderMode({
      label: 'Menu Item',
      startIcon: 'folder',
    }),
};

export const Dropdown: Story = {
  render: () =>
    renderMode({
      label: 'Menu Item',
      startIcon: 'folder',
      endIcon: 'chevron-down',
      endIconClickable: true,
    }),
};

export const Tree: Story = {
  render: () =>
    renderMode({
      label: 'Menu Item',
      startIcon: 'folder',
      endIcon: 'chevron-right',
      endIconClickable: true,
    }),
};

export const Badge: Story = {
  render: () =>
    renderMode({
      label: 'Menu Item',
      startIcon: 'folder',
      badge: '23',
    }),
};

export const BigIcon: Story = {
  render: () =>
    renderMode({
      label: 'Menu Item',
      subtitle: 'Enterprise',
      bigIcon: true,
    }),
};

export const Checkbox: Story = {
  render: () =>
    renderMode({
      label: 'Menu Item',
      checkbox: true,
    }),
};

/**
 * Drive `UiSidebarMenuButton` from Vue Router using `<RouterLink custom>`:
 *
 * - Render the button as `<a :href="href">` via the `as` + `href` attrs (they
 *   forward to the core primitive) so native link semantics (middle click,
 *   right-click open in new tab, copy link) work.
 * - Bind `:is-active` to the router's `isActive` to reflect the current route
 *   with the active rail treatment.
 * - Call `navigate` from the `@click` handler to delegate navigation.
 *
 * The story uses the Storybook-level router (see `.storybook/preview.ts`) and
 * renders a `<RouterView />` next to the sidebar so route changes are visible.
 */
export const WithVueRouter: Story = {
  parameters: {
    layout: 'fullscreen',
    docs: {
      description: {
        story:
          'Composing `UiSidebarMenuButton` with `<RouterLink custom>` to bind `href`, `isActive`, and `navigate`. The button renders as an `<a>` tag and the active state is driven purely by the current route.',
      },
    },
  },
  render: () => ({
    components: {
      RouterLink,
      RouterView,
      UiIcon,
      UiSidebar,
      UiSidebarContent,
      UiSidebarHeader,
      UiSidebarInset,
      UiSidebarMenu,
      UiSidebarMenuButton,
      UiSidebarMenuItem,
      UiSidebarProvider,
    },
    setup() {
      const router = useRouter();

      const items = [
        { to: '/menu-button-demo/overview', label: 'Overview', icon: 'home' },
        { to: '/menu-button-demo/projects', label: 'Projects', icon: 'folder' },
        {
          to: '/menu-button-demo/settings',
          label: 'Settings',
          icon: 'settings',
        },
      ];

      for (const item of items) {
        if (!router.hasRoute(item.to)) {
          router.addRoute({
            path: item.to,
            name: item.to,
            component: {
              setup: () => ({ label: item.label, to: item.to }),
              template: `
                <div class="flex flex-col gap-2 p-6">
                  <div class="label-12-regular text-content-on-surface-muted">Route</div>
                  <div class="heading-s text-content-on-surface-primary">{{ label }}</div>
                  <div class="body-14-regular text-content-on-surface-muted">
                    Rendered by <code>&lt;RouterView /&gt;</code> for <code>{{ to }}</code>.
                  </div>
                </div>
              `,
            },
          });
        }
      }

      onMounted(() => {
        router.replace(items[0].to);
      });

      return { items };
    },
    template: `
      <UiSidebarProvider :default-open="true">
        <UiSidebar collapsible="icon" class="w-72">
          <UiSidebarHeader tooltip="Toggle sidebar">Navigation</UiSidebarHeader>
          <UiSidebarContent class="p-2">
            <UiSidebarMenu class="gap-y-1">
              <UiSidebarMenuItem v-for="item in items" :key="item.to">
                <RouterLink
                  :to="item.to"
                  custom
                  v-slot="{ href, isActive, navigate }"
                >
                  <UiSidebarMenuButton
                    as="a"
                    :href="href"
                    :tooltip="item.label"
                    :is-active="isActive"
                    @click="navigate"
                  >
                    <template #start-icon>
                      <UiIcon :name="item.icon" size="s" />
                    </template>
                    {{ item.label }}
                  </UiSidebarMenuButton>
                </RouterLink>
              </UiSidebarMenuItem>
            </UiSidebarMenu>
          </UiSidebarContent>
        </UiSidebar>

        <UiSidebarInset>
          <RouterView />
        </UiSidebarInset>
      </UiSidebarProvider>
    `,
  }),
};
