import Helpers, { IHelpers } from '../Helpers';
import Emitter, { IEmitter } from '../Emitter';
import { IGridCellDataset, IGridCellParams, IGridContentCellPosition } from './GridCell';

const helpers: IHelpers = new Helpers();

export interface IGridCellHeadingDataset extends IGridCellDataset {
  type: string;
}

export interface IGridHeadingCellResizing extends IEmitter {
  type: string;
  width: number;
  height: number;
  offsetX: number;
  offsetY: number;
}

export interface IGridHeadingCell extends IEmitter {
  VALUE: string;
  RESIZING: string;
  RESIZED: string;
  type: string;
  cell: HTMLDivElement;
  handle: HTMLDivElement;
  dataset: IGridCellHeadingDataset;
  common: boolean;
  reference: string;
  hidden: boolean;
  params: IGridCellParams;
  row: number;
  col: number;  
  position: IGridContentCellPosition;
  index: IGridContentCellPosition;  
  selected(n: boolean): void;
  setFreeze(common: boolean): void;
  setSize(which: string, size: number): void;
  setOffset(which: string, size: number): void;
  setPosition(which: string, size: number, move?: boolean): void;
  setSorting(direction: string): void;
  setIndex(row: number, y: number, zIndex: number): void;
}

export class GridHeadingCell extends Emitter implements IGridHeadingCell {
  public get VALUE(): string {
    return 'value';
  }
  public get RESIZING(): string {
    return 'resizing';
  }
  public get RESIZED(): string {
    return 'resized';
  }
  public cell: HTMLDivElement;
  public handle: HTMLDivElement;
  public dataset: IGridCellHeadingDataset;
  public common: boolean = false;
  public reference: string = '';
  public hidden: boolean = false;
  public row: number = -1;
  public col: number = -1;  
  public index: IGridContentCellPosition = {
    row: -1,
    col: -1
  };  
  public position: IGridContentCellPosition = {
    row: -1,
    col: -1
  };  

  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 type: string, public params: IGridCellParams) {
    super();
    // this.hidden = params.hidden;
    let cell = document.createElement('div');
    cell.className = `grid-cell-heading grid-cell-heading-${type}`;
    cell.style.setProperty('transform', `translate(${params.x}px, ${params.y}px)`);
    // cell.style.setProperty('transform', `translateX(${params.x}px)`);
    if (type === 'row') {
      this.reference = helpers.toColumnName(params.colIndex + 1);
      cell.innerText = helpers.toColumnName(params.colIndex + 1);
      cell.style.setProperty('width', params.content.style.width!);
      cell.style.setProperty('height', '20px');
      cell.style.setProperty('z-index', `${params.zIndexCol}`);
    } else if (type === 'col') {
      this.reference = `${params.content.index.row + 1}`;
      cell.innerText = (params.content.index.row + 1).toString();
      cell.style.setProperty('width', '40px');
      cell.style.setProperty('height', params.content.style.height!);
      cell.style.setProperty('z-index', `${params.zIndexRow}`);
    }
    // cell.style.setProperty('z-index', `${params.zIndexRow * params.zIndexCol}`);
    // cell.dataset.width = parseFloat(params.col.style.width!).toString();
    // cell.dataset.height = parseFloat(params.col.style.height!).toString();
    // cell.dataset.overflow = cell.dataset.width;
    // cell.dataset.x = params.x.toString();
    // cell.dataset.y = params.y.toString();
    cell.dataset.row = params.rowIndex.toString();
    cell.dataset.col = params.colIndex.toString();
    cell.dataset.r = params.rowIndex.toString();
    cell.dataset.c = params.colIndex.toString();
    cell.dataset.type = type;

    this.row = params.rowIndex;
    this.col = params.colIndex;    
    this.position.row = params.rowIndex;
    this.position.col = params.colIndex;
    this.index.row = params.rowIndex;
    this.index.col = params.colIndex;

    this.handle = document.createElement('div');
    this.handle.className = 'grid-resize-handle';
    this.handle.addEventListener('mousedown', this.onMouseDown);
    cell.appendChild(this.handle);

    this.cell = cell;
    let dataset: any = {
      width: Math.round(parseFloat(params.content.style.width!)),
      height: Math.round(parseFloat(params.content.style.height!)),
      overflow: Math.round(parseFloat(params.content.style.width!)),
      x: params.x,
      y: params.y,
      row: params.rowIndex,
      col: params.colIndex,
      type
    };
    // Object.keys(cell.dataset).forEach((key: string) => {
    //   dataset[key] = key === 'type' ? cell.dataset[key] : parseFloat(cell.dataset[key] || '0');
    // });
    this.dataset = dataset;
  }
  public selected(n: boolean): void {
    if (!n) {
      this.cell.classList.remove('selected');
      return;
    }
    this.cell.classList.add('selected');
  }
  public setFreeze(common: boolean): void {
    this.common = common;
    this.setTranslate(this.dataset.x, this.dataset.y);
  }
  public setSize(which: string, size: number): void {
    if (this.type === 'corner') return;
    // if (this.type === 'col' && which === 'width') return;
    // if (this.type === 'row' && which === 'height') return;
    // if (which === 'width' && index !== this.dataset.col) return;
    // if (which === 'height' && index !== this.dataset.row) return;
    this.params.content.style[which] = `${size}px`;
    this.dataset[which] = size;
    if (which === 'width') {
      this.dataset.overflow = size;
    }
    this.cell.style.setProperty(which, `${size}px`);
  }
  public setOffset(which: string, offset: number): void {
    if (this.type === 'corner') return;
    let xOffset = this.dataset.x;
    let yOffset = this.dataset.y;
    if (which === 'width') {
      // if (this.dataset.col <= index || this.type === 'col') return;
      xOffset = this.dataset.x + offset;
    } else {
      // if (this.dataset.row <= index || this.type === 'row') return;
      yOffset = this.dataset.y + offset;
    }
    // this.cell.style.setProperty('transform', `translate(${xOffset}px, ${yOffset}px)`);
    this.setTranslate(xOffset, yOffset);
  }
  public setPosition(which: string, offset: number, move?: boolean): void {
    if (this.type === 'corner') return;
    if (which === 'width') {
      // if (this.dataset.col <= index) return;
      // this.params.x += offset;
      this.dataset.x += offset;
    } else {
      // if (this.dataset.row <= index) return;
      // this.params.y += offset;
      this.dataset.y += offset;
    }
    if (move) this.setTranslate(this.dataset.x, this.dataset.y);
  }
  public setIndex(row: number, y: number, zIndex: number): void {
    this.dataset.row = row;
    this.dataset.y = y;
    // this.cell.style.setProperty('transform', `translate(${this.dataset.x}px, ${this.dataset.y}px)`);
    this.setFreeze(this.common);
    // this.cell.style.setProperty('z-index', `${zIndex}`);
  }
  public setSorting(direction: string): void {
    if (!direction) {
      this.cell.classList.remove('sorting-asc', 'sorting-desc');
    } else {
      this.cell.classList.add(`sorting-${direction}`);
    }
  }
  private setTranslate(x: number, y: number): void {
    if (this.common) {
      this.hidden = false;
      if (this.type === 'row') {
        this.cell.style.setProperty('transform', `translate(${x + 40}px, ${y}px)`);
      } else {
        this.cell.style.setProperty('transform', `translate(${x}px, ${y + 20}px)`);
      }
    } else {
      this.cell.style.setProperty('transform', `translate(${x}px, ${y}px)`);
    }
  }
  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.height = this.dataset.height;
    this.startX = evt.x;
    this.startY = evt.y;
    // 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);
    console.log(this);
  };
  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
    });
    // 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);
  };
}
