import React from 'react';
import { Page } from '../Page';
import { connect } from 'react-redux';
import { selectFlagsIsLoading } from '../../store/selectors/flags';
import { fetchBoards, saveBoard, deleteBoard } from '../../store/actions/boards';
import { fetchProjects } from '../../store/actions/projects';
import uuidv4 from 'uuid/v4';
import { Loader } from '../Loader';

export class EditBoardPage extends React.Component {

  state = {
    edited: false,
    board: {
      id: "",
      title: "",
      description: "",
      projects: [],
      lanes: []
    },
  }

  static getDerivedStateFromProps(props, state) {
    const { board, isLoading } = props;

    if (isLoading || !board || state.edited) return state;

    return {
      edited: false,
      board: {
        id: board.id,
        title: board.title,
        description: board.description,
        projects: [ ...board.projects ],
        lanes: [ ...board.lanes.map(l => ({ ...l })) ]
      }
    };
  } 

  constructor(props) {
    super(props);
    this.onBoardTitleChange = this.onBoardAttrChange.bind(this, 'title');
    this.onBoardDescriptionChange = this.onBoardAttrChange.bind(this, 'description');
    this.onBoardLaneTitleChange = this.onBoardLaneAttrChange.bind(this, 'title');
    this.onBoardLaneIssueLabelChange = this.onBoardLaneAttrChange.bind(this, 'issueLabel');
    this.onDeleteBoardClick = this.onDeleteBoardClick.bind(this);
  }
  
  render() {
    const { isLoading } = this.props;
    const { board } = this.state;

    if (isLoading) {
      return (
        <Page>
          <Loader></Loader>
        </Page>
      )
    };
    
    return (
      <Page>
        <div className="container is-fluid has-margin-top-normal">
          <div className="columns">
            <div className="column is-6 is-offset-3">
              <div className="level is-mobile">
                <div className="level-left">
                  {
                    board.id ?
                    <h3 className="is-size-3 level-item">Éditer le tableau</h3> :
                    <h3 className="is-size-3 level-item">Nouveau tableau</h3>
                  }
                </div>
                <div className="level-right">
                  {
                    board.id ?
                    <button onClick={this.onDeleteBoardClick} className="level-item button is-danger">
                      <span className="icon">
                        <i className="fas fa-trash"></i>
                      </span>
                      <span>Supprimer</span>
                    </button> :
                    null
                  }
                </div>
              </div>
              <div className="field">
                <label className="label">Titre</label>
                <div className="control">
                  <input className="input" type="text" 
                    value={board.title} 
                    onChange={this.onBoardTitleChange} />
                </div>
              </div>
              <div className="field">
                <label className="label">Description</label>
                <div className="control">
                  <textarea className="textarea" 
                    value={board.description}
                    onChange={this.onBoardDescriptionChange}>  
                  </textarea>
                </div>
              </div>
              <hr />
              { this.renderProjectSelect() }
              <hr />
              { this.renderLanesSection() }
              <div className="field is-grouped is-grouped-right">
                <p className="control">
                  <a className="button is-light is-normal" href="#/">
                    Annuler
                  </a>
                </p>
                <p className="control">
                  <a className="button is-success is-normal"
                    onClick={this.onSaveBoardClick.bind(this)}>
                    Enregistrer
                  </a>
                </p>
              </div>
            </div>
          </div>
        </div>
      </Page>
    );
  }

  renderProjectSelect() {
    const { projects } = this.props;
    const { board } = this.state;

    const  projectSelectField = (projectIndex, value, withDeleteAddon) => {
      return (
        <div key={`project-${projectIndex}`} className="field has-addons">
          <div className="control is-expanded">
            <div className="select is-fullwidth">
              <select value={value} onChange={this.onBoardProjectChange.bind(this, projectIndex)}>
                <option value></option>
                {
                  projects.map(p => {
                    return <option key={`project-${p}`} value={p}>{p}</option>;
                  })
                }
              </select>
            </div>
          </div>
          { 
            withDeleteAddon ?
            <div className="control">
              <button type="submit" className="button is-danger"
                onClick={this.onBoardProjectDelete.bind(this, projectIndex)}>
                <span className="icon">
                  <i className="fas fa-trash"></i>
                </span>
              </button>
            </div> :
            null
          }
        </div>
      );
    }

    return (
      <React.Fragment>
        <label className="label">Projets</label>
        {
          board.projects.map((p, i) => {
            return projectSelectField(i, p, true);
          })
        }
        { projectSelectField(board.projects.length, '', false) }
      </React.Fragment>
    )
  }



  renderLanesSection() {

    const { board } = this.state;
 
    const laneSection = (laneIndex, lane) => {
      return (
        <React.Fragment key={`board-lane-${laneIndex}`}>
          <div className="columns">
            <div className="column is-10">
              <div className="field is-horizontal">
                <div className="field-label is-normal">
                  <label className="label">Titre</label>
                </div>
                <div className="field-body">
                  <div className="field">
                    <div className="control">
                      <input className="input" type="text" 
                        value={lane.title} 
                        onChange={this.onBoardLaneTitleChange.bind(this, laneIndex)} />
                    </div>
                  </div>
                </div>
              </div>
              <div className="field is-horizontal">
                <div className="field-label is-normal">
                  <label className="label">Label associé</label>
                </div>
                <div className="field-body">
                  <div className="field">
                    <div className="control">
                      <input className="input" type="text" 
                        value={lane.issueLabel}
                        onChange={this.onBoardLaneIssueLabelChange.bind(this, laneIndex)} />
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div className="column is-2 is-flex">
              <div className="buttons">
                <button className="button is-danger is-small"
                  onClick={this.onBoardLaneDelete.bind(this, laneIndex)}>
                  <span className="icon">
                    <i className="fas fa-trash"></i>
                  </span>
                </button>
                <button className="button is-primary is-small"
                  onClick={this.onBoardLaneMove.bind(this, laneIndex, -1)}>
                  <span className="icon">
                    <i className="fas fa-chevron-up"></i>
                  </span>
                </button>
                <button className="button is-primary is-small"
                  onClick={this.onBoardLaneMove.bind(this, laneIndex, 1)}>
                  <span className="icon">
                    <i className="fas fa-chevron-down"></i>
                  </span>
                </button>
              </div>
            </div>
          </div>
          <hr />
        </React.Fragment>
      );
    };

    const lanes = board.lanes.map((l, i) => laneSection(i, l))

    return (
      <React.Fragment>
        <div className="level">
          <div className="level-left">
            <label className="label level-item">Voies</label>
          </div>
          <div className="level-right">
            <div className="field is-grouped is-grouped-right level-item">
              <p className="control">
                <a className="button is-primary is-small"
                  onClick={this.onBoardLaneAdd.bind(this)}>
                  Ajouter une voie
                </a>
              </p>
            </div>
          </div>
        </div>
        { lanes }
      </React.Fragment>
    )
  }

  onBoardLaneAdd() {
    this.setState(state => {
      const lanes = [ 
        ...state.board.lanes, 
        { id: uuidv4(), title: "", issueLabel: "" }
      ];
      return {
        ...state,
        edited: true,
        board: {
          ...state.board,
          lanes
        }
      }
    });
  }

  onBoardProjectDelete(projectIndex) {
    this.setState(state => {
      const projects = [ ...state.board.projects ]
      projects.splice(projectIndex, 1); 
      return {
        ...state,
        edited: true,
        board: {
          ...state.board,
          projects
        }
      }
    });
  }

  onBoardLaneMove(laneIndex, direction) {
    this.setState(state => {
      const lanes = [ ...state.board.lanes ];

      const nextLaneIndex = laneIndex+direction;
      if (nextLaneIndex < 0 || nextLaneIndex >= lanes.length) {
        return state;
      }

      const l = lanes[laneIndex];
      lanes.splice(laneIndex, 1);
      lanes.splice(nextLaneIndex, 0, l);

      return {
        ...state,
        edited: true,
        board: {
          ...state.board,
          lanes
        }
      }
    });
  }

  onBoardLaneDelete(laneIndex) {
    this.setState(state => {
      const lanes = [ ...state.board.lanes ]
      lanes.splice(laneIndex, 1); 
      return {
        ...state,
        edited: true,
        board: {
          ...state.board,
          lanes
        }
      }
    });
  }

  onBoardProjectChange(projectIndex, evt) {
    const value = evt.target.value;
    this.setState(state => {
      const projects = [ ...state.board.projects ]; 
      projects[projectIndex] = value;
      return {
        ...state,
        edited: true,
        board: {
          ...state.board,
          projects
        }
      }
    });
  }

  onBoardAttrChange(attrName, evt) {
    const value = evt.target.value;
    this.setState(state => {
      return {
        ...state,
        edited: true,
        board: {
          ...state.board,
          [attrName]: value,
        }
      }
    });
  }

  onBoardLaneAttrChange(attrName, laneIndex, evt) {
    const value = evt.target.value;
    this.setState(state => {
      const lanes = [ ...state.board.lanes ];
      lanes[laneIndex] = {
        ...state.board.lanes[laneIndex],
        [attrName]: value
      };
      return {
        ...state,
        edited: true,
        board: {
          ...state.board,
          lanes
        }
      }
    });
  }

  onSaveBoardClick() {
    let { board } = this.state;
    board = { ...board };
    if (!board.id) board.id = uuidv4();
    this.props.dispatch(saveBoard({...board}));
    this.props.history.push('/');
  }

  onDeleteBoardClick() {
    const { board } = this.state;
    this.props.dispatch(deleteBoard(board.id));
    this.props.history.push('/');
  }

  componentDidMount() {
    this.props.dispatch(fetchBoards());
    this.props.dispatch(fetchProjects());
  }

}

export const ConnectedEditBoardPage = connect(function(state, props) {
  const boardID = props.match.params.id;
  const board = boardID ? state.boards.byID[boardID] : null;

  const projects = Object.keys(state.projects.byName).sort();

  const isLoading = selectFlagsIsLoading(state, 'FETCH_BOARDS', 'FETCH_PROJECTS');

  return { board, isLoading, projects };
})(EditBoardPage);