import { action } from '@storybook/addon-actions';
import { Meta, StoryObj } from '@storybook/react';
import { Field } from 'formik';
import React from 'react';
import { MemoryRouter } from 'react-router';
import * as Yup from 'yup';
import { createGroups } from '../../../helpers/storybook';
import {
  CustomTagsField,
  DateTimeTextField,
  FileUpload,
  SelectField,
  SingleLineTextField,
  TagsField,
} from '../../FormElements';
import { FileUploadField } from '../../FormElements/FileUploadControl/FileUploadField';
import { ObjectSchemaDefinition } from '../FormStation.models';
import { Create } from './Create';

interface CreateValues {
  title?: string;
  genres?: string[];
  ratings?: string;
  shortDescription?: string;
  longDescription?: string;
  cast?: string[];
  released?: string;
}

interface APIResponse {
  status: string;
}

type CreateStoryType = typeof Create<CreateValues, APIResponse>;

interface FileUploadFormData {
  ingest?: FileUpload;
}

type CreateUploadStoryType = typeof Create<FileUploadFormData>;

const groups = createGroups({
  Content: [],
  Behavior: [],
  Styling: [],
});

const meta: Meta<CreateStoryType> = {
  title: 'Primary Components/Station Controls/FormStation/Create',
  component: Create,
  argTypes: {
    ...groups,
  },
  decorators: [
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
    (Story) => (
      <MemoryRouter>
        <Story />
      </MemoryRouter>
    ),
  ],
};
export default meta;

export const Default: StoryObj<CreateStoryType> = {
  args: {
    saveData: (...args: unknown[]): Promise<APIResponse> => {
      action('saveData')(args);
      return new Promise<APIResponse>((resolve) => {
        setTimeout(() => {
          resolve({ status: 'ok' });
        }, 500);
      });
    },
    children: (
      <>
        <Field name="title" label="Title" as={SingleLineTextField} />
        <Field
          name="genres"
          label="Genre(s)"
          tagsOptions={['Crime', 'Drama', 'Thriller']}
          as={TagsField}
        />
        <Field
          name="ratings"
          label="Age Rating"
          options={[
            { value: 'PG', label: 'Parental Guidance Suggested (PG)' },
            { value: 'PG-13', label: 'Parents Strongly Cautioned (PG-13)' },
            { value: 'R', label: 'Restricted (R)' },
          ]}
          as={SelectField}
        />
        <Field
          name="shortDescription"
          label="Short Description"
          placeholder="Enter a short description..."
          as={SingleLineTextField}
        />
        <Field
          name="longDescription"
          label="Long Description"
          placeholder="Enter a description..."
          as={SingleLineTextField}
        />
        <Field name="cast" label="Cast" as={CustomTagsField} />
        <Field
          name="password"
          label="Password"
          as={SingleLineTextField}
          type="password"
        />
        <Field
          name="released"
          label="Released"
          as={DateTimeTextField}
          modifyTime={false}
        />
      </>
    ),
    title: 'Create a Movie',
    subtitle: 'Movies',
    validationSchema: Yup.object<ObjectSchemaDefinition<CreateValues>>({
      title: Yup.string().required().max(25).label('Title'),
      genres: Yup.array<CreateValues>().of(Yup.string()).max(2).label('Genres'),
      shortDescription: Yup.string().required().label('Short Description'),
      cast: Yup.array<CreateValues>().of(Yup.string()).min(1).label('Cast'),
    }),
    initialData: {
      loading: false,
      data: {
        title: '',
        genres: [],
        ratings: '',
        shortDescription: '',
        longDescription: '',
        cast: [],
        released: '',
      },
    },
    cancelNavigationUrl: '/',
  },
};

export const FileUploadStation: StoryObj<CreateUploadStoryType> = {
  args: {
    title: 'Upload Ingest',
    validationSchema: Yup.object<ObjectSchemaDefinition<FileUploadFormData>>({
      ingest: Yup.mixed().required('File is a required field'),
    }),
    initialData: {
      loading: false,
    },
    cancelNavigationUrl: '/',
    saveData: async (formData): Promise<string> =>
      new Promise<string>((resolve) => {
        if (formData.ingest) {
          const { file, uploadStarted, uploadProgress, uploadCompleted } =
            formData.ingest;

          let progress = 0;
          uploadStarted();
          const interval = setInterval(() => {
            uploadProgress((progress / file.size) * 100);
            progress += 10000;

            if (progress >= file.size) {
              uploadCompleted();
              clearInterval(interval);
              resolve(file.name);
            }
          }, 1);
        }
      }),
    onProceed: ({ submitResponse }) => {
      if (!submitResponse) {
        return { title: `Select a file to continue` };
      }
      action('File Uploaded')(submitResponse);
    },
    children: <Field name="ingest" label="Document" as={FileUploadField} />,
  },
};
