import type { Meta, StoryObj } from '@storybook/vue3-vite';
import UiItem from './UiItem.vue';
import {
  UiItemGroup,
  UiItemSeparator,
  UiItemMedia,
  UiItemContent,
  UiItemTitle,
  UiItemDescription,
  UiItemAction,
} from './index';

import { ItemVariants, ItemSizes } from './constants';
import { UiIcon } from '../UiIcon';
import { UiButton } from '../UiButton';
import {
  UiAvatar,
  UiAvatarFallback,
  UiAvatarGroup,
  UiAvatarImage,
} from '../UiAvatar';

const designStoryLink = '/?path=/docs/components-uiitem--design-notes';
const accessibilityStoryLink = '/?path=/docs/components-uiitem--accessibility';

/**
 * A versatile component that you can use to display any content.
 */
const meta: Meta<typeof UiItem> = {
  title: 'Components/UiItem',
  component: UiItem,
  subcomponents: {
    UiItemGroup,
    UiItemSeparator,
    UiItemMedia,
    UiItemContent,
    UiItemTitle,
    UiItemDescription,
    UiItemAction,
  },
  tags: ['autodocs'],
  argTypes: {
    variant: {
      control: 'select',
      options: ItemVariants,
      description:
        'The visual style of the item. Use `default` for static content, `active` for the current row indicator, `outline` for bordered appearance, `hover` for hover feedback, or `hover-action` for rows with separate actions.',
    },
    size: {
      control: 'select',
      options: ItemSizes,
      description:
        'The size of the item. Use `default` for standard spacing, `sm` for compact dense layouts, or `minimal` for the smallest action affordance.',
    },
    title: {
      control: 'text',
      description: 'Convenience title rendered with UiItemTitle.',
    },
    description: {
      control: 'text',
      description: 'Convenience description rendered with UiItemDescription.',
    },
    desc: {
      control: 'text',
      description: 'Alias for `description`.',
    },
    asChild: {
      control: 'boolean',
      description:
        'Whether to render as a child element using Radix asChild pattern. Useful for rendering as links or custom components while preserving variant/focus states.',
    },
    withListSemantics: {
      control: 'boolean',
      description:
        'Adds role="listitem" for use inside a parent with role="list".',
    },
  },
  args: {
    variant: 'default',
    size: 'default',
    title: 'Basic Item',
    description: 'A simple item with title and description.',
    desc: undefined,
    asChild: false,
    withListSemantics: false,
  },
  parameters: {
    docs: {
      links: [
        {
          label: 'Designer docs',
          href: designStoryLink,
          icon: 'palette',
        },
        {
          label: 'Accessibility',
          href: accessibilityStoryLink,
          icon: 'accessibility',
        },
      ],
    },
  },
};

export default meta;

type Story = StoryObj<typeof UiItem>;

const createSource = (
  imports: string[],
  template: string,
) => `<script setup lang="ts">
import { ${imports.join(', ')} } from '@aleph-alpha/ui-library'
</script>

<template>
${template.trim()}
</template>`;

const defaultTemplate = `
  <div class="w-full max-w-md">
    <UiItem
      variant="hover-action"
      title="Basic Item"
      description="A simple item with title and description."
    />
  </div>
`;

const variantsTemplate = `
  <div class="flex w-full max-w-md flex-col gap-3">
    <UiItem
      title="Default"
      description="Static row with the default trailing action."
    />
    <UiItem
      variant="active"
      title="Active"
      description="Current row with the shared active indicator."
    />
    <UiItem
      variant="outline"
      title="Outline"
      description="Visual outline without changing row height."
    />
    <UiItem
      variant="hover"
      title="Hover"
      description="Row-level hover feedback only."
    />
    <UiItem
      variant="hover-action"
      title="Hover Action"
      description="Separate row and action hover states."
    />
  </div>
`;

const sizesTemplate = `
  <div class="flex w-full max-w-md flex-col gap-3">
    <UiItem
      title="Default Size"
      description="Comfortable spacing and an icon-sm default action."
    />
    <UiItem
      size="sm"
      title="Small Size"
      description="Compact spacing with the same icon-sm default action."
    />
    <UiItem
      size="minimal"
      title="Minimal Size"
      description="Description is hidden and the default action uses icon-xs."
    />
  </div>
`;

const customSlotsTemplate = `
  <div class="w-full max-w-md">
    <UiItem variant="hover-action">
      <template #icon>
        <UiAvatar>
          <UiAvatarImage src="https://i.pravatar.cc/150?u=ui-item" alt="User avatar" />
          <UiAvatarFallback>AR</UiAvatarFallback>
        </UiAvatar>
      </template>

      <template #content>
        <div class="flex items-center gap-2">
          <span class="body-14-medium">Custom Content</span>
        </div>
        <p class="body-14-regular text-content-on-surface-secondary">
          Content, media, and action slots can be fully composed.
        </p>
      </template>

      <template #action>
        <UiButton variant="ghost" size="icon-sm" aria-label="Open item">
          <UiIcon name="external-link" />
        </UiButton>
      </template>
    </UiItem>
  </div>
`;

const withIconTemplate = `
  <div class="flex w-full max-w-md flex-col gap-3">
    <UiItem
      variant="hover"
      title="Security"
      description="Icon slot rendered through the convenience API."
    >
      <template #icon>
        <UiIcon name="shield-check" size="s" />
      </template>
    </UiItem>
    <UiItem
      variant="hover"
      size="minimal"
      title="Minimal Icon Row"
    >
      <template #icon>
        <UiIcon name="bell" size="s" />
      </template>
    </UiItem>
  </div>
`;

const actionsTemplate = `
  <div class="flex w-full max-w-md flex-col gap-3">
    <UiItem
      title="Default Action"
      description="Uses the built-in ghost action and emits the action event."
      @action="() => {}"
    />
    <UiItem
      variant="hover"
      title="Row Hover Only"
      description="The action stays transparent so only the row hover is visible."
    />
    <UiItem
      variant="hover-action"
      title="Custom Action"
      description="Hover-action keeps separate row and button hover states."
    >
      <template #action>
        <UiButton variant="ghost" size="icon-sm" aria-label="Archive">
          <UiIcon name="archive" />
        </UiButton>
      </template>
    </UiItem>
  </div>
`;

const actionTooltipTemplate = `
  <div class="w-full max-w-md">
    <UiItem variant="hover-action" title="Tooltip Action" description="The custom action explains itself on hover or focus.">
      <template #action>
        <UiItemAction tooltip="Archive item">
          <UiButton variant="ghost" size="icon-sm" aria-label="Archive">
            <UiIcon name="archive" />
          </UiButton>
        </UiItemAction>
      </template>
    </UiItem>
  </div>
`;

const mediaTemplate = `
  <div class="flex w-full max-w-md flex-col gap-3">
    <UiItem variant="hover" title="Icon Media" description="Convenience icon slot.">
      <template #icon>
        <UiIcon name="shield-check" size="s" />
      </template>
    </UiItem>

    <UiItem variant="hover">
      <UiItemMedia>
        <UiAvatar>
          <UiAvatarImage src="https://i.pravatar.cc/150?u=media-avatar" alt="Media avatar" />
          <UiAvatarFallback>MA</UiAvatarFallback>
        </UiAvatar>
      </UiItemMedia>
      <UiItemContent>
        <UiItemTitle>Avatar Media</UiItemTitle>
        <UiItemDescription>Composed media slot with an avatar.</UiItemDescription>
      </UiItemContent>
    </UiItem>

    <UiItem variant="hover">
      <UiItemMedia variant="image">
        <UiAvatar>
          <UiAvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
          <UiAvatarFallback>CN</UiAvatarFallback>
        </UiAvatar>
      </UiItemMedia>
      <UiItemContent>
        <UiItemTitle>Avatar Media</UiItemTitle>
        <UiItemDescription>Image media sizes a single avatar.</UiItemDescription>
      </UiItemContent>
    </UiItem>

    <UiItem variant="hover">
      <UiItemMedia variant="avatar-group">
        <UiAvatarGroup>
          <UiAvatar>
            <UiAvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
            <UiAvatarFallback>CN</UiAvatarFallback>
          </UiAvatar>
          <UiAvatar>
            <UiAvatarImage src="https://github.com/leerob.png" alt="@leerob" />
            <UiAvatarFallback>LR</UiAvatarFallback>
          </UiAvatar>
          <UiAvatar>
            <UiAvatarImage src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
            <UiAvatarFallback>ER</UiAvatarFallback>
          </UiAvatar>
        </UiAvatarGroup>
      </UiItemMedia>
      <UiItemContent>
        <UiItemTitle>Avatar Group Media</UiItemTitle>
        <UiItemDescription>Stacked avatars use UiAvatarGroup.</UiItemDescription>
      </UiItemContent>
    </UiItem>

    <UiItem variant="hover">
      <UiItemContent>
        <UiItemTitle>Text Action</UiItemTitle>
        <UiItemDescription>Muted label actions align with trailing content.</UiItemDescription>
      </UiItemContent>
      <UiItemAction variant="text">NEW</UiItemAction>
    </UiItem>

    <UiItem variant="hover-action">
      <UiItemContent>
        <UiItemTitle>Button Action</UiItemTitle>
        <UiItemDescription>Compact button-like action affordance.</UiItemDescription>
      </UiItemContent>
      <UiItemAction variant="button">
        <UiIcon name="plus" size="s" />
      </UiItemAction>
    </UiItem>
  </div>
`;

const groupTemplate = `
  <div class="w-full max-w-md">
    <UiItemGroup class="flex flex-col gap-2">
      <UiItem variant="hover" title="Profile" description="Manage account details.">
        <template #icon>
          <UiIcon name="user" size="s" />
        </template>
      </UiItem>
      <UiItemSeparator />
      <UiItem variant="hover" title="Notifications" description="Configure alert preferences.">
        <template #icon>
          <UiIcon name="bell" size="s" />
        </template>
      </UiItem>
      <UiItemSeparator />
      <UiItem variant="hover-action" title="Billing" description="Review invoices and payment methods.">
        <template #icon>
          <UiIcon name="credit-card" size="s" />
        </template>
      </UiItem>
    </UiItemGroup>
  </div>
`;

const asLinkTemplate = `
  <div class="w-full max-w-md">
    <UiItem variant="hover" as-child>
      <a href="#" class="flex items-center gap-3">
        <UiItemContent>
          <UiItemTitle>Documentation</UiItemTitle>
          <UiItemDescription>
            Render the item as a semantic anchor while keeping row styles.
          </UiItemDescription>
        </UiItemContent>
        <UiItemAction>
          <UiIcon name="arrow-up-right" size="s" />
        </UiItemAction>
      </a>
    </UiItem>
  </div>
`;

const allVariantsTemplate = `
  <div class="flex w-full flex-row justify-between gap-6">
    <UiItemGroup class="flex flex-col gap-2">
      <div class="label-12-medium text-content-on-surface-secondary">Default Variant</div>
      <UiItem title="Default size" description="Standard spacing without row hover." />
      <UiItemSeparator />
      <UiItem size="sm" title="Small size" description="Compact spacing without row hover." />
      <UiItemSeparator />
      <UiItem size="minimal" title="Minimal size" description="Description is omitted." />
    </UiItemGroup>

    <UiItemGroup class="flex flex-col gap-2">
      <div class="label-12-medium text-content-on-surface-secondary">Active Variant</div>
      <UiItem variant="active" title="Default size" description="Active indicator and background." />
      <UiItemSeparator />
      <UiItem variant="active" size="sm" title="Small size" description="Compact active row." />
      <UiItemSeparator />
      <UiItem variant="active" size="minimal" title="Minimal size" description="Description is omitted." />
    </UiItemGroup>

    <UiItemGroup class="flex flex-col gap-2">
      <div class="label-12-medium text-content-on-surface-secondary">Outline Variant</div>
      <UiItem variant="outline" title="Default size" description="Inset outline keeps height stable." />
      <UiItemSeparator />
      <UiItem variant="outline" size="sm" title="Small size" description="Compact outlined row." />
      <UiItemSeparator />
      <UiItem variant="outline" size="minimal" title="Minimal size" description="Description is omitted." />
    </UiItemGroup>

    <UiItemGroup class="flex flex-col gap-2">
      <div class="label-12-medium text-content-on-surface-secondary">Hover Variant</div>
      <UiItem variant="hover" title="Default size" description="Only row hover feedback." />
      <UiItemSeparator />
      <UiItem variant="hover" size="sm" title="Small size" description="Compact row hover feedback." />
      <UiItemSeparator />
      <UiItem variant="hover" size="minimal" title="Minimal size" description="Description is omitted." />
    </UiItemGroup>

    <UiItemGroup class="flex flex-col gap-2">
      <div class="label-12-medium text-content-on-surface-secondary">Hover Action Variant</div>
      <UiItem variant="hover-action" title="Default size" description="Row hover plus action hover." />
      <UiItemSeparator />
      <UiItem variant="hover-action" size="sm" title="Small size" description="Compact row and action hover." />
      <UiItemSeparator />
      <UiItem variant="hover-action" size="minimal" title="Minimal size" description="Description is omitted." />
    </UiItemGroup>
  </div>
`;

/**
 * Default item for common rows that need title, description, and the built-in
 * trailing action. Use this as the starting point for settings or list rows.
 *
 * Key features demonstrated:
 *
 * - Convenience props: `title`, `description`, and `desc`
 * - Visual variants: `default`, `active`, `outline`, `hover`, and `hover-action`
 * - Sizes: `default`, `sm`, and `minimal`
 * - Built-in default action with the `action` emit
 * - Slots: `#icon`, `#content`, `#action`, and the default slot for full composition
 * - Primitive composition through `UiItemMedia`, `UiItemContent`, `UiItemTitle`, `UiItemDescription`, and `UiItemAction`
 * - `asChild` rendering for semantic links or custom interactive roots
 * - Optional list semantics through `withListSemantics` when used inside a `role="list"` parent
 */
export const Basic: Story = {
  render: (args) => ({
    components: {
      UiItem,
    },
    setup() {
      return { args };
    },
    template: `
      <div class="w-full max-w-md">
        <UiItem v-bind="args" />
      </div>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(['UiItem'], defaultTemplate),
      },
    },
  },
};

/**
 * Design guidance for choosing item variants, density, and composition.
 */
export const DesignNotes: Story = {
  render: () => ({
    components: { UiButton },
    template: `
      <section class="flex flex-col gap-8 p-4 bg-surface-secondary">
        <div>
          <h2 class="heading-m font-bold text-content-on-surface-primary">Usage</h2>
          <p class="body-16-regular mt-2 text-content-on-surface-primary">
            The Item component can house nearly any type of content. Use it to display a title,
            description, and actions. Group it with the ItemGroup component to create a list of items.
            Please refer to the stories for examples of different configurations.
          </p>
        </div>
      </section>
    `,
  }),
  parameters: {
    chromatic: {
      disableSnapshot: true,
    },
    docs: {
      canvas: {
        sourceState: 'none',
      },
    },
  },
};

/**
 * Accessibility guidance for item contrast and accessible theme usage.
 */
export const Accessibility: Story = {
  render: () => ({
    components: { UiItem, UiIcon },
    template: `
      <section class="flex flex-col gap-6 p-4">
        <div>
          <h2 class="heading-m font-bold text-content-on-surface-primary">
            Accessibility
          </h2>
        </div>

        <div class="flex flex-col gap-6">
          <div class="flex flex-col gap-2">
            <h3 class="body-16-medium text-content-on-surface-primary">
              Enable accessibility theme
            </h3>
            <p class="body-16-regular text-content-on-surface-primary">
              When accessibility is required, enable our accessibility theme. This increases contrast and makes sure there are no color contrast issues.
            </p>
          </div>
        </div>

        <div class="grid gap-4 md:grid-cols-2">
          <div class="flex flex-col gap-3">
            <h3 class="label-16-medium text-center text-content-on-surface-primary">
              Default
            </h3>
            <div class="flex min-h-20 items-center justify-center border border-border-surface-default p-6">
              <UiItem variant="outline" title="Item title" description="Item description goes here">
                <template #icon>
                  <UiIcon name="folder-open" size="s" />
                </template>
              </UiItem>
            </div>
          </div>

          <div class="accessible-theme flex flex-col gap-3">
            <h3 class="label-16-medium text-center text-content-on-surface-primary">
              Accessible
            </h3>
            <div class="flex min-h-20 items-center justify-center border border-border-surface-default p-6">
              <UiItem variant="outline" title="Item title" description="Item description goes here">
                <template #icon>
                  <UiIcon name="folder-open" size="s" />
                </template>
              </UiItem>
            </div>
          </div>
        </div>
      </section>
    `,
  }),
  parameters: {
    chromatic: {
      disableSnapshot: true,
    },
    docs: {
      canvas: {
        sourceState: 'none',
      },
    },
  },
};

/**
 * Shows each visual variant and when to choose it. Use this to compare static,
 * current, outlined, row-hover, and separate action-hover rows.
 */
export const Variants: Story = {
  render: () => ({
    components: {
      UiItem,
    },
    template: variantsTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(['UiItem'], variantsTemplate),
      },
    },
  },
};

/**
 * Compares item density across the available sizes. Use `minimal` for one-line
 * compact rows where the description should be omitted.
 */
export const Sizes: Story = {
  render: () => ({
    components: {
      UiItem,
    },
    template: sizesTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(['UiItem'], sizesTemplate),
      },
    },
  },
};

/**
 * Demonstrates full slot composition for media, content, and custom action
 * controls. Use slots when the convenience props are too limited.
 */
export const CustomSlots: Story = {
  render: () => ({
    components: {
      UiAvatar,
      UiAvatarFallback,
      UiAvatarImage,
      UiButton,
      UiIcon,
      UiItem,
    },
    template: customSlotsTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(
          [
            'UiAvatar',
            'UiAvatarFallback',
            'UiAvatarImage',
            'UiButton',
            'UiIcon',
            'UiItem',
          ],
          customSlotsTemplate,
        ),
      },
    },
  },
};

/**
 * Uses the convenience `#icon` slot for lightweight leading icons. Prefer this
 * when the media content is decorative or directly supports the row label.
 */
export const WithIcon: Story = {
  render: () => ({
    components: {
      UiIcon,
      UiItem,
    },
    template: withIconTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(['UiIcon', 'UiItem'], withIconTemplate),
      },
    },
  },
};

/**
 * Shows the built-in default action and a custom action slot. Use
 * `hover-action` when the action needs its own hover feedback.
 */
export const Actions: Story = {
  render: () => ({
    components: {
      UiButton,
      UiIcon,
      UiItem,
    },
    template: actionsTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(['UiButton', 'UiIcon', 'UiItem'], actionsTemplate),
      },
    },
  },
};

/**
 * Adds tooltip copy to a custom item action. Use this when an icon-only action
 * needs additional explanation beyond its accessible label.
 */
export const ActionTooltip: Story = {
  render: () => ({
    components: {
      UiButton,
      UiIcon,
      UiItem,
      UiItemAction,
    },
    template: actionTooltipTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(
          ['UiButton', 'UiIcon', 'UiItem', 'UiItemAction'],
          actionTooltipTemplate,
        ),
      },
    },
  },
};

/**
 * Shows the available media patterns: icon, avatar, image, text label, and
 * compact button media. Use the composed media primitive for richer leading content.
 */
export const Media: Story = {
  render: () => ({
    components: {
      UiAvatar,
      UiAvatarFallback,
      UiAvatarGroup,
      UiAvatarImage,
      UiIcon,
      UiItem,
      UiItemAction,
      UiItemContent,
      UiItemDescription,
      UiItemMedia,
      UiItemTitle,
    },
    template: mediaTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(
          [
            'UiAvatar',
            'UiAvatarFallback',
            'UiAvatarGroup',
            'UiAvatarImage',
            'UiIcon',
            'UiItem',
            'UiItemAction',
            'UiItemContent',
            'UiItemDescription',
            'UiItemMedia',
            'UiItemTitle',
          ],
          mediaTemplate,
        ),
      },
    },
  },
};

/**
 * Groups related items with separator lines only. Use this for simple lists
 * where the surrounding layout owns spacing and surface treatment.
 */
export const Group: Story = {
  render: () => ({
    components: {
      UiIcon,
      UiItem,
      UiItemGroup,
      UiItemSeparator,
    },
    template: groupTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(
          ['UiIcon', 'UiItem', 'UiItemGroup', 'UiItemSeparator'],
          groupTemplate,
        ),
      },
    },
  },
};

/**
 * Renders the item as a semantic link while preserving item layout and hover
 * styles. Use `asChild` when the row should navigate.
 */
export const AsLink: Story = {
  render: () => ({
    components: {
      UiIcon,
      UiItem,
      UiItemAction,
      UiItemContent,
      UiItemDescription,
      UiItemTitle,
    },
    template: asLinkTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(
          [
            'UiIcon',
            'UiItem',
            'UiItemAction',
            'UiItemContent',
            'UiItemDescription',
            'UiItemTitle',
          ],
          asLinkTemplate,
        ),
      },
    },
  },
};

/**
 * Overview of every visual variant with every size in one place. Use this for
 * visual QA rather than as copy-paste guidance for a single use case.
 */
export const AllVariants: Story = {
  render: () => ({
    components: {
      UiItem,
      UiItemGroup,
      UiItemSeparator,
    },
    template: allVariantsTemplate,
  }),
  parameters: {
    docs: {
      source: {
        code: createSource(
          ['UiItem', 'UiItemGroup', 'UiItemSeparator'],
          allVariantsTemplate,
        ),
      },
    },
  },
};
