import type { Meta, StoryObj } from '@storybook/vue3-vite';
import UiBadge from './UiBadge.vue';
import { BadgeSizes, BadgeVariants } from './constants';
import { UiIcon } from '../UiIcon';

const InfoIcon = {
  components: { UiIcon },
  template: '<UiIcon name="info" :size="14" />',
};

const XIcon = {
  components: { UiIcon },
  template: '<UiIcon name="x" :size="14" />',
};

const CheckIcon = {
  components: { UiIcon },
  template: '<UiIcon name="badge-check" :size="14" />',
};

const variantLabels = {
  default: 'Default',
  secondary: 'Secondary',
  outline: 'Outline',
  destructive: 'Destructive',
  success: 'Success',
  warning: 'Warning',
  verified: 'Verified',
} as const;

/**
 * UiBadge is a compact, non-interactive label for counts, statuses, or short metadata attached to a parent element.
 * Use the variant prop to convey intent (default, secondary, outline, destructive, success, warning, verified).
 * For interactive selections like filters or removable tags, use `UiChip` instead.
 */
const meta: Meta<typeof UiBadge> = {
  title: 'Components/UiBadge',
  component: UiBadge,
  tags: ['autodocs'],
  argTypes: {
    variant: {
      control: 'select',
      options: BadgeVariants,
      description: 'The visual style of the badge',
    },
    size: {
      control: 'select',
      options: BadgeSizes,
      description: 'The size of the badge',
    },
    disabled: {
      control: 'boolean',
      description: 'Disables the badge',
    },
    startIcon: {
      control: false,
      description: 'Icon component to display before the badge text',
    },
    endIcon: {
      control: false,
      description: 'Icon component to display after the badge text',
    },
  },
  args: {
    variant: 'default',
    size: 'default',
    disabled: false,
  },
};

export default meta;

type Story = StoryObj<typeof UiBadge>;

function createVariantStory(variant: keyof typeof variantLabels): Story {
  const label = variantLabels[variant];

  return {
    render: () => ({
      components: { UiBadge },
      template: `<UiBadge variant="${variant}">${label}</UiBadge>`,
    }),
    parameters: {
      docs: {
        source: {
          code: `<script setup lang="ts">
import { UiBadge } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiBadge variant="${variant}">${label}</UiBadge>
</template>`,
        },
      },
    },
  };
}

/**
 * Accent badge variant for primary emphasis.
 */
export const Default: Story = createVariantStory('default');

/**
 * Neutral badge variant for secondary emphasis.
 */
export const Secondary: Story = createVariantStory('secondary');

/**
 * Minimal bordered badge variant.
 */
export const Outline: Story = createVariantStory('outline');

/**
 * Destructive badge variant for errors or critical states.
 */
export const Destructive: Story = createVariantStory('destructive');

/**
 * Success badge variant for positive outcomes or completion.
 */
export const Success: Story = createVariantStory('success');

/**
 * Warning badge variant for caution or attention-needed states.
 */
export const Warning: Story = createVariantStory('warning');

/**
 * Verified badge variant using accent emphasis (e.g. trust or confirmation).
 */
export const Verified: Story = createVariantStory('verified');

/**
 * Disabled badges suppress hover treatment and reduce emphasis.
 */
export const Disabled: Story = {
  render: () => ({
    components: { UiBadge },
    template: `
      <div class="flex flex-wrap items-center gap-2">
        <UiBadge
          v-for="variant in badgeVariants"
          :key="variant"
          :variant="variant"
          disabled
        >
          {{ variantLabels[variant] }}
        </UiBadge>
      </div>
    `,
    setup() {
      return { variantLabels, badgeVariants: BadgeVariants };
    },
  }),
};

/**
 * Leading icons work across the supported badge variants.
 */
export const WithStartIcon: Story = {
  render: () => ({
    components: { UiBadge },
    setup() {
      return { CheckIcon };
    },
    template: `
      <div class="flex flex-wrap items-center gap-2">
        <UiBadge variant="default" :start-icon="CheckIcon">Default</UiBadge>
        <UiBadge variant="secondary" :start-icon="CheckIcon">Secondary</UiBadge>
      </div>
    `,
  }),
};

/**
 * Trailing icons can be used for dismiss or status affordances.
 */
export const WithEndIcon: Story = {
  render: () => ({
    components: { UiBadge },
    setup() {
      return { XIcon };
    },
    template: `
      <div class="flex flex-wrap items-center gap-2">
        <UiBadge variant="secondary" :end-icon="XIcon">Secondary</UiBadge>
        <UiBadge variant="destructive" :end-icon="XIcon">Destructive</UiBadge>
      </div>
    `,
  }),
};

/**
 * You can combine leading and trailing icons on the same badge.
 */
export const WithBothIcons: Story = {
  render: () => ({
    components: { UiBadge },
    setup() {
      return { InfoIcon, XIcon };
    },
    template: `
      <UiBadge variant="default" :start-icon="InfoIcon" :end-icon="XIcon">
        Default
      </UiBadge>
    `,
  }),
};

/**
 * Icon slots remain available for custom badge layouts.
 */
export const WithIconSlot: Story = {
  render: () => ({
    components: { UiBadge, UiIcon },
    template: `
      <UiBadge variant="default">
        <UiIcon name="badge-check" :size="12" />
        Default
      </UiBadge>
    `,
  }),
};

/**
 * Numeric badges across all variants in default and disabled states.
 */
export const Numbers: Story = {
  render: () => ({
    components: { UiBadge },
    setup() {
      const variants = BadgeVariants.map((variant) => ({
        key: variant,
        label: variantLabels[variant],
      }));

      const states = [
        { key: 'default', label: 'Default', disabled: false },
        { key: 'disabled', label: 'Disabled', disabled: true },
      ];

      return { states, variants };
    },
    template: `
      <div class="overflow-x-auto rounded-lg border border-border-surface-default p-4">
        <div
          class="grid min-w-[920px] gap-x-4 gap-y-3"
          :style="{ gridTemplateColumns: '120px repeat(' + variants.length + ', minmax(0, 1fr))' }"
        >
          <div class="text-xs font-medium text-content-on-surface-muted">Variant</div>
          <div
            v-for="variant in variants"
            :key="variant.key"
            class="text-xs font-medium text-content-on-surface-muted"
          >
            {{ variant.label }}
          </div>

          <template v-for="state in states" :key="state.key">
            <div class="text-xs font-medium text-content-on-surface-muted">
              {{ state.label }}
            </div>

            <div v-for="variant in variants" :key="state.key + '-' + variant.key">
              <UiBadge :variant="variant.key" size="small" :disabled="state.disabled">10</UiBadge>
            </div>
          </template>
        </div>
      </div>
    `,
  }),
};

/**
 * Available badge sizes across all variants.
 */
export const Sizes: Story = {
  render: () => ({
    components: { UiBadge },
    setup() {
      const variants = BadgeVariants.map((variant) => ({
        key: variant,
        label: variantLabels[variant],
      }));

      const sizes = BadgeSizes.map((size) => ({
        key: size,
        label: size === 'default' ? 'Default' : 'Small',
      }));

      return { sizes, variants };
    },
    template: `
      <div class="overflow-x-auto rounded-lg border border-border-surface-default p-4">
        <div
          class="grid min-w-[920px] items-center gap-x-4 gap-y-3"
          :style="{ gridTemplateColumns: '120px repeat(' + variants.length + ', minmax(0, 1fr))' }"
        >
          <div class="text-xs font-medium text-content-on-surface-muted">Size</div>
          <div
            v-for="variant in variants"
            :key="variant.key"
            class="text-xs font-medium text-content-on-surface-muted"
          >
            {{ variant.label }}
          </div>

          <template v-for="size in sizes" :key="size.key">
            <div class="text-xs font-medium text-content-on-surface-muted">
              {{ size.label }}
            </div>

            <div v-for="variant in variants" :key="size.key + '-' + variant.key">
              <UiBadge :variant="variant.key" :size="size.key">
                {{ variant.label }}
              </UiBadge>
            </div>
          </template>
        </div>
      </div>
    `,
  }),
};

/**
 * All badge variants shown in both sizes, in default and disabled states.
 */
export const AllVariants: Story = {
  render: () => ({
    components: { UiBadge },
    setup() {
      const variants = BadgeVariants.map((variant) => ({
        key: variant,
        label: variantLabels[variant],
      }));

      const rows = BadgeSizes.flatMap((size) => {
        const sizeLabel = size === 'default' ? 'Default' : 'Small';
        return [
          { key: `${size}-default`, label: sizeLabel, size, disabled: false },
          {
            key: `${size}-disabled`,
            label: `${sizeLabel} · Disabled`,
            size,
            disabled: true,
          },
        ];
      });

      return { rows, variants };
    },
    template: `
      <div class="overflow-x-auto rounded-lg border border-border-surface-default p-4">
        <div
          class="grid min-w-[920px] items-center gap-x-4 gap-y-3"
          :style="{ gridTemplateColumns: '160px repeat(' + variants.length + ', minmax(0, 1fr))' }"
        >
          <div class="text-xs font-medium text-content-on-surface-muted">Variant</div>
          <div
            v-for="variant in variants"
            :key="variant.key"
            class="text-xs font-medium text-content-on-surface-muted"
          >
            {{ variant.label }}
          </div>

          <template v-for="row in rows" :key="row.key">
            <div class="text-xs font-medium text-content-on-surface-muted">
              {{ row.label }}
            </div>

            <div v-for="variant in variants" :key="row.key + '-' + variant.key">
              <UiBadge :variant="variant.key" :size="row.size" :disabled="row.disabled">
                {{ variant.label }}
              </UiBadge>
            </div>
          </template>
        </div>
      </div>
    `,
  }),
};
