import React, { useState } from "react";

import { Search } from "neetoicons";
import { pluck, prop } from "ramda";
import * as yup from "yup";

import Button from "components/Button";
import MultiEmailInput from "components/MultiEmailInput";
import Typography from "components/Typography";
import {
  MultiEmailInput as FormikMultiEmailInput,
  Form,
} from "formikcomponents";

import { EMAILS } from "./constants";

import { suffixes, prefixes } from "../constants";

import MultiEmailInputCounterDocs from "!raw-loader!./MultiEmailInputStoriesDocs/MultiEmailInputCounterDocs.mdx";
import MultiEmailInputCSSCustomization from "!raw-loader!./MultiEmailInputStoriesDocs/MultiEmailInputCSSCustomization.mdx";
import MultiEmailInputDocs from "!raw-loader!./MultiEmailInputStoriesDocs/MultiEmailInputDocs.mdx";

const metadata = {
  title: "Components/MultiEmailInput",
  component: MultiEmailInput,
  parameters: {
    layout: "padded",
    docs: { description: { component: MultiEmailInputDocs } },
    design: {
      type: "figma",
      url: "https://www.figma.com/file/zhdsnPzXzr264x1WUeVdmA/02-Components?node-id=926%3A2379",
    },
  },
  argTypes: {
    prefix: { options: Object.keys(prefixes), mapping: prefixes },
    suffix: { options: Object.keys(suffixes), mapping: suffixes },
    onChange: {
      table: {
        type: { summary: "func" },
        defaultValue: { summary: "(event) => void" },
      },
    },
    onBlur: {
      table: {
        type: { summary: "func" },
        defaultValue: { summary: "(event) => void" },
      },
    },
  },
};

const Controlled = args => {
  const [emails, setEmails] = useState(args.value);

  return (
    <MultiEmailInput
      {...args}
      options={EMAILS}
      value={emails}
      onChange={emails => setEmails(emails)}
    />
  );
};

Controlled.args = { value: [EMAILS[0]] };

const Error = args => <MultiEmailInput {...args} />;

Error.args = {
  error: "Please make sure all emails are valid.",
  value: [{ label: "test", value: "test", valid: false }],
};

const Disabled = _args => <MultiEmailInput disabled />;

const HelpText = _args => (
  <MultiEmailInput helpText="This is the help text for this component." />
);
HelpText.storyName = "Help text";

const Counter = _args => {
  const [emails, setEmails] = useState(EMAILS.slice(0, 3));

  return (
    <MultiEmailInput
      counter={{ startsFrom: 3 }}
      value={emails}
      onChange={emails => setEmails(emails)}
    />
  );
};

Counter.parameters = {
  docs: { description: { story: MultiEmailInputCounterDocs } },
};

const WithPrefixAndSuffix = args => {
  const [emails, setEmails] = useState(args.value);

  return (
    <MultiEmailInput
      {...args}
      prefix={<Search />}
      suffix={<div className="neeto-ui-text-gray-700">.bigbinary.com</div>}
      value={emails}
      onChange={emails => setEmails(emails)}
    />
  );
};

WithPrefixAndSuffix.args = { value: [EMAILS[0]] };
WithPrefixAndSuffix.storyName = "With prefix and suffix";

const AlwaysExpandedInput = args => {
  const [emails, setEmails] = useState(args.value);

  return (
    <MultiEmailInput
      {...args}
      value={emails}
      onChange={emails => setEmails(emails)}
    />
  );
};

AlwaysExpandedInput.args = { value: EMAILS, isAlwaysExpanded: true };
AlwaysExpandedInput.storyName = "Always expanded input";

const FormikEmail = _args => {
  const [emails, setEmails] = useState([]);

  const INITIAL_VALUES = { emails: [] };
  const VALIDATION_SCHEMA = yup.object().shape({
    emails: yup
      .array()
      .min(1, "Please enter atleast one email.")
      .test(
        "are-all-emails-valid",
        "Please make sure all emails are valid.",
        emails => emails.every(prop("valid"))
      )
      .nullable(),
  });

  const handleSubmit = ({ emails }) => setEmails(pluck("value", emails));

  return (
    <Form
      formProps={{ className: "space-y-2" }}
      formikProps={{
        initialValues: INITIAL_VALUES,
        validationSchema: VALIDATION_SCHEMA,
        onSubmit: handleSubmit,
      }}
    >
      <FormikMultiEmailInput
        counter
        filterInvalidEmails
        required
        label="Email(s)"
        name="emails"
      />
      <Button
        data-cy="add-member-submit-button"
        label="Save changes"
        style="primary"
        type="submit"
      />
      <Typography style="body1">Emails: {JSON.stringify(emails)}</Typography>
    </Form>
  );
};

FormikEmail.storyName = "Formik email";

const CSSCustomization = args => {
  const [emails, setEmails] = useState(args.value);

  return (
    <div className="neetix-email-input">
      <MultiEmailInput
        {...args}
        counter
        options={EMAILS}
        value={emails}
        onChange={emails => setEmails(emails)}
      />
    </div>
  );
};

CSSCustomization.storyName = "MultiEmailInput CSS Customization";

CSSCustomization.args = { value: [EMAILS[0]] };

CSSCustomization.parameters = {
  docs: { description: { story: MultiEmailInputCSSCustomization } },
};

export {
  Controlled,
  Error,
  Disabled,
  HelpText,
  Counter,
  WithPrefixAndSuffix,
  AlwaysExpandedInput,
  FormikEmail,
  CSSCustomization,
};

export default metadata;
