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, SelectComponent } from '../../public-api';

/**
 * `<nj-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<SelectComponent> = {
  title: 'Components/Select/Select',
  id: 'select',
  component: SelectComponent,
  decorators: [
    applicationConfig({
      providers: [provideAnimations()]
    }),
    moduleMetadata({
      imports: [SelectComponent, ListItemComponent, FormsModule, ReactiveFormsModule]
    }),
    componentWrapperDecorator(
      (story) => `
        <div style="height: 300px; display: flex; flex-direction: column; gap: 32px">${story}</div>
    `
    )
  ],
  parameters: {
    docs: {
      imports: [ListItemComponent, SelectComponent],
      controls: {
        exclude: new RegExp(/password\w*/)
      }
    }
  },
  argTypes: {
    hasCustomIcon: {
      control: {
        type: null
      }
    },
    iconClick: {
      control: {
        type: null
      }
    },
    iconKeydown: {
      control: {
        type: null
      }
    },
    wrapperClick: {
      control: {
        type: null
      }
    }
  }
};

export default meta;

type SelectLabelAndSubscript = SelectComponent & { label: string; subscript: string };
type Story = StoryObj<SelectLabelAndSubscript>;

export const Select: Story = {
  args: {
    label: 'Country',
    subscript: 'Hint to help the user fill the input',
    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-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-select>
    `
  })
};

export const SelectWithSelectedTemplate: Story = {
  args: {
    label: 'Country',
    subscript: 'Hint to help the user fill the input',
    inputId: 'inputId2',
    listNavigationLabel: 'Use up and down arrows and Enter to select a value',
    buttonDefaultValueLabel: 'Select a country',
    fieldLabel: 'Country'
  },
  render: (args) => ({
    props: args,
    template: `
      <nj-select ${argsToTemplate(args, { exclude: ['label', 'subscript'] })} [ngModel]="''" #model="ngModel">
        <ng-template njCustomLabelDef let-value let-index="index">
            Value: {{value}} - Index: {{index}}
        </ng-template>
        <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-select>
      <pre>Selected value: {{model.value|json}}</pre>
    `
  })
};

/**
 * `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',
    inputId: 'inputId2',
    listNavigationLabel: 'Use up and down arrows and Enter to select a value',
    buttonDefaultValueLabel: 'Select a country',
    fieldLabel: 'Country'
  },
  render: (args) => ({
    props: {
      ...args,
      value: null,
      selectControl: new FormControl(),
      formControlState() {
        const { pristine, dirty, touched, untouched, value, status, errors } = this.selectControl;
        return { pristine, dirty, touched, untouched, value, status, errors };
      }
    },
    template: `
    <h3>With ngModel - FormsModule</h3>
    <p>
      <nj-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>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>Botswana</li>
          <li nj-list-item>Brazil</li>
          <li nj-list-item>Brunei</li>
          <li nj-list-item>Bulgaria</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-select>
    </p>
    <pre>Value: {{ value | json }}</pre>
    <hr>
    <h3>With FormControl - ReactiveFormsModule</h3>
    <p>
      <nj-select [formControl]="selectControl" ${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>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>Brunei</li>
          <li nj-list-item>Bulgaria</li>
          <li nj-list-item>Burkina Faso</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-select>
    </p>
    <pre>Control: {{ formControlState() | json }}</pre>
    `
  })
};
