import React from 'react';

import Accordion from '../../shared/Accordion';
import FieldText from '../fields/Text';
import FieldTextArea from '../fields/Textarea';
import FieldRichText from '../fields/Richtext';
import FieldSelect from '../fields/Select';
import FieldFile from '../fields/File';
import FieldRepeater from '../fields/Repeater';

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

    this.state = props.fields;

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

  updateParentState() {
    this.props.onChange(this.state);
  }

  handleFieldChange(name, value) {
    this.setState({
      [name]: value
    }, this.updateParentState);
  }

  renderSection(name, section) {
    return (
      <Accordion title={section.title} desc={section.desc} key={name}>
        {this.renderFields(section.fields)}
      </Accordion>
    );
  }

  renderFields(fields) {
    return Object.entries(fields).map(([name, field]) => this.renderField(name, field));
  }

  renderField(name, field) {
    if ('repeater' === field.type) {
      return (
        <FieldRepeater entry={this.props.entry} title={field.label} name={name} key={name} desc={field.desc}>
          {this.renderFields(field.fields)}
        </FieldRepeater>
      );
    }

    const Component = this.getFieldComponent(field.type);

    return <Component value={this.getFieldValue(name)} title={field.label} name={name} key={name} desc={field.desc} onChange={this.handleFieldChange}/>
  }

  getFieldValue(name) {
    if (!this.state[name]) {
      return '';
    }

    return this.state[name];
  }

  getFieldComponent(type) {
    const map = {
      text: FieldText,
      textarea: FieldTextArea,
      richtext: FieldRichText,
      select: FieldSelect,
      file: FieldFile,
    };

    if (!map.hasOwnProperty(type)) {
      throw new Error(`Invalid field type: ${type}`);
    }

    return map[type];
  }

  render() {
    const layout = this.props.entryType.layouts[this.props.layout];
    if (!layout) {
      return null;
    }

    return (
      <React.Fragment>
        {Object.entries(layout.sections).map(([name, section]) => this.renderSection(name, section))}
      </React.Fragment>
    );
  }
}

export default Sections;
