import type { Meta, StoryObj } from '@storybook/vue3-vite';
import { ref } from 'vue';
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
  UiSelectLabel,
  UiSelectGroup,
  UiSelectSeparator,
} from './index';
import { UiIcon } from '@/components/UiIcon';

/**
 * UiSelect is a trigger-and-dropdown primitive for choosing one option from a list, with grouped options, separators, and labels.
 * Use it for compact form selects; for filterable or always-visible lists, prefer `UiListbox`.
 */
const meta: Meta<typeof UiSelect> = {
  title: 'Components/UiSelect',
  component: UiSelect,
  tags: ['autodocs'],
  argTypes: {
    modelValue: {
      control: 'text',
      description: 'The controlled value of the select (use with v-model)',
    },
    disabled: {
      control: 'boolean',
      description: 'Whether the select is disabled',
    },
    required: {
      control: 'boolean',
      description: 'Whether the select is required in a form',
    },
  },
  args: {
    disabled: false,
    required: false,
  },
};

export default meta;

type Story = StoryObj<typeof UiSelect>;

const defaultTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '@aleph-alpha/ui-library'

const value = ref('')
</script>

<template>
  <UiSelect v-model="value">
    <UiSelectTrigger ariaLabel="Select option">
      <UiSelectValue placeholder="Select a fruit" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectItem value="apple">Apple</UiSelectItem>
      <UiSelectItem value="banana">Banana</UiSelectItem>
      <UiSelectItem value="orange">Orange</UiSelectItem>
    </UiSelectContent>
  </UiSelect>
</template>`;

/**
 * Default select dropdown with simple options.
 * Click the trigger to open the dropdown and select an item.
 */
export const Default: Story = {
  render: (args) => ({
    components: {
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
    },
    setup() {
      const value = ref('');
      return { args, value };
    },
    template: `
      <UiSelect v-model="value" v-bind="args">
        <UiSelectTrigger ariaLabel="Select option">
          <UiSelectValue placeholder="Select a fruit" />
        </UiSelectTrigger>
        <UiSelectContent>
          <UiSelectItem value="apple">Apple</UiSelectItem>
          <UiSelectItem value="banana">Banana</UiSelectItem>
          <UiSelectItem value="orange">Orange</UiSelectItem>
          <UiSelectItem value="grape">Grape</UiSelectItem>
          <UiSelectItem value="mango">Mango</UiSelectItem>
        </UiSelectContent>
      </UiSelect>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: defaultTemplateSource,
      },
    },
  },
};

const withGroupsTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
  UiSelectLabel,
  UiSelectGroup,
  UiSelectSeparator,
} from '@aleph-alpha/ui-library'

const value = ref('')
</script>

<template>
  <UiSelect v-model="value">
    <UiSelectTrigger ariaLabel="Select option">
      <UiSelectValue placeholder="Select a food" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectGroup>
        <UiSelectLabel>Fruits</UiSelectLabel>
        <UiSelectItem value="apple">Apple</UiSelectItem>
        <UiSelectItem value="banana">Banana</UiSelectItem>
        <UiSelectItem value="orange">Orange</UiSelectItem>
      </UiSelectGroup>
      <UiSelectSeparator />
      <UiSelectGroup>
        <UiSelectLabel>Vegetables</UiSelectLabel>
        <UiSelectItem value="carrot">Carrot</UiSelectItem>
        <UiSelectItem value="broccoli">Broccoli</UiSelectItem>
        <UiSelectItem value="spinach">Spinach</UiSelectItem>
      </UiSelectGroup>
    </UiSelectContent>
  </UiSelect>
</template>`;

/**
 * Select with grouped options using labels and separators.
 */
export const WithGroups: Story = {
  render: (args) => ({
    components: {
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
      UiSelectLabel,
      UiSelectGroup,
      UiSelectSeparator,
    },
    setup() {
      const value = ref('');
      return { args, value };
    },
    template: `
      <UiSelect v-model="value" v-bind="args">
        <UiSelectTrigger ariaLabel="Select option">
          <UiSelectValue placeholder="Select a food" />
        </UiSelectTrigger>
        <UiSelectContent>
          <UiSelectGroup>
            <UiSelectLabel>Fruits</UiSelectLabel>
            <UiSelectItem value="apple">Apple</UiSelectItem>
            <UiSelectItem value="banana">Banana</UiSelectItem>
            <UiSelectItem value="orange">Orange</UiSelectItem>
          </UiSelectGroup>
          <UiSelectSeparator />
          <UiSelectGroup>
            <UiSelectLabel>Vegetables</UiSelectLabel>
            <UiSelectItem value="carrot">Carrot</UiSelectItem>
            <UiSelectItem value="broccoli">Broccoli</UiSelectItem>
            <UiSelectItem value="spinach">Spinach</UiSelectItem>
          </UiSelectGroup>
        </UiSelectContent>
      </UiSelect>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: withGroupsTemplateSource,
      },
    },
  },
};

const withDisabledItemsTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '@aleph-alpha/ui-library'

const value = ref('')
</script>

<template>
  <UiSelect v-model="value">
    <UiSelectTrigger ariaLabel="Select option">
      <UiSelectValue placeholder="Select a plan" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectItem value="free">Free Plan</UiSelectItem>
      <UiSelectItem value="pro">Pro Plan</UiSelectItem>
      <UiSelectItem value="enterprise" :disabled="true">Enterprise (Contact Sales)</UiSelectItem>
    </UiSelectContent>
  </UiSelect>
</template>`;

/**
 * Select with some disabled items that cannot be selected.
 */
export const WithDisabledItems: Story = {
  render: (args) => ({
    components: {
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
    },
    setup() {
      const value = ref('');
      return { args, value };
    },
    template: `
      <UiSelect v-model="value" v-bind="args">
        <UiSelectTrigger ariaLabel="Select option">
          <UiSelectValue placeholder="Select a plan" />
        </UiSelectTrigger>
        <UiSelectContent>
          <UiSelectItem value="free">Free Plan</UiSelectItem>
          <UiSelectItem value="pro">Pro Plan</UiSelectItem>
          <UiSelectItem value="enterprise" :disabled="true">Enterprise (Contact Sales)</UiSelectItem>
        </UiSelectContent>
      </UiSelect>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: withDisabledItemsTemplateSource,
      },
    },
  },
};

const withIconsTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiIcon,
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '@aleph-alpha/ui-library'

const value = ref('')
</script>

<template>
  <UiSelect v-model="value">
    <UiSelectTrigger ariaLabel="Select option" class="w-[220px]">
      <UiSelectValue placeholder="Select chart type" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectItem value="line">
        <div class="flex items-center gap-3">
          <UiIcon name="chart-line" size="s" />
          <span>Line</span>
        </div>
      </UiSelectItem>
      <UiSelectItem value="bar">
        <div class="flex items-center gap-3">
          <UiIcon name="chart-bar" size="s" />
          <span>Bar</span>
        </div>
      </UiSelectItem>
      <UiSelectItem value="pie">
        <div class="flex items-center gap-3">
          <UiIcon name="chart-pie" size="s" />
          <span>Pie</span>
        </div>
      </UiSelectItem>
    </UiSelectContent>
  </UiSelect>
</template>`;

/**
 * Select items can render icons in their default slot. Use this for visual
 * option lists where each choice has a leading symbol.
 */
export const WithIcons: Story = {
  render: (args) => ({
    components: {
      UiIcon,
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
    },
    setup() {
      const value = ref('');
      return { args, value };
    },
    template: `
      <UiSelect v-model="value" v-bind="args">
        <UiSelectTrigger ariaLabel="Select option" class="w-[220px]">
          <UiSelectValue placeholder="Select chart type" />
        </UiSelectTrigger>
        <UiSelectContent>
          <UiSelectItem value="line">
            <div class="flex items-center gap-3">
              <UiIcon name="chart-line" size="s" />
              <span>Line</span>
            </div>
          </UiSelectItem>
          <UiSelectItem value="bar">
            <div class="flex items-center gap-3">
              <UiIcon name="chart-bar" size="s" />
              <span>Bar</span>
            </div>
          </UiSelectItem>
          <UiSelectItem value="pie">
            <div class="flex items-center gap-3">
              <UiIcon name="chart-pie" size="s" />
              <span>Pie</span>
            </div>
          </UiSelectItem>
        </UiSelectContent>
      </UiSelect>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: withIconsTemplateSource,
      },
    },
  },
};

const disabledTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '@aleph-alpha/ui-library'

const value = ref('')
</script>

<template>
  <UiSelect v-model="value" :disabled="true">
    <UiSelectTrigger ariaLabel="Select option">
      <UiSelectValue placeholder="Select an option" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectItem value="option1">Option 1</UiSelectItem>
      <UiSelectItem value="option2">Option 2</UiSelectItem>
    </UiSelectContent>
  </UiSelect>
</template>`;

/**
 * Disabled select that cannot be interacted with.
 */
export const Disabled: Story = {
  render: () => ({
    components: {
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
    },
    setup() {
      const value = ref('');
      return { value };
    },
    template: `
      <UiSelect v-model="value" :disabled="true">
        <UiSelectTrigger ariaLabel="Select option">
          <UiSelectValue placeholder="Select an option" />
        </UiSelectTrigger>
        <UiSelectContent>
          <UiSelectItem value="option1">Option 1</UiSelectItem>
          <UiSelectItem value="option2">Option 2</UiSelectItem>
        </UiSelectContent>
      </UiSelect>
    `,
  }),
  args: { disabled: true },
  parameters: {
    docs: {
      source: {
        code: disabledTemplateSource,
      },
    },
  },
};

const withDefaultValueTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '@aleph-alpha/ui-library'

const value = ref('banana')
</script>

<template>
  <UiSelect v-model="value">
    <UiSelectTrigger ariaLabel="Select option">
      <UiSelectValue placeholder="Select a fruit" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectItem value="apple">Apple</UiSelectItem>
      <UiSelectItem value="banana">Banana</UiSelectItem>
      <UiSelectItem value="orange">Orange</UiSelectItem>
    </UiSelectContent>
  </UiSelect>
</template>`;

const multipleTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '@aleph-alpha/ui-library'

const value = ref<string[]>([])
</script>

<template>
  <!--
    The trigger keeps a fixed width. Selected values render as a
    comma-separated list and truncate with an ellipsis instead of
    stretching the trigger when more items are selected.
  -->
  <UiSelect v-model="value" :multiple="true">
    <UiSelectTrigger ariaLabel="Select option" class="w-[220px]">
      <UiSelectValue placeholder="Select fruits" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectItem value="apple">Apple</UiSelectItem>
      <UiSelectItem value="banana">Banana</UiSelectItem>
      <UiSelectItem value="orange">Orange</UiSelectItem>
      <UiSelectItem value="grape">Grape</UiSelectItem>
      <UiSelectItem value="mango">Mango</UiSelectItem>
    </UiSelectContent>
  </UiSelect>
</template>`;

/**
 * Multi-select mode. Pass `multiple` to use the same select primitive with
 * array values. The dropdown stays open between clicks so users can toggle several
 * items, the selected values are emitted as an array via `update:modelValue`,
 * and the trigger renders the selected items as a comma-separated list that
 * truncates with an ellipsis when it exceeds the trigger's width.
 */
export const Multiple: Story = {
  render: () => ({
    components: {
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
    },
    setup() {
      const value = ref<string[]>([]);
      return { value };
    },
    template: `
      <div class="flex flex-col gap-3">
        <UiSelect v-model="value" :multiple="true">
          <UiSelectTrigger ariaLabel="Select option" class="w-[220px]">
            <UiSelectValue placeholder="Select fruits" />
          </UiSelectTrigger>
          <UiSelectContent>
            <UiSelectItem value="apple">Apple</UiSelectItem>
            <UiSelectItem value="banana">Banana</UiSelectItem>
            <UiSelectItem value="orange">Orange</UiSelectItem>
            <UiSelectItem value="grape">Grape</UiSelectItem>
            <UiSelectItem value="mango">Mango</UiSelectItem>
          </UiSelectContent>
        </UiSelect>
        <div class="text-xs text-content-on-surface-secondary">Selected: {{ value.join(', ') || '—' }}</div>
      </div>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: multipleTemplateSource,
      },
    },
  },
};

const multipleWithDefaultTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import {
  UiSelect,
  UiSelectTrigger,
  UiSelectContent,
  UiSelectItem,
  UiSelectValue,
} from '@aleph-alpha/ui-library'

const value = ref<string[]>(['banana', 'mango'])
</script>

<template>
  <UiSelect v-model="value" :multiple="true">
    <UiSelectTrigger ariaLabel="Select option" class="w-[260px]">
      <UiSelectValue placeholder="Select fruits" />
    </UiSelectTrigger>
    <UiSelectContent>
      <UiSelectItem value="apple">Apple</UiSelectItem>
      <UiSelectItem value="banana">Banana</UiSelectItem>
      <UiSelectItem value="orange">Orange</UiSelectItem>
      <UiSelectItem value="grape">Grape</UiSelectItem>
      <UiSelectItem value="mango">Mango</UiSelectItem>
    </UiSelectContent>
  </UiSelect>
</template>`;

/**
 * Multi-select with a pre-selected list of values. The trigger renders the
 * matching item labels even before the dropdown is opened.
 */
export const MultipleWithDefaultValue: Story = {
  render: () => ({
    components: {
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
    },
    setup() {
      const value = ref<string[]>(['banana', 'mango']);
      return { value };
    },
    template: `
      <UiSelect v-model="value" :multiple="true">
        <UiSelectTrigger ariaLabel="Select option" class="w-[260px]">
          <UiSelectValue placeholder="Select fruits" />
        </UiSelectTrigger>
        <UiSelectContent>
          <UiSelectItem value="apple">Apple</UiSelectItem>
          <UiSelectItem value="banana">Banana</UiSelectItem>
          <UiSelectItem value="orange">Orange</UiSelectItem>
          <UiSelectItem value="grape">Grape</UiSelectItem>
          <UiSelectItem value="mango">Mango</UiSelectItem>
        </UiSelectContent>
      </UiSelect>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: multipleWithDefaultTemplateSource,
      },
    },
  },
};

/**
 * Select with a pre-selected default value.
 */
export const WithDefaultValue: Story = {
  render: () => ({
    components: {
      UiSelect,
      UiSelectTrigger,
      UiSelectContent,
      UiSelectItem,
      UiSelectValue,
    },
    setup() {
      const value = ref('banana');
      return { value };
    },
    template: `
      <UiSelect v-model="value">
        <UiSelectTrigger ariaLabel="Select option">
          <UiSelectValue placeholder="Select a fruit" />
        </UiSelectTrigger>
        <UiSelectContent>
          <UiSelectItem value="apple">Apple</UiSelectItem>
          <UiSelectItem value="banana">Banana</UiSelectItem>
          <UiSelectItem value="orange">Orange</UiSelectItem>
        </UiSelectContent>
      </UiSelect>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: withDefaultValueTemplateSource,
      },
    },
  },
};
