/** @jsx etch.dom */
/* eslint react/no-unknown-property: "off" */

import path from 'path';

import etch from 'etch';
import {autobind} from 'core-decorators';
import {CompositeDisposable} from 'event-kit';

import CommitView from '../views/commit-view';
import ModelStateRegistry from '../models/model-state-registry';
import {readFile} from '../helpers';

export const COMMIT_GRAMMAR_SCOPE = 'text.git-commit';

export default class CommitViewController {
  static focus = {
    ...CommitView.focus,
  }

  constructor(props) {
    this.props = props;
    this.deactivateCommitBox = false;

    this.repoStateRegistry = new ModelStateRegistry(CommitViewController, {
      initialModel: props.repository,
      save: () => {
        return {
          regularCommitMessage: this.regularCommitMessage,
          amendingCommitMessage: this.amendingCommitMessage,
        };
      },
      restore: (state = {}) => {
        this.regularCommitMessage = state.regularCommitMessage || '';
        this.amendingCommitMessage = state.amendingCommitMessage || '';
      },
    });

    if (this.props.isMerging && this.props.mergeMessage) {
      this.regularCommitMessage = this.props.mergeMessage;
    }

    this.subscriptions = new CompositeDisposable();
    etch.initialize(this);
  }

  update(props) {
    const wasAmending = this.props.isAmending;
    const wasMerging = this.props.isMerging;
    this.props = {...this.props, ...props};
    this.repoStateRegistry.setModel(this.props.repository);
    // If we just checked the "amend" box and we don't yet have a saved amending message,
    // initialize it to be the message from the last commit.
    if (!wasAmending && this.props.isAmending && !this.amendingCommitMessage && this.props.lastCommit.isPresent()) {
      this.amendingCommitMessage = props.lastCommit.getMessage();
    } else if (!wasMerging && this.props.isMerging && !this.regularCommitMessage) {
      this.regularCommitMessage = this.props.mergeMessage || '';
    }
    return etch.update(this);
  }

  render() {
    const message = this.getCommitMessage();

    return (
      <CommitView
        ref="commitView"
        stagedChangesExist={this.props.stagedChangesExist}
        mergeConflictsExist={this.props.mergeConflictsExist}
        prepareToCommit={this.props.prepareToCommit}
        commit={this.commit}
        setAmending={this.props.setAmending}
        abortMerge={this.props.abortMerge}
        branchName={this.props.branchName}
        commandRegistry={this.props.commandRegistry}
        maximumCharacterLimit={72}
        message={message}
        isMerging={this.props.isMerging}
        isAmending={this.props.isAmending}
        lastCommit={this.props.lastCommit}
        onChangeMessage={this.handleMessageChange}
        didMoveUpOnFirstLine={this.props.didMoveUpOnFirstLine}
        openCommitEditor={this.openCommitEditor}
        deactivateCommitBox={this.deactivateCommitBox}
      />
    );
  }

  @autobind
  async commit(message) {
    try {
      await this.props.commit(message);
      this.regularCommitMessage = '';
      this.amendingCommitMessage = '';
      etch.update(this);
    } catch (e) {
      this.props.notificationManager.addError('Unable to commit', {
        dismissable: true,
        description: `<pre>${e.stdErr || e.stack}</pre>`,
      });
    }
  }

  getCommitMessage() {
    const message = this.props.isAmending ? this.amendingCommitMessage : this.regularCommitMessage;
    return message || '';
  }

  @autobind
  handleMessageChange(newMessage) {
    if (this.props.isAmending) {
      this.amendingCommitMessage = newMessage;
    } else {
      this.regularCommitMessage = newMessage;
    }
    etch.update(this);
  }

  activateCommitEditor() {
    const panes = this.props.workspace.getPanes();
    const paneWithEditor = panes.find(pane => {
      const editor = pane.getItems().find(item => item === this.editor);
      return !!editor;
    });
    paneWithEditor.activate();
    paneWithEditor.activateItem(this.editor);
  }

  @autobind
  async openCommitEditor(messageFromBox) {
    if (this.editor) {
      this.activateCommitEditor();
      return;
    }

    const atomCommitMessagePath = path.join(this.props.repository.getGitDirectoryPath(), 'ATOM_COMMIT_EDITMSG');
    this.editor = await this.props.workspace.open(atomCommitMessagePath);
    this.editor.setText(messageFromBox);
    this.deactivateCommitBox = true;

    const grammar = this.props.grammars.grammarForScopeName(COMMIT_GRAMMAR_SCOPE);
    if (grammar) {
      this.editor.setGrammar(grammar);
    } else {
      this.grammarSubscription = this.props.grammars.onDidAddGrammar(this.grammarAdded);
      this.subscriptions.add(this.grammarSubscription);
    }
    etch.update(this);

    this.editorSubscription = this.editor.onDidDestroy(async () => {
      this.editor = null;
      const contents = await readFile(atomCommitMessagePath);
      this.regularCommitMessage = contents;
      this.deactivateCommitBox = false;
      this.editorSubscription.dispose();
      etch.update(this);
    });
    this.subscriptions.add(this.editorSubscription);
  }

  @autobind
  grammarAdded(grammar) {
    if (grammar.scopeName !== COMMIT_GRAMMAR_SCOPE) { return; }

    this.editor.setGrammar(grammar);
    this.grammarSubscription.dispose();
  }

  rememberFocus(event) {
    return this.refs.commitView.rememberFocus(event);
  }

  setFocus(focus) {
    return this.refs.commitView.setFocus(focus);
  }

  hasFocus() {
    return this.element.contains(document.activeElement);
  }

  destroy() {
    this.subscriptions.dispose();
    this.repoStateRegistry.save();
    return etch.destroy(this);
  }
}

@@ -551,46 +551,8 @@
 ops;
-%0A    this.deactivateCommitBox = false;
 %0A%0A  
@@ -2865,32 +2865,27 @@
 ox=%7B
+!!
 this.
-deactivateCommitBox
+commitEditor
 %7D%0A  
@@ -3846,25 +3846,31 @@
 em === this.
-e
+commitE
 ditor);%0A    
@@ -3960,25 +3960,31 @@
 teItem(this.
-e
+commitE
 ditor);%0A  %7D%0A
@@ -4048,25 +4048,31 @@
    if (this.
-e
+commitE
 ditor) %7B%0A   
@@ -4238,33 +4238,39 @@
 MSG');%0A    this.
-e
+commitE
 ditor = await th
@@ -4318,33 +4318,39 @@
 Path);%0A    this.
-e
+commitE
 ditor.setText(me
@@ -4367,45 +4367,8 @@
 ox);
-%0A    this.deactivateCommitBox = true;
 %0A%0A  
@@ -4470,33 +4470,39 @@
 r) %7B%0A      this.
-e
+commitE
 ditor.setGrammar
@@ -4731,25 +4731,31 @@
 tion = this.
-e
+commitE
 ditor.onDidD
@@ -4782,25 +4782,31 @@
 %0A      this.
-e
+commitE
 ditor = null
@@ -4917,48 +4917,8 @@
 ts;%0A
-      this.deactivateCommitBox = false;%0A
     
@@ -5153,25 +5153,31 @@
 %7D%0A%0A    this.
-e
+commitE
 ditor.setGra

remove unnecessary flag `this.deactivateCommitBox`