import React from 'react';

import { Redirect } from 'react-router-dom';

import Header from './form/Header';
import BaseFields from './form/Base';
import Sections from './form/Sections';
import { connect } from 'react-redux';

import { admin as adminApi } from '@devcms/sdk';

import { showError, showSuccess } from '../../../actions/notice';

class EntryForm extends React.Component {
  constructor(props) {
    super(props);

    const { match: { params: { type, id } } } = props;

    this.state = {
      loaded: !id,
      redirect: null,

      type: type,
      id: id,
      entryType: props.site.schema.entries[type],

      base: {
        title: '',
        slug: '',
        layout: 'default',
        status: 'draft',
        tags: []
      },
      fields: {}
    };

    this.handleBaseChange = this.handleBaseChange.bind(this);
    this.handleFieldsChange = this.handleFieldsChange.bind(this);
    this.handleDelete = this.handleDelete.bind(this);

    this.saveEntry = this.saveEntry.bind(this);
  }

  static getDerivedStateFromProps(props, state) {
    if (props.match.params.id !== state.id || props.match.params.type !== state.type) {
      return {
        entry: null,
        loaded: false,
        redirect: null,
        id: props.match.params.id,
        type: props.match.params.type,
      };
    }

    return null;
  }

  componentDidMount() {
    this.fetchEntry();
  }

  componentDidUpdate(prevProps, prevState) {
    if (this.state.loaded === false) {
      this.fetchEntry();
    }
  }

  fetchEntry() {
    if (!this.state.id) {
      return;
    }

    adminApi.entries.get(this.state.id).then((entry) => {
      this.setState({
        entry: entry,
        base: {
          title: entry.title,
          slug: entry.slug,
          layout: entry.layout,
          status: entry.status,
          tags: entry.tags || [],
        },
        fields: entry.fields,
        loaded: true
      });
    }).catch(error => this.props.showError(error.response.data.error));
  }

  handleBaseChange(base, cb) {
    this.setState({ base }, cb);
  }

  handleFieldsChange(fields, cb) {
    this.setState({ fields }, cb);
  }

  saveEntry() {
    this.state.entry ? this.update() : this.create();
  }

  handleDelete() {
    if (!this.state.entry) {
      return;
    }

    this.delete();
  }

  create() {
    adminApi.entries.create({
      type: this.state.type,
      title: this.state.base.title,
      slug: this.state.base.slug,
      layout: this.state.base.layout,
      tags: this.state.base.tags,
      status: this.state.base.status,
      fields: this.state.fields,
    }).then(entry => {
      this.setState({
        entry: entry,
        redirect: `/entries/${this.state.type}/${entry.id}`
      });

      this.props.showSuccess('Saved!');
    }).catch(error => this.props.showError('Unable to save. Make sure slug is unique.'));
  }

  update() {
    adminApi.entries.update(this.state.entry.id, {
      title: this.state.base.title,
      slug: this.state.base.slug,
      tags: this.state.base.tags,
      status: this.state.base.status,
      fields: this.state.fields,
    }).then(entry => {
      this.setState({ entry: entry });

      this.props.showSuccess('Saved!');
    }).catch(error => this.props.showError('Unable to save. Make sure slug is unique.'));
  }

  delete() {
    adminApi.entries.delete(this.state.entry.id).then(() => {
      this.setState({ redirect: `/entries/${this.state.type}` });
    }).catch(error => this.props.showError('Error occurred while deleting record.'));
  }

  render() {
    if (this.state.redirect) {
      return <Redirect to={this.state.redirect}/>
    }

    if (!this.state.loaded) {
      return null;
    }

    return (
      <div>
        <Header entryType={this.state.entryType} editing={!!this.state.entry} onDelete={this.handleDelete} saveEntry={this.saveEntry}/>
        <BaseFields entryType={this.state.entryType} base={this.state.base} editing={!!this.state.entry} onChange={this.handleBaseChange} saveEntry={this.saveEntry}/>
        <Sections entryType={this.state.entryType} layout={this.state.base.layout} fields={this.state.fields} onChange={this.handleFieldsChange}/>
      </div>
    );
  }
}

export default connect(
  (state) => ({
    site: state.site
  }),
  { showError, showSuccess}
)(EntryForm);
