import React, { Fragment } from 'react';
import { Page } from '../Page';
import { connect, DispatchProp } from 'react-redux';
import Board from '@lourenci/react-kanban';
import { fetchBoards } from '../../store/actions/boards';
import { createIssue } from '../../store/actions/issues';
import { buildKanboard, moveCard } from '../../store/actions/kanboards';
import { Loader } from '../Loader';
import { IssueCard } from './IssueCard';
import { Modal } from '../Modal';

export interface BoardPageProps extends DispatchProp {
  board: any
  kanboard: any
}
export class BoardPage extends React.Component<BoardPageProps> {

  state = {
    newCardModalActive: false,
    newCardLaneID: 0,
    newCard: {
      title: "",
      body: "",
      project: ""
    },
    compactMode: true,
  }

  onNewCardTitleChange: (evt: any) => void;
  onNewCardBodyChange: (evt: any) => void;
  onNewCardProjectChange: (evt: any) => void;

  constructor(props: BoardPageProps) {
    super(props);
    this.renderLaneHeader = this.renderLaneHeader.bind(this);
    this.onNewCardClick = this.onNewCardClick.bind(this);
    this.onNewCardCloseClick = this.onNewCardCloseClick.bind(this);
    this.onNewCardTitleChange = this.onNewCardAttrChange.bind(this, 'title');
    this.onNewCardBodyChange = this.onNewCardAttrChange.bind(this, 'body');
    this.onNewCardProjectChange = this.onNewCardAttrChange.bind(this, 'project');
    this.onNewCardSaveClick = this.onNewCardSaveClick.bind(this);
  }

  render() {
    const { board } = this.props;
    return (
      <Page title={`${board ? (board.title + ' - ') : ''}GenGitKan`}>
        <div className="container is-fluid">
          {this.renderBoard()}
        </div>
      </Page>
    );
  }

  renderBoard() {
    const { kanboard } = this.props;
    
    if (!kanboard) {
      return <Loader></Loader>
    }

    return (
      <Fragment>
        <div className="is-clearfix has-margin-top-normal">
          <div className="is-pulled-right">
            <div className="field">
              <input id="compactMode"
                checked={this.state.compactMode}
                onChange={this.onCompactModeChange.bind(this)}
                type="checkbox"
                className="switch is-rtl"
                name="compactMode"
                />
              <label htmlFor="compactMode">Mode compact</label>
            </div>
          </div>
        </div>
        <div className="kanboard-container is-fullheight">
          <Board disableLaneDrag={true}
            renderCard={this.renderCard.bind(this)}
            renderLaneHeader={this.renderLaneHeader}
            onCardDragEnd={this.onCardDragEnd.bind(this)}>
            {kanboard}
          </Board>
          { this.renderNewCardModal() }
        </div>
      </Fragment>
      
    );
  }

  renderNewCardModal() {
    const { newCardModalActive, newCardLaneID } = this.state;
    const { board } = this.props;
    if (!board || !newCardLaneID) return null;
    return (
      <Modal active={newCardModalActive}>
        <div className="new-card-modal">
          <article className="message">
            <div className="message-header">
              <p><span>"{board.lanes[newCardLaneID].title}" - Nouveau ticket</span></p>
              <button className="delete" aria-label="delete" onClick={this.onNewCardCloseClick}></button>
            </div>
            <div className="message-body">
              <div className="field">
                <div className="control">
                  <input className="input is-medium" type="text" 
                    placeholder="Titre de votre ticket..."
                    value={this.state.newCard.title} 
                    onChange={this.onNewCardTitleChange} />
                </div>
              </div>
              <div className="field">
                <div className="control">
                  <textarea className="textarea" 
                    placeholder="Description du nouveau ticket..."
                    value={this.state.newCard.body} 
                    onChange={this.onNewCardBodyChange}
                    rows={10}>
                  </textarea>
                </div>
              </div>
              <div className="field">
                <div className="control is-expanded">
                  <div className="select is-fullwidth">
                    <select
                      value={this.state.newCard.project} 
                      onChange={this.onNewCardProjectChange}>
                      {
                        board.projects.map((p: any, i: number) => {
                          return <option key={`new-card-project-${i}`} value={p}>{p}</option>
                        })
                      }
                    </select>
                  </div>
                </div>
              </div>
              <div className="field is-grouped is-grouped-right">
                <p className="control">
                  <a className="button is-light" 
                    onClick={this.onNewCardCloseClick}>
                    Annuler
                  </a>
                </p>
                <p className="control">
                  <a className="button is-primary"
                    onClick={this.onNewCardSaveClick}>
                    Enregistrer
                  </a>
                </p>
              </div>
            </div>
          </article>
        </div>
      </Modal>
    )
  }

  renderCard(card: any) {
    return <IssueCard compact={this.state.compactMode} card={card} />;
  }

  renderLaneHeader(lane: any) {
    return (
      <div className="kanboard-lane">
        <div className="level">
          <div className="level-left">
            <h3 className="level-item is-size-3">{lane.title}</h3>
          </div>
          <div className="level-right">
            <button className="button is-light level-item is-medium"
              onClick={this.onNewCardClick.bind(this, lane.id)}>
              <span className="icon">
                <i className="fas fa-plus" aria-hidden="true"></i>
              </span>
            </button>
          </div>
        </div>
      </div>      
    )
  }

  onCardDragEnd(source: any, dest: any) {
    const { board } = this.props;
    this.props.dispatch(moveCard(
      board.id,
      source.fromLaneId,
      source.fromPosition,
      dest.toLaneId,
      dest.toPosition
    ));
  }

  componentDidMount() {
    const { board } = this.props;
    if (!board) {
      this.requestBoardsUpdate();
      return
    }

    this.requestBuildKanboard();
  }

  onNewCardClick(laneID: string) {
    const { board } = this.props;
    this.setState({ 
      newCardModalActive: true, 
      newCardLaneID: laneID,
      newCard: {
        title: "",
        body: "",
        project: board.projects[0],
      }
    });
  }

  onNewCardCloseClick() {
    this.setState({ newCardModalActive: false });
  }

  onNewCardAttrChange(attrName: string, evt: React.ChangeEvent) {
    const value = (evt.target as HTMLInputElement).value;
    this.setState((state: any) => {
      return {
        ...state,
        newCard: {
          ...state.newCard,
          [attrName]: value,
        }
      }
    })
  }

  onNewCardSaveClick() {
    const { newCard, newCardLaneID } = this.state;
    const { board } = this.props;
    this.setState({ newCardModalActive: false });
    this.props.dispatch(createIssue(
      newCard.project, 
      newCard.title, 
      newCard.body, 
      board.lanes[newCardLaneID].issueLabel
    ));
  }

  componentDidUpdate(prevProps: any) {
    if (prevProps.board !== this.props.board) this.requestBuildKanboard();
  }

  requestBoardsUpdate() {
    this.props.dispatch(fetchBoards());
  }

  requestBuildKanboard() {
    const { board } = this.props;
    if (!board) return;
    this.props.dispatch(buildKanboard(board));
  }

  onCompactModeChange(evt: React.ChangeEvent) {
    const checked = (evt.currentTarget as HTMLInputElement).checked;
    this.setState(state => ({...state, compactMode: checked }));
  }

}

export const ConnectedBoardPage = connect(function(state: any, props: any) {
  const boardID = props.match.params.id;
  return {
    board: state.boards.byID[boardID],
    kanboard: state.kanboards.byID[boardID]
  };
})(BoardPage);