/* eslint-disable react/no-unused-prop-types */
/* eslint-disable react/static-property-placement */
import React from 'react';
import axios from 'axios';
import { Typography, CircularProgress } from '@mui/material';

import { mergeProps } from '../Util';
import { warn as deprecatedWarn } from '../Util/deprecate';
import Button from '../Button';
import { styled } from '../Theme';

export function submitContactForm(
  { formId, portalId }: { formId: string; portalId: string },
  fields: Record<string, string>,
  context: Record<string, string>
) {
  const url = `https://api.hsforms.com/submissions/v3/integration/submit/${portalId}/${formId}`;
  return axios
    .post(url, {
      submittedAt: Date.now(),
      fields: Object.keys(fields).map((x) => ({
        name: x.replace(/\s+/, '').toLowerCase(),
        value: fields[x],
      })),
      context,
      skipValidation: false,
    })
    .then((res) => res.data.inlineMessage)
    .catch((res) => (res.data ? res.data.message : 'Form Submit Failed'));
}

export interface ContactFormProps extends React.HTMLAttributes<HTMLFormElement> {
  className?: string;
  portalId?: string;
  formId?: string;
  title?: string;
  button?: string;
  successMessage?: string;
  layout?: 'horizontal' | 'vertical';
  fields?: string | string[];
}

export default class ContactForm extends React.Component<
  ContactFormProps,
  {
    loading: boolean;
    errorMessage: string;
    successMessage: string;
    [x: string]: string | boolean;
  }
> {
  static defaultProps = {
    className: '',
    portalId: '4796488',
    formId: '929a510f-34f4-4251-98b3-34175200aebd',
    title: undefined,
    button: '',
    layout: 'vertical' as const,
    successMessage: 'Form Submit Success',
    fields: ['Email', 'First Name', 'Last Name'],
  };

  fields: string[];

  constructor(props: ContactFormProps) {
    super(props);

    if (typeof props.fields === 'string') {
      this.fields = props.fields.split(',').map((x) => x.trim());
    } else {
      this.fields = props.fields!;
    }

    this.state = {
      loading: false,
      errorMessage: '',
      successMessage: '',
    };

    this.fields.forEach((x) => {
      // @ts-ignore
      this.state[x] = '';
    });
    deprecatedWarn('ContactForm');
  }

  deriveProps() {
    const newProps = mergeProps(this.props, ContactForm);

    if (typeof newProps.title === 'undefined') {
      newProps.title = 'Signup for our news letter';
    }
    if (!newProps.button) {
      newProps.button = 'Subscribe';
    }

    return newProps;
  }

  render() {
    const { className, style, title, button, layout } = this.deriveProps();
    const { loading, errorMessage, successMessage } = this.state;
    return (
      <Form
        onSubmit={this.onSubmit}
        className={className}
        style={style}
        layout={layout}
        fieldCount={this.fields.length}
        name="subscribe">
        {!!title && (
          <Typography component="p" className="title">
            {title}
          </Typography>
        )}
        <div className="form-controls">
          {this.fields.map((x) => (
            <input
              required
              key={x}
              type="text"
              value={this.state[x] as string}
              onChange={this.getInputHandler(x)}
              className="input"
              placeholder={x}
            />
          ))}
          <Button
            variant="outlined"
            type="submit"
            color="inherit"
            size="large"
            disabled={loading}
            className="subscribe-btn-empty">
            {loading ? <CircularProgress size={28} /> : button}
          </Button>
        </div>
        {!!errorMessage && (
          <Typography
            component="p"
            variant="body1"
            className="error"
            color="secondary"
            dangerouslySetInnerHTML={{ __html: errorMessage }}
          />
        )}
        {!!successMessage && (
          <Typography
            component="p"
            variant="body1"
            className="success"
            color="primary"
            dangerouslySetInnerHTML={{ __html: successMessage }}
          />
        )}
      </Form>
    );
  }

  onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    this.setState({ loading: true });

    try {
      const message = await submitContactForm(
        { formId: this.props.formId!, portalId: this.props.portalId! },
        this.fields.reduce<Record<string, string>>((obj, x) => {
          obj[x] = this.state[x] as string;
          return obj;
        }, {}),
        {
          pageUri: window.location.href,
          pageName: document.title,
        }
      );

      this.setState({
        loading: false,
        successMessage: message || this.props.successMessage,
      });
    } catch (err) {
      this.setState({
        loading: false,
        errorMessage: err ? (err as Error).message : 'Form submit failed',
      });
    }
  };

  getInputHandler =
    (name: string, state = {}) =>
    (e: React.ChangeEvent<HTMLInputElement>) => {
      this.setState(
        Object.assign(state, {
          [name]: e.target.value,
        })
      );
    };
}

interface FormProps {
  layout: 'vertical' | 'horizontal';
  fieldCount: number;
}

// prettier-ignore
const getInputWidth = (props: FormProps) => (props.layout === 'vertical' ? '100%' : `${Math.max(95 / (props.fieldCount + 1), 20)}%`);

const Form = styled('form', {
  shouldForwardProp: (prop) => prop !== 'layout' && prop !== 'fieldCount',
})<FormProps>`
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  @media (max-width: ${(props) => props.theme.breakpoints.values.sm}px) {
    width: 100% !important;
  }
  max-width: 800px;
  margin: 0px auto;

  .title {
    font-size: 30px;
    text-align: center;
    color: ${(props) => {
      return props.theme.typography.color.main;
    }};
  }

  .form-controls {
    width: 100%;
    flex-direction: ${(props) => (props.layout === 'vertical' ? 'column' : 'row')};
    justify-content: space-between;
    align-items: center;

    .input {
      width: ${(props) => getInputWidth(props)};
      height: 50px;
      border: none;
      border-bottom: 1px solid
        ${(props) => {
          return props.theme.typography.color.main;
        }};
      font-size: 16px;
      letter-spacing: 1.8px;
      outline: none;
      margin: ${(props) => (props.layout === 'vertical' ? '12px 0' : '12px')};
      background: transparent;

      &:first-of-type {
        margin-top: 40px;
      }
    }

    .subscribe-btn-empty {
      margin-top: ${(props) => (props.layout === 'vertical' ? '40px' : '0')};
      width: ${(props) => (props.layout === 'vertical' ? '100%' : 'auto')};
    }
  }

  .error,
  .success {
    margin-top: 20px;
  }
`;
