import {CompositeDisposable} from 'atom';

import URIPattern from './atom/uri-pattern';

class ItemWatcher {
  constructor(workspace, pattern, component, stateKey, opts) {
    this.workspace = workspace;
    this.pattern = pattern instanceof URIPattern ? pattern : new URIPattern(pattern);
    this.component = component;
    this.stateKey = stateKey;
    this.opts = opts;

    this.itemCount = this.readItemCount();
    this.activeCount = this.readActiveCount();
    this.subs = new CompositeDisposable();
  }

  getCurrentState() {
    if (this.opts.active) {
      return this.activeCount > 0;
    } else {
      return this.itemCount > 0;
    }
  }

  setInitialState() {
    if (!this.component.state) {
      this.component.state = {};
    }
    this.component.state[this.stateKey] = this.getCurrentState();
    return this;
  }

  subscribeToWorkspace() {
    this.subs.dispose();
    this.subs = new CompositeDisposable(
      this.workspace.onDidAddPaneItem(this.itemAdded),
      this.workspace.onDidDestroyPaneItem(this.itemDestroyed),
    );
    return this;
  }

  setPattern(pattern) {
    const wasTrue = this.itemCount > 0;

    this.pattern = pattern instanceof URIPattern ? pattern : new URIPattern(pattern);

    // Update the item count to match the new pattern
    this.itemCount = this.getItemCount();

    // Update the component's state if it's changed as a result
    if (wasTrue && this.itemCount <= 0) {
      return new Promise(resolve => this.component.setState({[this.stateKey]: false}, resolve));
    } else if (!wasTrue && this.itemCount > 0) {
      return new Promise(resolve => this.component.setState({[this.stateKey]: true}, resolve));
    } else {
      return Promise.resolve();
    }
  }

  itemMatches = item => item && item.getURI && this.pattern.matches(item.getURI()).ok()

  readItemCount() {
    return this.workspace.getPaneItems().filter(this.itemMatches).length;
  }

  readActiveCount() {
    return this.workspace.getPanes().filter(pane => this.itemMatches(pane.getActiveItem())).length;
  }

  itemAdded = ({item}) => {
    const hadOpen = this.itemCount > 0;
    if (this.itemMatches(item)) {
      this.itemCount++;

      if (this.itemCount > 0 && !hadOpen) {
        this.component.setState({[this.stateKey]: true});
      }
    }
  }

  itemDestroyed = ({item}) => {
    const hadOpen = this.itemCount > 0;
    if (this.itemMatches(item)) {
      this.itemCount--;

      if (this.itemCount <= 0 && hadOpen) {
        this.component.setState({[this.stateKey]: false});
      }
    }
  }

  dispose() {
    this.subs.dispose();
  }
}

export function watchWorkspaceItem(workspace, pattern, component, stateKey, options = {}) {
  const opts = {
    active: false,
    ...options,
  };

  return new ItemWatcher(workspace, pattern, component, stateKey, opts)
    .setInitialState()
    .subscribeToWorkspace();
}

@@ -155,22 +155,16 @@
 stateKey
-, opts
 ) %7B%0A    
@@ -342,30 +342,8 @@
 Key;
-%0A    this.opts = opts;
 %0A%0A  
@@ -366,20 +366,19 @@
  = this.
-read
+get
 ItemCoun
@@ -395,230 +395,41 @@
 his.
-activeCount = this.readActiveCount();%0A    this.subs = new CompositeDisposable();%0A  %7D%0A%0A  getCurrentState() %7B%0A    if (this.opts.active) %7B%0A      return this.activeCount %3E 0;%0A    %7D else %7B%0A      return this.itemCount %3E 0;%0A    %7D
+subs = new CompositeDisposable();
 %0A  %7D
@@ -575,25 +575,21 @@
 his.
-getCurrentState()
+itemCount %3E 0
 ;%0A  
@@ -1592,20 +1592,19 @@
 ok()%0A%0A  
-read
+get
 ItemCoun
@@ -1692,135 +1692,8 @@
  %7D%0A%0A
-  readActiveCount() %7B%0A    return this.workspace.getPanes().filter(pane =%3E this.itemMatches(pane.getActiveItem())).length;%0A  %7D%0A%0A
   it
@@ -2313,83 +2313,11 @@
 eKey
-, options = %7B%7D) %7B%0A  const opts = %7B%0A    active: false,%0A    ...options,%0A  %7D;%0A
+) %7B
 %0A  r
@@ -2381,14 +2381,8 @@
 eKey
-, opts
 )%0A  

Revert "Incomplete work to get {active: true} working"