import type { Meta, StoryObj } from '@storybook/vue3-vite';
import MCombobox from './MCombobox.vue';
import { computed, ref } from 'vue';
import type { ListboxOption } from '../optionListbox/MOptionListbox.vue';
import MTag from '../tag/MTag.vue';
import MButton from '../button/MButton.vue';

const defaultOptions = Array.from({ length: 12 }).map((_el, index) => {
  return {
    label: `Option ${index + 1}`,
    value: `option${index + 1}`,
  };
});

let optionCount = 0;

const optionsWithSections: ListboxOption[] = Array.from({ length: 12 }).map(
  (_el, index) => {
    const isSection = index % 3 === 0;

    if (!isSection) {
      optionCount++;
    }

    return {
      label: `${isSection ? 'Section' : 'Option'} ${isSection ? index / 3 + 1 : optionCount}`,
      value: !isSection ? `option${optionCount}` : undefined,
      type: isSection ? 'section' : 'option',
    };
  },
);

const meta: Meta<typeof MCombobox> = {
  title: 'Form elements/Combobox',
  component: MCombobox,
  tags: ['v2'],
  parameters: {
    docs: {
      description: {
        component:
          'A combobox is an input field that allows users to select an option from a dropdown list or enter a custom value. It combines the functionality of a text input and a dropdown menu, providing flexibility and ease of use in forms and user interfaces.',
      },
      story: {
        height: '300px',
      },
    },
  },
  args: {
    open: false,
    modelValue: null,
    checkableSections: true,
    options: defaultOptions,
  },
  render: (args) => ({
    components: { MCombobox },
    setup() {
      const counterLabel = computed(
        () => `${(args.modelValue as Array<unknown>)?.length} selected`,
      );
      return { args, counterLabel };
    },
    template: `
      <MCombobox v-bind="args" v-model="args.modelValue" v-model:open="args.open" :counter-label="counterLabel"></MCombobox>
    `,
  }),
};
export default meta;
type Story = StoryObj<typeof MCombobox>;

export const Default: Story = {};

export const Multiple: Story = {
  args: {
    multiple: true,
    modelValue: [],
  },
};

export const SearchInput: Story = {
  args: {
    search: true,
    modelValue: [],
    multiple: true,
  },
};

export const ActionButtons: Story = {
  args: {
    modelValue: [],
    multiple: true,
    actions: true,
  },
};

export const WithSections: Story = {
  args: {
    options: optionsWithSections,
  },
};

export const SelectableSections: Story = {
  args: {
    modelValue: [],
    multiple: true,
    options: optionsWithSections,
    checkableSections: true,
  },
};

export const Clearable = {
  args: {
    clearable: true,
  },
};

export const Disabled: Story = {
  args: {
    disabled: true,
  },
};

export const Readonly: Story = {
  args: {
    readonly: true,
  },
};

export const Invalid: Story = {
  args: {
    invalid: true,
  },
};

export const AdditionalInformation: Story = {
  args: {
    options: defaultOptions.map((option) => ({
      ...option,
      content: 'Additional information',
    })),
  },
};

export const RemovableTags: Story = {
  args: {
    modelValue: [],
    options: defaultOptions,
    multiple: true,
  },
  render: (args) => ({
    components: { MCombobox, MTag, MButton },
    setup() {
      function findByValue(value: string | number) {
        return args.options.find((option) => option.value === value);
      }

      const open = ref(false);
      const maxResultsDisplayed = ref(9);
      const counterLabel = computed(
        () => `${(args.modelValue as Array<unknown>)?.length} selected`,
      );
      return { args, counterLabel, maxResultsDisplayed, findByValue, open };
    },
    template: `
      <MCombobox v-bind="args" v-model="args.modelValue" :counter-label="counterLabel" @update:open="open = $event"></MCombobox>

      <template
        v-if="!open"
      >
        <div style="width: 300px; display: flex;align-items: center;gap: 10px;flex-wrap: wrap;margin: 16px 0;">
          <MTag
            v-for="(item, index) in args.modelValue?.slice(0, maxResultsDisplayed)"
            :key="index"
            id="tag"
            :label="findByValue(item)?.label || ''"
            type="removable"
            size="s"
          />
        </div>

        <MButton
          v-if="args.modelValue?.length > maxResultsDisplayed"
          outlined
          size="s"
          @click="maxResultsDisplayed = args.modelValue?.length"
        >
          Show more
        </MButton>
      </template>
    `,
  }),
};
