import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { provideAnimations } from '@angular/platform-browser/animations';
import {
  applicationConfig,
  argsToTemplate,
  componentWrapperDecorator,
  Meta,
  moduleMetadata,
  StoryObj
} from '@storybook/angular';
import { ListItemComponent, MultiSelectComponent } from '../../public-api';

/**
 * `<nj-multi-select>` is compatible with `@angular/forms` and supports both `FormsModule` and `ReactiveFormsModule`.
 * It also extends `FormItem` so it can take all its props
 */
const meta: Meta<MultiSelectComponent> = {
  title: 'Components/Multi Select',
  id: 'multi-select',
  component: MultiSelectComponent,
  decorators: [
    applicationConfig({
      providers: provideAnimations()
    }),
    moduleMetadata({
      imports: [ListItemComponent, FormsModule, ReactiveFormsModule]
    }),
    componentWrapperDecorator(
      (story) => `
        <div style="height: 300px">${story}</div>
    `
    )
  ],
  argTypes: {
    hasCustomIcon: {
      control: {
        type: null
      }
    },
    iconClick: {
      control: {
        type: null
      }
    },
    iconKeydown: {
      control: {
        type: null
      }
    },
    wrapperClick: {
      control: {
        type: null
      }
    }
  },
  parameters: {
    docs: {
      imports: [MultiSelectComponent, ListItemComponent],
      controls: {
        exclude: new RegExp(/password\w*/)
      }
    }
  }
};

export default meta;

type MultiSelectWithLabelAndSubscript = MultiSelectComponent & {
  label: string;
  subscript: string;
};
type Story = StoryObj<MultiSelectWithLabelAndSubscript>;

export const MultiSelect: Story = {
  args: {
    label: 'Country',
    subscript: 'Hint to help the user fill the input',
    isFloatingLabel: true,
    inputId: 'inputId',
    listNavigationLabel: 'Use up and down arrows and Enter to select a value',
    buttonDefaultValueLabel: 'Select a country',
    fieldLabel: 'Country'
  },
  render: (args) => ({
    props: args,
    template: `
      <nj-multi-select ${argsToTemplate(args, { exclude: ['label', 'subscript'] })}>
        <ng-container njSelectOptions>
          <li nj-list-item value="af">Afghanistan</li>
          <li nj-list-item>Albania</li>
          <li nj-list-item>Algeria</li>
          <li nj-list-item>Andorra</li>
          <li nj-list-item>Angola</li>
          <li nj-list-item>Antigua and Barbuda</li>
          <li nj-list-item>Argentina</li>
          <li nj-list-item>Armenia</li>
          <li nj-list-item>Australia</li>
          <li nj-list-item>Austria</li>
          <li nj-list-item>Azerbaijan</li>
          <li nj-list-item>The Bahamas</li>
          <li nj-list-item>Bahrain</li>
          <li nj-list-item>Bangladesh</li>
          <li nj-list-item>Barbados</li>
          <li nj-list-item>Belarus</li>
          <li nj-list-item>Belgium</li>
          <li nj-list-item>Belize</li>
          <li nj-list-item>Benin</li>
          <li nj-list-item>Bhutan</li>
          <li nj-list-item>Bolivia</li>
          <li nj-list-item>Bosnia and Herzegovina</li>
          <li nj-list-item>Botswana</li>
          <li nj-list-item>Brazil</li>
          <li nj-list-item>Brunei</li>
          <li nj-list-item>Bulgaria</li>
          <li nj-list-item>Burkina Faso</li>
          <li nj-list-item>Burundi</li>
          <li nj-list-item>Cambodia</li>
          <li nj-list-item>Cameroon</li>
          <li nj-list-item>Canada</li>
          <li nj-list-item>Cape Verde</li>
          <li nj-list-item>Central African Republic</li>
          <li nj-list-item>Chad</li>
        </ng-container>
        <ng-container njFormLabel>{{label}}</ng-container>
        <ng-container njFormSubscript>{{subscript}}</ng-container>
      </nj-multi-select>
    `
  })
};

/**
 * `SliderComponent` implements `ControlValueAccessor` interface. It can be interfaced with `FormsModule` and `ReactiveFormsModule` APIs
 */
export const WithAngularFormsAPI: Story = {
  name: 'Use core Angular forms APIs',
  args: {
    label: 'Country',
    subscript: 'Hint to help the user fill the input',
    isFloatingLabel: true,
    inputId: 'inputId',
    listNavigationLabel: 'Use up and down arrows and Enter to select a value',
    buttonDefaultValueLabel: 'Select a country',
    fieldLabel: 'Country'
  },
  render: (args) => ({
    props: {
      ...args,
      value: null,
      multiSelectControl: new FormControl(),
      formControlState() {
        const { pristine, dirty, touched, untouched, value, status, errors } = this.multiSelectControl;
        return { pristine, dirty, touched, untouched, value, status, errors };
      }
    },
    template: `
    <h3>With ngModel - FormsModule</h3>
    <p>
      <nj-multi-select [(ngModel)]="value" ${argsToTemplate(args, { exclude: ['label', 'subscript'] })}>
        <ng-container njSelectOptions>
          <li nj-list-item value="af">Afghanistan</li>
          <li nj-list-item>Albania</li>
          <li nj-list-item>Austria</li>
          <li nj-list-item>Azerbaijan</li>
          <li nj-list-item>The Bahamas</li>
          <li nj-list-item>Bahrain</li>
          <li nj-list-item>Bolivia</li>
          <li nj-list-item>Bosnia and Herzegovina</li>
          <li nj-list-item>Botswana</li>
          <li nj-list-item>Cameroon</li>
          <li nj-list-item>Canada</li>
          <li nj-list-item>Chad</li>
        </ng-container>
        <ng-container njFormLabel>{{label}}</ng-container>
        <ng-container njFormSubscript>{{subscript}}</ng-container>
      </nj-multi-select>
    </p>
    <pre>Value: {{ value | json }}</pre>
    <hr>
    <h3>With FormControl - ReactiveFormsModule</h3>
    <p>
      <nj-multi-select [formControl]="multiSelectControl" ${argsToTemplate(args, { exclude: ['label', 'subscript'] })}>
        <ng-container njSelectOptions>
          <li nj-list-item value="af">Afghanistan</li>
          <li nj-list-item>Albania</li>
          <li nj-list-item>Algeria</li>
          <li nj-list-item>Belize</li>
          <li nj-list-item>Benin</li>
          <li nj-list-item>Bhutan</li>
          <li nj-list-item>Bolivia</li>
          <li nj-list-item>Bosnia and Herzegovina</li>
          <li nj-list-item>Botswana</li>
          <li nj-list-item>Brazil</li>
          <li nj-list-item>Chad</li>
        </ng-container>
        <ng-container njFormLabel>{{label}}</ng-container>
        <ng-container njFormSubscript>{{subscript}}</ng-container>
      </nj-multi-select>
    </p>
    <pre>Control: {{ formControlState() | json }}</pre>
    `
  })
};
