import type { Meta, StoryObj } from '@storybook/vue3-vite';
import { UiRadioGroup, UiRadioGroupItem } from './index';
import { ref, watch } from 'vue';

/**
 * UiRadioGroup is a set of mutually exclusive options where exactly one can be selected.
 * Use it for short option lists in forms; for longer or searchable lists, prefer `UiSelect` or `UiListbox`.
 */
const meta: Meta<typeof UiRadioGroup> = {
  title: 'Components/UiRadioGroup',
  component: UiRadioGroup,
  tags: ['autodocs'],
  argTypes: {
    modelValue: {
      control: 'select',
      options: ['default', 'comfortable', 'compact'],
      description: 'The selected value',
    },
    disabled: {
      control: 'boolean',
      description: 'Disable the entire radio group',
    },
    orientation: {
      control: 'select',
      options: ['vertical', 'horizontal'],
      description: 'The orientation of the radio group',
    },
  },
  args: {
    name: 'radio-group',
    modelValue: 'comfortable',
    disabled: false,
    orientation: 'vertical',
  },
};

export default meta;

type Story = StoryObj<typeof UiRadioGroup>;

const defaultTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import { UiRadioGroup, UiRadioGroupItem } from '@aleph-alpha/ui-library'

const selected = ref('comfortable')
</script>

<template>
  <UiRadioGroup v-model="selected" name="spacing">
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r1" value="default" />
      <label for="r1" class="text-sm font-medium">Default</label>
    </div>
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r2" value="comfortable" />
      <label for="r2" class="text-sm font-medium">Comfortable</label>
    </div>
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r3" value="compact" />
      <label for="r3" class="text-sm font-medium">Compact</label>
    </div>
  </UiRadioGroup>
</template>`;

/**
 * Default radio group with three options.
 */
export const Default: Story = {
  render: (args) => ({
    components: { UiRadioGroup, UiRadioGroupItem },
    setup() {
      const selected = ref(args.modelValue);
      watch(
        () => args.modelValue,
        (val) => {
          selected.value = val;
        },
      );
      return { args, selected };
    },
    template: `
      <UiRadioGroup v-model="selected" name="spacing" :disabled="args.disabled" :orientation="args.orientation">
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r1" value="default" />
          <label for="r1" class="text-sm font-medium">Default</label>
        </div>
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r2" value="comfortable" />
          <label for="r2" class="text-sm font-medium">Comfortable</label>
        </div>
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r3" value="compact" />
          <label for="r3" class="text-sm font-medium">Compact</label>
        </div>
      </UiRadioGroup>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: defaultTemplateSource,
      },
    },
  },
};

const disabledTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import { UiRadioGroup, UiRadioGroupItem } from '@aleph-alpha/ui-library'

const selected = ref('default')
</script>

<template>
  <UiRadioGroup v-model="selected" name="spacing">
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r1" value="default" />
      <label for="r1" class="text-sm font-medium">Default</label>
    </div>
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r2" value="comfortable" disabled />
      <label for="r2" class="text-sm font-medium text-muted-foreground">Comfortable</label>
    </div>
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r3" value="compact" />
      <label for="r3" class="text-sm font-medium">Compact</label>
    </div>
  </UiRadioGroup>
</template>`;

/**
 * Radio group with a disabled item.
 */
export const Disabled: Story = {
  render: (args) => ({
    components: { UiRadioGroup, UiRadioGroupItem },
    setup() {
      const selected = ref('default');
      return { args, selected };
    },
    template: `
      <UiRadioGroup v-model="selected" name="spacing" :orientation="args.orientation">
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r1" value="default" />
          <label for="r1" class="text-sm font-medium">Default</label>
        </div>
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r2" value="comfortable" disabled />
          <label for="r2" class="text-sm font-medium text-muted-foreground">Comfortable</label>
        </div>
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r3" value="compact" />
          <label for="r3" class="text-sm font-medium">Compact</label>
        </div>
      </UiRadioGroup>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: disabledTemplateSource,
      },
    },
  },
};

const horizontalTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import { UiRadioGroup, UiRadioGroupItem } from '@aleph-alpha/ui-library'

const selected = ref('small')
</script>

<template>
  <UiRadioGroup v-model="selected" name="size" orientation="horizontal">
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r1" value="small" />
      <label for="r1" class="text-sm font-medium">Small</label>
    </div>
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r2" value="medium" />
      <label for="r2" class="text-sm font-medium">Medium</label>
    </div>
    <div class="flex items-center gap-x-2">
      <UiRadioGroupItem id="r3" value="large" />
      <label for="r3" class="text-sm font-medium">Large</label>
    </div>
  </UiRadioGroup>
</template>`;

/**
 * Radio group with horizontal orientation.
 * Items are laid out horizontally and can be navigated using Left/Right arrow keys.
 */
export const HorizontalOrientation: Story = {
  args: {
    orientation: 'horizontal',
    modelValue: 'small',
  },
  render: (args) => ({
    components: { UiRadioGroup, UiRadioGroupItem },
    setup() {
      const selected = ref(args.modelValue);
      watch(
        () => args.modelValue,
        (val) => {
          selected.value = val;
        },
      );
      return { args, selected };
    },
    template: `
      <UiRadioGroup v-model="selected" name="size" :orientation="args.orientation">
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r1" value="small" />
          <label for="r1" class="text-sm font-medium">Small</label>
        </div>
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r2" value="medium" />
          <label for="r2" class="text-sm font-medium">Medium</label>
        </div>
        <div class="flex items-center gap-x-2">
          <UiRadioGroupItem id="r3" value="large" />
          <label for="r3" class="text-sm font-medium">Large</label>
        </div>
      </UiRadioGroup>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: horizontalTemplateSource,
      },
    },
  },
};

const asChildTemplateSource = `<script setup lang="ts">
import { ref } from 'vue'
import { UiRadioGroup, UiRadioGroupItem } from '@aleph-alpha/ui-library'

const selected = ref('default')
</script>

<template>
  <UiRadioGroup v-model="selected" name="options" as-child>
    <fieldset class="rounded-lg border p-4">
      <legend class="px-2 text-sm font-medium">Select an option</legend>
      <div class="flex items-center gap-x-2">
        <UiRadioGroupItem id="r1" value="default" />
        <label for="r1" class="text-sm font-medium">Default</label>
      </div>
      <div class="flex items-center gap-x-2">
        <UiRadioGroupItem id="r2" value="second" />
        <label for="r2" class="text-sm font-medium">Second</label>
      </div>
    </fieldset>
  </UiRadioGroup>
</template>`;

/**
 * Radio group with as-child prop.
 * The radio group merges its props into the slotted element instead of wrapping it.
 */
export const AsChild: Story = {
  render: (args) => ({
    components: { UiRadioGroup, UiRadioGroupItem },
    setup() {
      const selected = ref('default');
      return { args, selected };
    },
    template: `
      <UiRadioGroup v-model="selected" name="options" as-child>
        <fieldset class="rounded-lg border p-4">
          <legend class="px-2 text-sm font-medium">Select an option</legend>
          <div class="flex items-center gap-x-2">
            <UiRadioGroupItem id="r1" value="default" />
            <label for="r1" class="text-sm font-medium">Default</label>
          </div>
          <div class="flex items-center gap-x-2">
            <UiRadioGroupItem id="r2" value="second" />
            <label for="r2" class="text-sm font-medium">Second</label>
          </div>
        </fieldset>
      </UiRadioGroup>
    `,
  }),
  parameters: {
    docs: {
      source: {
        code: asChildTemplateSource,
      },
    },
  },
};
