'use strict';

const version = require('../package.json').version;

import { IIPPConfig, Config, IConfig } from './Config';
import { IApiService, Api } from './Api';
import { StorageService, IStorageService } from './Storage';
import Classy, { IClassy } from './Classy';
import Utils, { IUtils } from './Utils';
import Helpers, { IHelpers, IButtonTask } from './Helpers';
import { IAuthService, Auth } from './Auth';
import { ICryptoService, Crypto } from './Crypto';
import { IPageMain, PageWrap, Page, IPageService } from './Page/Page';
import { Clipboard, IClipboard } from './Clipboard';
import Tracking, { ITracking } from './Tracking';
import { PermissionRange, IPagePermissionRange, IPageRangeRights } from './Page/Range';
import PdfWrap, { IPdf, Pdf } from './Pdf';
// import { IParser, Parser, IParserColumnDefinition, ParserColumnDefinition, IPageCellStyle } from './Page/Parser';
import { IGrid, Grid } from './Grid4/Grid';
import { IFunctions, IFunctionsVar, Functions } from './Functions';
import { IPageContent } from './Page/Content';
import Keys, { IKeysService } from './Keys';
import { IActionsButton, Button } from './Actions/Buttons';
import { IActionsChart, Chart } from './Actions/Charts';
import {
  ITask,
  Task,
  ITaskActionSet,
  ITaskActionSetAction,
  ITaskActionSetActionShare,
  ITaskActionSetActionNotification,
  ITaskActionSetActionShareComponent,
  ITaskActionSetActionData,
  TaskActions,
  TaskAction,
  ShareTaskAction,
  DataTaskAction,
  NotificationTaskAction,
  ComponentTaskAction
} from './Actions/Tasks';
import { IActionsStyle, IActionsStyleCondition, Style, StyleCondition } from './Actions/Styles';
import { FolderWrap, Folder } from './Folder';
import Usage, { IUsage } from './Usage';
import Billing, { IBilling } from './Billing';
import Organization, { IOrganization } from './Organization';

export interface ICreate {
  version: string;
  config: any;
  api: IApiService;
  auth: IAuthService;
  crypto: ICryptoService;
  tracking: ITracking;
  helpers: IHelpers;
  storage: IStorageService;
  usage: IUsage;
  organization: IOrganization;
  utils: IUtils;
  keys: IKeysService;
  billing: IBilling;
  // Parser: new () => IParser;
  // ParserColumnDefintion: new (data: any, styleDefaults: IPageCellStyle) => IParserColumnDefinition;
  Grid: new (id: string, options?: any) => IGrid;
  Page: new (pageId: number | string, folderId: number | string, uuid?: string) => IPageMain;
  PermissionRange: new (
    name: string,
    rowStart: number,
    rowEnd: number,
    colStart: number,
    colEnd: number,
    permissions?: IPageRangeRights
  ) => IPagePermissionRange;
  Clipboard: new (element?: any, doc?: boolean) => IClipboard;
  Pdf: new (container: string) => IPdf;
  Functions: new (content?: IPageContent, vars?: IFunctionsVar) => IFunctions;
  Button: new (data?: any) => IActionsButton;
  Chart: new (data?: any) => IActionsChart;
  Task: new (data?: any) => ITask;
  TaskActions: new (data?: any) => ITaskActionSet;
  TaskAction: new (data?: any) => ITaskActionSetAction;
  DataTaskAction: new (data?: any) => ITaskActionSetActionData;
  ShareTaskAction: new (data?: any) => ITaskActionSetActionShare;
  NotificationTaskAction: new (data?: any) => ITaskActionSetActionNotification;
  ComponentTaskAction: new (data?: any) => ITaskActionSetActionShareComponent;
  Style: new (data?: any) => IActionsStyle;
  StyleCondition: new (data?: any) => IActionsStyleCondition;
  Folder: new () => Folder;
}

const ScriptLoader = (url: string) => {
  var s = document.createElement('script');
  s.type = 'text/javascript';
  s.async = true;
  s.src = url;
  var x = document.getElementsByTagName('head')[0];
  x.appendChild(s);
};

const config: IConfig = new Config();
const storage: IStorageService = new StorageService(config) as IStorageService;
const api: IApiService = new Api(config, storage);
const crypto: ICryptoService = new Crypto();
const auth: IAuthService = new Auth(config, api, storage);
const helpers: IHelpers = new Helpers();
const utils: IUtils = new Utils();
const tracking: ITracking = new Tracking(storage);
const usage: IUsage = new Usage(api, auth);
const organization: IOrganization = new Organization(api, auth);
const keys: IKeysService = new Keys(storage);
const billing: IBilling = new Billing(config, api, storage);
new PageWrap(api, auth, storage, keys, crypto, config);
new PdfWrap(storage, config) as IPdf;
new FolderWrap(api, auth);

export class Create implements ICreate {
  public version = version;
  public config: IConfig;
  public storage: IStorageService;
  public classy: IClassy;
  public helpers: IHelpers;
  public utils: IUtils;
  public api: IApiService;
  public auth: IAuthService;
  public crypto: ICryptoService;
  public tracking: ITracking;
  public usage: IUsage;
  public organization: IOrganization;
  public keys: IKeysService;
  public billing: IBilling;
  // public Parser: new () => IParser;
  // public ParserColumnDefintion: new (data: any, styleDefaults: IPageCellStyle) => IParserColumnDefinition;
  public Grid: new (id: string, options?: any) => IGrid;
  public PermissionRange: new (
    name: string,
    rowStart: number,
    rowEnd: number,
    colStart: number,
    colEnd: number,
    permissions?: IPageRangeRights
  ) => IPagePermissionRange;
  public Page: IPageService;
  public Clipboard: new (element?: any, doc?: boolean) => IClipboard;
  public Pdf: new (container: string) => IPdf;
  public Functions: new (content?: IPageContent, vars?: IFunctionsVar) => IFunctions;
  public Button: new (data?: any) => IActionsButton;
  public Chart: new (data?: any) => IActionsChart;
  public Task: new (data?: any) => ITask;
  public TaskActions: new (data?: any) => ITaskActionSet;
  public TaskAction: new (data?: any) => ITaskActionSetAction;
  public DataTaskAction: new (data?: any) => ITaskActionSetActionData;
  public ShareTaskAction: new (data?: any) => ITaskActionSetActionShare;
  public NotificationTaskAction: new (data?: any) => ITaskActionSetActionNotification;
  public ComponentTaskAction: new (data?: any) => ITaskActionSetActionShareComponent;  
  public Style: new (data?: any) => IActionsStyle;
  public StyleCondition: new (data?: any) => IActionsStyleCondition;  
  public Folder: new () => Folder;
  constructor(public settings: IIPPConfig) {
    this.config = config;
    this.config.set(settings);
    this.classy = new Classy();
    this.helpers = helpers;
    this.utils = utils;
    this.crypto = crypto;
    this.storage = new StorageService(this.config) as IStorageService;
    this.api = new Api(this.config, this.storage);
    this.auth = new Auth(this.config, this.api, this.storage);
    this.tracking = new Tracking(this.storage);
    this.usage = new Usage(this.api, this.auth);
    this.organization = new Organization(this.api, this.auth);
    this.helpers = helpers;
    this.keys = keys;
    this.billing = billing;
    // this.Parser = Parser;
    // this.ParserColumnDefintion = ParserColumnDefinition;
    this.Grid = Grid;
    new PageWrap(this.api, this.auth, this.storage, this.keys, this.crypto, this.config);
    this.Page = Page;
    this.PermissionRange = PermissionRange;
    this.Clipboard = Clipboard;
    this.Pdf = Pdf;
    this.Functions = Functions;
    this.Button = Button;
    this.Chart = Chart;
    this.Task = Task;
    this.TaskActions = TaskActions;
    this.TaskAction = TaskAction;
    this.DataTaskAction = DataTaskAction;
    this.ShareTaskAction = ShareTaskAction;
    this.NotificationTaskAction = NotificationTaskAction;
    this.ComponentTaskAction = ComponentTaskAction;
    this.Style = Style;
    this.StyleCondition = StyleCondition;
    new FolderWrap(api, auth);
    this.Folder = Folder;
  }
}

export {
  version,
  config,
  storage,
  api,
  crypto,
  auth,
  helpers,
  utils,
  tracking,
  usage,
  organization,
  keys,
  billing,
  Page,
  ScriptLoader,
  Grid,
  Pdf,
  Functions,
  Clipboard,
  PermissionRange,
  Button,
  Chart,
  Task,
  TaskActions,
  TaskAction,
  DataTaskAction,
  ShareTaskAction,
  NotificationTaskAction,
  ComponentTaskAction,
  Style,
  StyleCondition,
  Folder
};

export interface IPushPull {
  version: string;
  config: IConfig;
  storage: IStorageService;
  api: IApiService;
  crypto: ICryptoService;
  auth: IAuthService;
  helpers: IHelpers;
  utils: IUtils;
  tracking: ITracking;
  usage: IUsage;
  organization: IOrganization;
  keys: IKeysService;
  billing: IBilling;
  Create: new (settings: IIPPConfig) => ICreate;
  Page: IPageService;
  ScriptLoader: any;
  Grid: new (id: string, options?: any) => IGrid;
  Functions: new (content?: IPageContent, vars?: IFunctionsVar) => IFunctions;
  Clipboard: new (element?: any, doc?: boolean) => IClipboard;
  PermissionRange: new (
    name: string,
    rowStart: number,
    rowEnd: number,
    colStart: number,
    colEnd: number,
    permissions?: IPageRangeRights
  ) => IPagePermissionRange;
  Pdf: new (container: string) => IPdf;
  Button: new (data?: any) => IActionsButton;
  Chart: new (data?: any) => IActionsChart;
  Task: new (data?: any) => ITask;
  TaskActions: new (data?: any) => ITaskActionSet;
  TaskAction: new (data?: any) => ITaskActionSetAction;
  DataTaskAction: new (data?: any) => ITaskActionSetActionData;
  ShareTaskAction: new (data?: any) => ITaskActionSetActionShare;
  NotificationTaskAction: new (data?: any) => ITaskActionSetActionNotification;
  ComponentTaskAction: new (data?: any) => ITaskActionSetActionShareComponent;  
  Style: new (data?: any) => IActionsStyle;
  StyleCondition: new (data?: any) => IActionsStyleCondition;  
  Folder: new () => Folder;
}

let ipushpull: IPushPull = {
  version,
  config,
  storage,
  api,
  crypto,
  auth,
  helpers,
  utils,
  tracking,
  usage,
  organization,
  keys,
  billing,
  Create,
  Page,
  Grid,
  Pdf,
  Functions,
  Clipboard,
  PermissionRange,
  ScriptLoader,
  Button,
  Chart,
  Task,
  TaskActions,
  TaskAction,
  DataTaskAction,
  ShareTaskAction,
  NotificationTaskAction,
  ComponentTaskAction,  
  Style,
  StyleCondition,
  Folder
};
export default ipushpull;
