import { Inject, Injectable, LOCALE_ID } from '@angular/core';
import { Route } from '@angular/router';
import { EN_LogType } from '../consts';
import * as utils from '../utils';
import { exportPivotGrid as exportPivotGridToExcel, exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
import { jsPDF, jsPDFOptions } from 'jspdf';
import { Workbook } from 'exceljs';
import { saveAs } from 'file-saver';
import config from 'devextreme/core/config';
import { licenseKey } from '../devextreme-license';


export interface HRExportDataFromDxGrid {
  gridComponent: any;
  fileName: string;
  title?: {
    text?: string;
    tabName?: string;
    align?: 'left' | 'center' | 'right' | 'justify';
    x?: number;
    y?: number;
    divX?: number
  };
  margin?: { top: number; right: number; bottom: number; left: number };
  pdfOptions?: jsPDFOptions;
  repeatHeaders?: boolean;
  customizeCallback?: (any) => void;
  finalizeCallback?: () => void;
}

export interface IMessageBoxButton {
  title: string;
  hint?: string;
  code?: number;
  default?: boolean;
  cancel?: boolean;
  callback?: () => void;
}

export interface IMessageBoxData {
  type: EN_LogType;
  overHeader?: string;
  header: string;
  message: string;
  buttons: IMessageBoxButton[];
}

export interface IAppPage extends Route {
  caption: string;
  icon?: string;
  messageCaption?: string;
  hidden?: boolean;
  allowRedirect?: boolean;
  disabled?: boolean;
  showIconInNavbar?: boolean;
  dontAllowEmptyURL?: boolean;
}

export const LOGIN_PAGE: IAppPage = {
  caption: 'core.caption.login',
  path: 'login',
  loadChildren: () => import('../components/login/login.module').then(m => m.LoginModule),
  icon: 'logout',
  allowRedirect: true,
  hidden: true,
  messageCaption: 'stammdaten',
};

export const ACCOUNT_PAGE: IAppPage = {
  caption: 'core.caption.account',
  path: 'account',
  loadChildren: () => import('../components/account/account.module').then(m => m.AccountModule),
  icon: 'account_circle',
  hidden: false,
  messageCaption: 'My Account',
  showIconInNavbar: true
};

export enum EN_CoreEntities {
  User = 'WebAppUser',
  ServerInfo = 'Info'
}

config({ licenseKey });


@Injectable({ providedIn: 'root' })

export class Globals {
  public hrColorDarkBlue: string = '#0b3a62';
  public hrColorLightBlue: string = '#78b7e5';
  public hrColorLightGrey: string = '#878787';
  public hrColorDarkGrey: string = '#3c3c3b';
  public hrColorGreen: string = '#76b82a';

  public appTitle: string;
  public appTitleWithVersion: string;
  public currentPage: string; //path of the urrent page
  public urlParam: string;  //parameter in url
  public mainPage: IAppPage;
  public ipAddress: string;
  public showIds: boolean = false;

  public appPages: IAppPage[] = [
    LOGIN_PAGE,
  ];

  constructor(
    @Inject(LOCALE_ID) private locale: string
  ) { }


  isTheMainPage(page: string = null): boolean {
    return this.isThePage(this.mainPage.path, page);
  }

  isTheLoginPage(page: string = null): boolean {
    return this.isThePage(LOGIN_PAGE.path, page);
  }

  isTheCurrentPage(pageInx: number): boolean {
    return this.isThePage(this.appPages[pageInx].path);
  }

  isVisiblePage(page: string = null): boolean {
    const pg = this.appPages.find((_pg: IAppPage) => this.isThePage(_pg.path, page));
    return (pg && !pg.hidden);
  }

  isThePage(pagePath: string, page: string = null): boolean {
    return page ? ((!page.startsWith('/') ? '/' : '') + page + '/').startsWith('/' + pagePath + '/') : (this.currentPage + '/').startsWith(pagePath + '/');
  }

  getPageIndex(page: string): number {
    return this.appPages.findIndex((pg) => pg.path === page);
  }


  getPage(page: string): IAppPage {
    const indx = this.getPageIndex(page);
    return indx > -1 ? this.appPages[indx] : null;
  }

  //------------------------------------------

  public formatNumber(data: any, frac: number): string {
    if (data === null || data === undefined) return '';
    if (typeof data === 'object') return utils.formatNumbers(this.locale, +data.value, frac);
    else return utils.formatNumbers(this.locale, +data, frac);
  }


  formatNumber_0(data: any): string {
    return this.formatNumber(data, 0);
  }

  formatNumber_1(data: any): string {
    return this.formatNumber(data, 1);
  }

  formatNumber_2(data: any): string {
    return this.formatNumber(data, 2);
  }

  formatNumber_3(data: any): string {
    return this.formatNumber(data, 3);
  }

  formatNumber_4(data: any): string {
    return this.formatNumber(data, 4);
  }

  get localeDecimalSeparator(): string {
    return utils.getDecimalSeparator(this.locale);
  }

  get localeThousandSeparator(): string {
    return utils.getThousandSeparator(this.locale);
  }

  get localeDateFormat(): string {
    return utils.getDateFormat(this.locale);
  }

  get localeDateTimeFormat(): string {
    return utils.getDateTimeFormat(this.locale);
  }


  exportToPDF(option: HRExportDataFromDxGrid) {
    const doc = new jsPDF(option.pdfOptions);
    doc.text(option.title.text, option.title.x ?? doc.internal.pageSize.width / option.title.divX, option.title.y ?? 15, { align: option.title.align ?? 'center' });
    exportDataGridToPDF({
      jsPDFDocument: doc,
      component: option.gridComponent,
      repeatHeaders: option.repeatHeaders ?? true,
      margin: option.margin,
      customizeCell: (options) => { if (option.customizeCallback) option.customizeCallback(options); }
    }).then(() => {
      doc.save(option.fileName);
      if (option.finalizeCallback) option.finalizeCallback();
    });
  }



  public exportToExcel(option: HRExportDataFromDxGrid) {
    const workbook = new Workbook();
    const worksheet = workbook.addWorksheet(option.title?.tabName ?? utils.removeSpecialChars(option.fileName));
    const self = this;

    const exportToExcel = 'dxPivotGrid' === option.gridComponent.NAME ? exportPivotGridToExcel : exportDataGridToExcel;
    exportToExcel({
      component: option.gridComponent,
      worksheet: worksheet,
      topLeftCell: option.margin ? { row: option.margin.top, column: option.margin.left } : null,
      customizeCell: (options) => { if (option.customizeCallback) option.customizeCallback(options); }
    }).then(function () {
      workbook.xlsx.writeBuffer()
        .then((buffer: BlobPart) => {
          saveAs(new Blob([buffer], { type: 'application/octet-stream' }), option.fileName + '.xlsx');
        });
      if (option.finalizeCallback) option.finalizeCallback();
    });
  }


  public doExcelExportSimple(e: any, filename, dontExportFieldnameTemplatenameList?: string) {
    this.exportToExcel({
      fileName: filename
      , gridComponent: e.component
      , customizeCallback: 'dxPivotGrid' === e.component.NAME && !!dontExportFieldnameTemplatenameList ? this.dontExportFieldnameTemplatename.bind(this, dontExportFieldnameTemplatenameList) : null
    });
  }


  private dontExportFieldnameTemplatename(dontExportFieldnameTemplatenameList: string, options: any) {
    const { gridCell, excelCell } = options;
    dontExportFieldnameTemplatenameList = ',' + dontExportFieldnameTemplatenameList.replace(' ', '').toLocaleLowerCase() + ',';

    if (!!gridCell.column?.cellTemplate && dontExportFieldnameTemplatenameList.indexOf(',#' + gridCell.column?.cellTemplate.toLocaleLowerCase() + ',') > -1
      || !!gridCell.column?.dataField && dontExportFieldnameTemplatenameList.indexOf(',' + gridCell.column?.dataField.toLocaleLowerCase() + ',') > -1
    ) {
      excelCell.value = null;
      excelCell._column.hidden = true;
    }
  }
}
