import type { Meta, StoryObj } from '@storybook/vue3-vite';
import { ref } from 'vue';
import { UiToggleGroup, UiToggleGroupItem } from './index';
import { UiIcon } from '../UiIcon';

/**
 * Shared item configurations for consistent stories.
 */
const formattingItems = [
  { value: 'bold', icon: 'bold', label: 'Toggle bold' },
  { value: 'italic', icon: 'italic', label: 'Toggle italic' },
  { value: 'underline', icon: 'underline', label: 'Toggle underline' },
];

const alignmentItems = [
  { value: 'left', icon: 'align-left', label: 'Align left' },
  { value: 'center', icon: 'align-center', label: 'Align center' },
  { value: 'right', icon: 'align-right', label: 'Align right' },
];

const viewItems = [
  { value: 'list', icon: 'list', label: 'List view' },
  { value: 'grid', icon: 'layout-grid', label: 'Grid view' },
  { value: 'columns', icon: 'columns-3', label: 'Column view' },
];

/**
 * Helper factory to create render functions with consistent setup.
 * @param config - Configuration object for the toggle group render.
 * @param config.type - The selection type: 'single' or 'multiple'.
 * @param config.items - Array of items to render in the toggle group.
 * @param [config.initialValue] - Initial selected value(s).
 * @param [config.variant] - Visual style variant: 'default' or 'outline'.
 * @param [config.size] - Size of the toggle group: 'default', 'sm', or 'lg'.
 * @param [config.disabled] - Whether the entire group is disabled.
 * @param [config.itemDisabledIndex] - Index of a specific item to disable.
 * @param [config.showLabels] - Whether to show text labels alongside icons.
 */
const createToggleGroupRender = (config: {
  type: 'single' | 'multiple';
  items: typeof formattingItems;
  initialValue?: string | string[];
  variant?: 'default' | 'outline';
  size?: 'default' | 'sm' | 'lg';
  disabled?: boolean;
  itemDisabledIndex?: number;
  showLabels?: boolean;
}) => {
  return (args: Record<string, unknown>) => ({
    components: { UiToggleGroup, UiToggleGroupItem, UiIcon },
    setup() {
      const value = ref(
        config.initialValue ?? (config.type === 'single' ? '' : []),
      );
      return { args, value, config };
    },
    template: `
      <UiToggleGroup
        v-model="value"
        :type="config.type"
        :variant="args.variant ?? config.variant"
        :size="args.size ?? config.size"
        :disabled="args.disabled ?? config.disabled"
      >
        <UiToggleGroupItem
          v-for="(item, index) in config.items"
          :key="item.value"
          :value="item.value"
          :aria-label="item.label"
          :disabled="config.itemDisabledIndex === index"
        >
          <UiIcon :name="item.icon" :size="16" />
          <span v-if="config.showLabels">{{ item.label.replace('Toggle ', '').replace('Align ', '') }}</span>
        </UiToggleGroupItem>
      </UiToggleGroup>
    `,
  });
};

/**
 * UiToggleGroup is a horizontal group of related toggle buttons supporting single- or multi-selection.
 * Use it for text-formatting toolbars, view-mode switchers, and feature toggles; for a single standalone toggle, use `UiToggle`.
 */
const meta: Meta<typeof UiToggleGroup> = {
  title: 'Components/UiToggleGroup',
  component: UiToggleGroup,
  subcomponents: { UiToggleGroupItem },
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component:
          'A set of two-state buttons that can be toggled on or off. Supports single selection (like radio buttons) or multiple selection (like checkboxes). Use for toolbar actions, formatting options, or view toggles.',
      },
    },
  },
  argTypes: {
    type: {
      control: 'select',
      options: ['single', 'multiple'],
      description:
        'The type of selection: single (one at a time) or multiple (many at once)',
    },
    variant: {
      control: 'select',
      options: ['default', 'outline'],
      description: 'The visual style variant applied to all items',
    },
    size: {
      control: 'select',
      options: ['default', 'sm', 'lg'],
      description: 'The size applied to all items',
    },
    disabled: {
      control: 'boolean',
      description: 'Whether the entire group is disabled',
    },
    orientation: {
      control: 'select',
      options: ['horizontal', 'vertical'],
      description: 'The orientation for keyboard navigation',
    },
  },
  args: {
    type: 'multiple',
    variant: 'default',
    size: 'default',
    disabled: false,
    orientation: 'horizontal',
  },
};

export default meta;

type Story = StoryObj<typeof UiToggleGroup>;

/**
 * The default toggle group with multiple selection enabled.
 * Users can select multiple options simultaneously, similar to checkboxes.
 *
 * **Use cases:**
 * - Text formatting toolbars (bold, italic, underline)
 * - Filter selections
 * - Feature toggles
 */
export const Default: Story = {
  render: createToggleGroupRender({
    type: 'multiple',
    items: formattingItems,
  }),
};

/**
 * The outline variant provides a bordered appearance with a subtle shadow.
 * Use this when you need more visual prominence or when placing on colored backgrounds.
 *
 * **Best for:**
 * - Prominent toolbar actions
 * - Standalone toggle groups
 * - Higher contrast requirements
 */
export const Outline: Story = {
  render: createToggleGroupRender({
    type: 'multiple',
    items: formattingItems,
    variant: 'outline',
  }),
};

/**
 * When `type="single"`, only one item can be selected at a time.
 * Selecting a new item automatically deselects the previous one.
 *
 * **Use cases:**
 * - View mode selectors (list/grid)
 * - Alignment options (left/center/right)
 * - Exclusive options where only one can be active
 */
export const Single: Story = {
  render: createToggleGroupRender({
    type: 'single',
    items: alignmentItems,
    initialValue: 'center',
  }),
};

/**
 * The small size variant (`size="sm"`) provides a more compact toggle group.
 * Use this when space is limited or for secondary actions.
 *
 * **Best for:**
 * - Compact toolbars
 * - Inline controls
 * - Dense UI layouts
 */
export const Small: Story = {
  render: createToggleGroupRender({
    type: 'single',
    items: alignmentItems,
    size: 'sm',
    initialValue: 'left',
  }),
};

/**
 * The large size variant (`size="lg"`) provides bigger touch targets.
 * Use this for primary actions or touch-friendly interfaces.
 *
 * **Best for:**
 * - Touch interfaces
 * - Primary toolbars
 * - Accessibility-focused designs
 */
export const Large: Story = {
  render: createToggleGroupRender({
    type: 'multiple',
    items: formattingItems,
    size: 'lg',
  }),
};

/**
 * The disabled state prevents all interaction with the toggle group.
 * Use this when the options are temporarily unavailable.
 *
 * **Note:** You can also disable individual items using the `disabled` prop
 * on `UiToggleGroupItem`.
 */
export const Disabled: Story = {
  render: createToggleGroupRender({
    type: 'multiple',
    items: formattingItems,
    disabled: true,
  }),
};

/**
 * Toggle group items can include both icons and text labels for better clarity.
 * This is useful when the icon alone might not clearly convey the action.
 *
 * **Best for:**
 * - Complex options that need explanation
 * - Less frequently used features
 * - Accessibility improvements
 */
export const WithText: Story = {
  render: createToggleGroupRender({
    type: 'single',
    items: alignmentItems,
    variant: 'outline',
    initialValue: 'left',
    showLabels: true,
  }),
};

/**
 * A common pattern for switching between different view modes.
 * This example shows a list/grid/column view selector.
 *
 * **Use cases:**
 * - File browsers
 * - Product listings
 * - Dashboard layouts
 */
export const ViewToggle: Story = {
  render: createToggleGroupRender({
    type: 'single',
    items: viewItems,
    variant: 'outline',
    initialValue: 'grid',
  }),
};

/**
 * Individual items can be disabled while keeping others interactive.
 * This is useful when certain options are temporarily unavailable.
 *
 * **Use cases:**
 * - Premium features that require upgrade
 * - Context-dependent options
 * - Temporarily unavailable actions
 */
export const IndividualDisabled: Story = {
  render: createToggleGroupRender({
    type: 'multiple',
    items: formattingItems,
    variant: 'outline',
    initialValue: ['bold'],
    itemDisabledIndex: 1,
  }),
};

/**
 * A comprehensive showcase of all toggle group states and variations in a single view.
 * This is useful for:
 *
 * - **Visual QA**: Quickly verify all states look correct
 * - **Design review**: See all variations side by side
 * - **Documentation**: Reference for available options
 *
 * ### Variants
 * - Default, Outline
 *
 * ### Sizes
 * - Small, Default, Large
 *
 * ### Types
 * - Single selection, Multiple selection
 *
 * ### States
 * - Normal, Disabled, Individual disabled
 */
export const AllStates: Story = {
  render: () => ({
    components: { UiToggleGroup, UiToggleGroupItem, UiIcon },
    setup() {
      const multipleDefault = ref<string[]>(['bold']);
      const multipleOutline = ref<string[]>(['italic']);
      const singleValue = ref<string>('center');
      const smallValue = ref<string>('left');
      const defaultSizeValue = ref<string[]>(['bold', 'italic']);
      const largeValue = ref<string[]>(['underline']);
      const disabledValue = ref<string[]>([]);
      const partialDisabled = ref<string[]>(['bold']);
      return {
        multipleDefault,
        multipleOutline,
        singleValue,
        smallValue,
        defaultSizeValue,
        largeValue,
        disabledValue,
        partialDisabled,
        formattingItems,
        alignmentItems,
      };
    },
    template: `
      <div class="flex flex-col gap-8 w-full max-w-2xl">
        <section>
          <h3 class="text-lg font-semibold mb-4">Variants</h3>
          <div class="flex flex-col gap-4">
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Default:</span>
              <UiToggleGroup v-model="multipleDefault" type="multiple">
                <UiToggleGroupItem v-for="item in formattingItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Outline:</span>
              <UiToggleGroup v-model="multipleOutline" type="multiple" variant="outline">
                <UiToggleGroupItem v-for="item in formattingItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
          </div>
        </section>

        <section>
          <h3 class="text-lg font-semibold mb-4">Selection Types</h3>
          <div class="flex flex-col gap-4">
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Single:</span>
              <UiToggleGroup v-model="singleValue" type="single" variant="outline">
                <UiToggleGroupItem v-for="item in alignmentItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Multiple:</span>
              <UiToggleGroup v-model="defaultSizeValue" type="multiple" variant="outline">
                <UiToggleGroupItem v-for="item in formattingItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
          </div>
        </section>

        <section>
          <h3 class="text-lg font-semibold mb-4">Sizes</h3>
          <div class="flex flex-col gap-4">
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Small:</span>
              <UiToggleGroup v-model="smallValue" type="single" variant="outline" size="sm">
                <UiToggleGroupItem v-for="item in alignmentItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Default:</span>
              <UiToggleGroup v-model="defaultSizeValue" type="multiple" variant="outline">
                <UiToggleGroupItem v-for="item in formattingItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Large:</span>
              <UiToggleGroup v-model="largeValue" type="multiple" variant="outline" size="lg">
                <UiToggleGroupItem v-for="item in formattingItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
          </div>
        </section>

        <section>
          <h3 class="text-lg font-semibold mb-4">Disabled States</h3>
          <div class="flex flex-col gap-4">
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">All disabled:</span>
              <UiToggleGroup v-model="disabledValue" type="multiple" variant="outline" disabled>
                <UiToggleGroupItem v-for="item in formattingItems" :key="item.value" :value="item.value" :aria-label="item.label">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
            <div class="flex items-center gap-4">
              <span class="text-sm text-muted-foreground w-24">Partial:</span>
              <UiToggleGroup v-model="partialDisabled" type="multiple" variant="outline">
                <UiToggleGroupItem v-for="(item, index) in formattingItems" :key="item.value" :value="item.value" :aria-label="item.label" :disabled="index === 1">
                  <UiIcon :name="item.icon" :size="16" />
                </UiToggleGroupItem>
              </UiToggleGroup>
            </div>
          </div>
        </section>

        <section>
          <h3 class="text-lg font-semibold mb-4">With Text Labels</h3>
          <UiToggleGroup v-model="singleValue" type="single" variant="outline">
            <UiToggleGroupItem v-for="item in alignmentItems" :key="item.value" :value="item.value" :aria-label="item.label">
              <UiIcon :name="item.icon" :size="16" />
              {{ item.label.replace('Align ', '') }}
            </UiToggleGroupItem>
          </UiToggleGroup>
        </section>
      </div>
    `,
  }),
};
