import { any } from 'bluebird';

export interface ITask {
  ref: string;
  range: string;
  tasks: ITaskActionSet[];
  parse(data: any): void;
  [key: string]: any;
}

export interface ITaskActionSet {
  condition: string;
  actions: ITaskActionSetAction[];
  [key: string]: any;
  parse(data: any): void;
}

export enum IActionType {
  VALUE = 'value',
  NOTIFICATION = 'notification',
  SHARE = 'share',
  // JAVASCRIPT = 'javascript',
  COMPONENT = 'component',
}

export interface ITaskActionSetAction {
  type: IActionType;
  offset: string;
  cell: string;
  share: ITaskActionSetActionShare;
  notification: ITaskActionSetActionNotification;
  data: ITaskActionSetActionData;
  // javascript: IActionsTaskActionSetActionJavascript;
  component: ITaskActionSetActionShareComponent;
  [key: string]: any;
  parse(data: any): void;
}

export interface ITaskActionSetActionShare {
  title: string;
  subTitle: string;
  blurb: string;
  icon: string;
  [key: string]: any;
  parse(data: any): void;
}

export interface ITaskActionSetActionShareComponent {
  name: string;
  type: string;
  data: string;
  [key: string]: any;
  parse(data: any): void;
}

export enum INotificationType {
  CARD = 'card',
  TEXT = 'text'
}

export interface ITaskActionSetActionNotification {
  type: INotificationType;
  message: string;
  body: string;
  conversation_id: string;
  table?: any;
  [key: string]: any;
  parse(data: any): void;
}

export interface ITaskActionSetActionData {
  value: string;
  formatted_value: string;
  reset_value?: string;
  reset_time?: string;
  [key: string]: any;
  parse(data: any): void;
}

export interface ITaskActionSetActionJavascript {
  code: string;
}

export class Task implements ITask {
  public ref: string = '';
  public range: string = '';
  public tasks: ITaskActionSet[] = [];
  constructor(data?: any) {
    this.parse(data || {});
  }
  public parse(data: any): void {
    ['ref', 'range', 'tasks'].forEach(key => {
      if (data[key] === undefined) return;
      if (key === 'tasks') {
        this.tasks = [];
        data[key].forEach((taskSetData: any) => {
          this.tasks.push(new TaskActions(taskSetData));
        });
      } else {
        (<ITask>this)[key] = data[key];
      }
    });
  }
}
export class TaskActions implements ITaskActionSet {
  public name: string = '';
  public condition: string = '';
  public actions: ITaskActionSetAction[] = [];
  constructor(data?: any) {
    this.parse(data || {});
  }
  public parse(data: any): void {
    ['name', 'condition', 'actions'].forEach(key => {
      if (data[key] === undefined) return;
      if (key === 'actions') {
        this.actions = [];
        data[key].forEach((actionData: any) => {
          let actionSet = new TaskAction();
          actionSet.parse(actionData);
          this.actions.push(actionSet);
        });
      } else {
        (<ITaskActionSet>this)[key] = data[key];
      }
    });
  }
}

export class TaskAction implements ITaskActionSetAction {
  public static TYPES: string[] = ['share', 'notification', 'data', 'component'];
  public type: IActionType = IActionType.VALUE;
  public offset: string = '';
  public cell: string = '';
  public share!: ITaskActionSetActionShare;
  public notification!: ITaskActionSetActionNotification;
  public data!: ITaskActionSetActionData;
  // private _javascript!: IActionsTaskActionSetActionJavascript;
  public component!: ITaskActionSetActionShareComponent;
  constructor(data?: any) {
    this.parse(data || {});
  }
  public parse(data: any): void {
    ['type', 'offset', 'cell'].forEach(key => {
      if (data[key] === undefined) return;
      (<ITaskActionSetAction>this)[key] = data[key];
    });
    TaskAction.TYPES.forEach(key => {
      if (key === 'share') {
        this.share = new ShareTaskAction(data[key]);;
      } else if (key === 'notification') {
        this.notification = new NotificationTaskAction(data[key]);
      } else if (key === 'data') {
        this.data = new DataTaskAction(data[key]);
      } else if (key === 'component') {
        this.component = new ComponentTaskAction(data[key]);
      } else {
        if (data[key] === undefined) return;
        (<ITaskActionSetAction>this)[key] = data[key];
      }
    });
  }
  // public get share(): ShareTaskAction {
  //   return this._share;
  // }
  // public get notification(): ITaskActionSetActionNotification {
  //   return this._notification;
  // }
  // public get data(): DataTaskAction {
  //   return this._data;
  // }
  // public get component(): ITaskActionSetActionShareComponent {
  //   return this._component;
  // }
}

export class ShareTaskAction implements ITaskActionSetActionShare {
  public title: string = '';
  public subTitle: string = '';
  public blurb: string = '';
  public icon: string = '';
  constructor(data?: any) {
    this.parse(data || {});
  }
  public parse(data: any): void {
    ['title', 'subTitle', 'blurb', 'icon'].forEach(key => {
      if (data[key] === undefined) return;
      (<ITaskActionSetActionShare>this)[key] = data[key];
    });
  }
}

export class NotificationTaskAction implements ITaskActionSetActionNotification {
  public type = INotificationType.TEXT;
  public message = '';
  public body = '';
  public conversation_id = '';
  constructor(data?: any) {
    this.parse(data || {});
  }
  public parse(data: any): void {
    ['type', 'message', 'body', 'conversation_id'].forEach(key => {
      if (data[key] === undefined) return;
      (<ITaskActionSetActionNotification>this)[key] = data[key];
    });
  }
}

export class DataTaskAction implements ITaskActionSetActionData {
  public value: string = '';
  public formatted_value: string = '';
  public reset_value?: string = '';
  public reset_time?: string = '';
  constructor(data?: any) {
    this.parse(data || {});
  }
  public parse(data: any): void {
    ['value', 'formatted_value', 'reset_value', 'reset_time'].forEach(key => {
      if (data[key] === undefined) return;
      (<ITaskActionSetActionData>this)[key] = data[key];
    });
  }
}

export class ComponentTaskAction implements ITaskActionSetActionShareComponent {
  public name: string = '';
  public type: string = 'News';
  public data: string = '';
  constructor(data?: any) {
    this.parse(data || {});
  }
  public parse(data: any): void {
    ['name', 'type', 'data'].forEach(key => {
      if (data[key] === undefined) return;
      (<ITaskActionSetActionShareComponent>this)[key] = data[key];
    });
  }
}
