import Helpers, { IHelpers } from '../Helpers';
import Emitter, { IEmitter } from '../Emitter';
import { IPageContentLink, IPageContentCell, IPageContentCellIndex } from '../Page/Content';
import { IActionsButton } from '../Actions/Buttons';
import GridPage, { IGridPage } from './GridPage';
import { IActionsStyleConditionStyle } from '../Actions/Styles';
import GridEvents, { IGridEvents } from './GridEvents';
import { IGridSelection, IGrid } from './Grid';

const helpers: IHelpers = new Helpers();

export interface IGridCellDataset {
  x: number;
  y: number;
  width: number;
  height: number;
  overflow: number;
  row: number;
  col: number;
  [key: string]: any;
}

export interface IGridContentCellPosition {
  row: number;
  col: number;
  [key: string]: number;
}

export interface IGridCellEvent {
  evt: any;
  cell: IGridHeadingCell;
  value: string;
  done: boolean;
}

export interface IGridHeadingCellDetails {
  // evt?: any;
  // cell?: HTMLDivElement;
  content: IPageContentCell;
  row: number;
  col: number;
  position: IGridContentCellPosition;
  index: IGridContentCellPosition;
  dataset: IGridCellDataset;
  reference: string;
  sticky: boolean;
}

export interface IGridHeadingCell extends IEmitter {

  Page: IGridPage;
  Events: IGridEvents; 

  row: number;
  rowIndex: number;
  col: number;
  init: boolean;
  cell: HTMLDivElement;
  dataset: IGridCellDataset;
  reference: string;
  content: IPageContentCell;
  hidden: boolean;
  position: IPageContentCellIndex;
  index: IGridContentCellPosition;
  type: string;

  create(): void;
  update(row: number, col: number, force?: boolean): void;
  refresh(): void;

  setFreeze(n: boolean): void;
  setSelected(selection: IGridSelection): void;
  setSorting(direction: string): void;
}

export class GridHeadingCell extends Emitter implements IGridHeadingCell {
  // public Page!: IGridPage;
  // public Events!: IGridEvents;  
  // public type: string = '';
  public init: boolean = false;
  public sticky: boolean = false;
  public selected: boolean = false;
  public dataset: IGridCellDataset = {
    x: 0,
    y: 0,
    width: 0,
    height: 0,
    overflow: 0,
    row: 0,
    col: 0
  };
  public button: IActionsButton | null = null;
  public link: IPageContentLink | null = null;
  public style: IActionsStyleConditionStyle | null = null;
  public reference: string = '';
  public hidden: boolean = false;
  public position: IPageContentCellIndex = {
    row: -1,
    col: -1
  };
  public index: IGridContentCellPosition = {
    row: -1,
    col: -1
  };

  // dom
  public cell: HTMLDivElement;
  public handle!: HTMLDivElement;

  public editing: boolean = false;
  public content!: IPageContentCell;

  private borders: any = {
    widths: {
      none: 0,
      thin: 1,
      medium: 2,
      thick: 3
    },
    styles: {
      none: 'none',
      solid: 'solid',
      double: 'double',
      dash: 'dashed'
    },
    names: {
      t: 'top',
      r: 'right',
      b: 'bottom',
      l: 'left'
    }
  };
  private highlightTimer: any = null;
  private oldValue: string = '';
  private _rowIndex: number = 0;
  private buttonPopper: any;
  private selectedOption: number = 0;
  private done: boolean = false;
  private editValue: any;

  private moving: boolean = false;
  public startX: number = 0;
  public offsetX: number = 0;
  public startY: number = 0;
  public offsetY: number = 0;
  public zIndex: string = '';
  private width: number = 0;
  private height: number = 0;

  constructor(public Page: IGridPage, public Events: IGridEvents, public row: number, public col: number, public type: string) {
    super();
    this.cell = document.createElement('div');
    this.cell.classList.add('grid-cell-heading');
    this.cell.classList.add(`grid-cell-heading-${type}`);
    this.cell.classList.add(`grid-col-${col}`);
    this.rowIndex = row;
    if (this.type === 'col') {
      this.reference = `${helpers.toColumnName(col + 1)}`;
    } else if (this.type === 'row') {
      this.reference = `${row + 1}`;
    }
    this.cell.textContent = this.reference;

    if (!this.Page.touch) {
      this.handle = document.createElement('div');
      this.handle.className = 'grid-resize-handle';
      this.handle.addEventListener('mousedown', this.onMouseDown);
      this.cell.appendChild(this.handle);
    }

    this.update(row, col);
    // this.update(row, col);
  }

  public get rowIndex(): number {
    return this._rowIndex;
  }

  public set rowIndex(n: number) {
    this._rowIndex = n;
    this.index.row = n;
  }

  public create(): void {
    this.init = true;

    // events
    // let rightClick = false;
    // let d = new Date();
    // let clickedAt = 0;
    // let doubleClicked = false;
    const emit = (evt: any) => {
      this.Events.emit(this.Events.CELL, { evt, cell: this });
    };
    if (this.Page.touch) {
      this.cell.ontouchstart = emit;
      // this.cell.ontouchmove = emit;
      this.cell.ontouchend = emit;
    } else {
      this.cell.onmousedown = emit;
      this.cell.onmouseover = emit;
      this.cell.onmouseup = emit;
    }
  }

  public update(row: number, col: number): void {
    this.content = { ...this.Page.originalContent[row][col] };
    // if (
    //   this.Page.deltaContent[this.content.index!.row] &&
    //   this.Page.deltaContent[this.content.index!.row][this.content.index!.col]
    // ) {
    //   force = true;
    //   this.content = { ...this.Page.deltaContent[this.content.index!.row][this.content.index!.col] };
    // }
    // if (this.row === row && this.col === col && !force) return;
    this.index.row = this.row;
    this.index.col = this.col;
    this.position = this.index!;
    this.row = row;
    this.col = col;
    if (!this.init) this.create();
    // this.cell.setAttribute('id', `cell-${row}-${col}`);
    let pos = this.Page.cellPos(row, col);
    this.dataset.x = pos.x;
    this.dataset.y = pos.y;
    this.dataset.width = parseFloat(this.content.style.width!);
    this.dataset.height = parseFloat(this.content.style.height!);
    // this.cell.style.setProperty('left', `${pos.x}px`);
    // if (this.type === 'col') this.cell.style.setProperty('width', this.content.style.width!);
    // this.cell.style.setProperty('height', this.content.style.height!);
    let offset = this.type === 'corner' ? 2 : 1;
    this.cell.style.setProperty('z-index', `${this.Page.cols - this.col + offset}`);
    // this.cell.style.cssText = `width:${this.content.style.width!};height:${this.content.style.height!};z-index:${this.Page.cols - this.col}`;
    // if (
    //   this.Page.originalContent[this.row][this.col - 1] &&
    //   this.content.style['background-color'] != this.Page.originalContent[this.row][this.col - 1].style['background-color']
    // ) {
    //   if (!this.cellBackground.parentNode) this.cell.appendChild(this.cellBackground);
    // }
    // this.cellBackground.style.cssText = `background-color:${this.content.style['background-color']}`;
    // this.refresh();
  }

  public refresh(): void {}

  public getDetails(): IGridHeadingCellDetails {
    return {
      content: this.content,
      row: this.row,
      col: this.col,
      position: {
        row: this.row,
        col: this.col
      },
      index: {
        row: this.content.index!.row,
        col: this.content.index!.col
      },
      dataset: { ...this.dataset },
      reference: this.reference,
      sticky: this.sticky
    };
  }

  public setFreeze(n: boolean): void {
    // if (n === this.sticky) return;
    this.sticky = n;
    if (n) {
      // let left = this.Page.colWidths.slice(0, this.col).reduce((a: any, b: any) => a + b, 0);
      this.cell.classList.add('sticky');
      let offset = this.Page.headings && this.type != 'corner' ? 40 : 0;
      this.cell.style.setProperty('left', `${this.dataset.x + offset}px`);
    } else {
      this.cell.classList.remove('sticky');
      this.cell.style.removeProperty('left');
    }
  }

  public setSelected(selection: IGridSelection): void {
    this.selected =
      (this.type === 'row' && this.Page.selectedRows.includes(this.row)) ||
      (this.type == 'col' && this.Page.selectedCols.includes(this.col));
    // this.col >= selection.colFrom &&
    // this.row >= selection.rowFrom &&
    // this.col <= selection.colTo &&
    // this.row <= selection.rowTo;
    // if (n === this.selected) return;
    // console.log(this.selected, this.row, this.col);
    if (this.selected) {
      this.cell.classList.add('selected');
    } else {
      this.cell.classList.remove('selected');
    }
  }

  public setSorting(direction: string): void {
    if (!direction) {
      this.cell.classList.remove('sorting-asc', 'sorting-desc');
    } else {
      this.cell.classList.add(`sorting-${direction}`);
    }
  }

  private onMouseDown = (evt: MouseEvent) => {
    if (evt.target !== this.handle) {
      return;
    }
    window.addEventListener('mouseup', this.onMouseUp);
    window.addEventListener('mousemove', this.onMouseMove);
    this.moving = true;
    this.width = this.dataset.width = this.Page.colWidths[this.col]; // this.dataset.width;
    this.height = this.dataset.height = this.Page.rowHeights[this.row]; // this.dataset.height;
    this.startX = evt.x;
    this.startY = evt.y;
    evt.stopPropagation();
    this.Events.emit(this.Events.CELL, {
      evt: { type: 'resize' },
      cell: this,
      data: {
        width: this.dataset.width,
        height: this.dataset.height
      }
    });    
    // this.zIndex = this.element.style.getPropertyValue('z-index');
    // this.element.style.setProperty('z-index', `${parseFloat(this.zIndex) * 1000}`);
    // this.element.classList.add('active');
  };
  private onMouseUp = (evt: MouseEvent) => {
    if (!this.moving) {
      return;
    }
    window.removeEventListener('mouseup', this.onMouseUp);
    window.removeEventListener('mousemove', this.onMouseMove);
    this.moving = false;
    // this.element.style.setProperty('z-index', `${parseFloat(this.zIndex) * 1000}`);
    // this.element.classList.remove('active');
    // this.emitSize();
    // this.emit(this.RESIZED);
    this.Events.emit(this.Events.CELL, {
      evt: { type: 'resized' },
      cell: this,
      data: {
        width: this.dataset.width,
        height: this.dataset.height
      }
    });
    evt.stopPropagation();
  };
  private onMouseMove = (evt: MouseEvent) => {
    if (!this.moving) {
      return;
    }
    this.offsetX = evt.x - this.startX;
    this.offsetY = evt.y - this.startY;
    let width = this.width + this.offsetX;
    if (width < 20) width = 20;
    let height = this.height + this.offsetY;
    if (height < 20) height = 20;
    // this.emit(this.RESIZING, {
    //   type: this.type,
    //   width,
    //   height,
    //   offsetX: width - this.width,
    //   offsetY: height - this.height
    // });
    this.Events.emit(this.Events.CELL, {
      evt: { type: 'resizing' },
      cell: this,
      data: {
        type: this.type,
        width,
        height,
        offsetX: width - this.width,
        offsetY: height - this.height
      }
    });
    if (this.type === 'col') {
      this.dataset.width = width;
    }
    if (this.type === 'row') {
      this.dataset.height = height;
    }
    evt.stopPropagation();
    // console.log(this.onListeners);
    // if (this.axis === 'col') {
    //   this.Grid.Content.setColSize(this.cell, width);
    // } else {
    //   this.Grid.Content.setRowSize(this.cell, height);
    // }

    // console.log(this.width, width, this.Grid.Content.cells[0][0].style.width);
  };
}
