import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';

export class DragDropEventFactory<T> {

  createInContainerEvent(containerId: string, data: T[], fromIndex: number, toIndex: number): CdkDragDrop<T[], T[]> {
    const event = this.createEvent(fromIndex, toIndex);
    // tslint:disable-next-line: no-any
    const container: any = { id: containerId, data };
    event.container = (container as CdkDropList<T[]>);
    event.previousContainer = event.container;
    event.item = ({ data: data[fromIndex] } as CdkDrag<T>);
    return event;
  }

  createCrossContainerEvent(from: IContainerModel<T>, to: IContainerModel<T>): CdkDragDrop<T[], T[]> {
    const event = this.createEvent(from.index, to.index);
    event.container = this.createContainer(to);
    event.previousContainer = this.createContainer(from);
    event.item = ({ data: from.data[from.index] } as CdkDrag<T>);
    return event;
  }

  private createEvent(previousIndex: number, currentIndex: number): CdkDragDrop<T[], T[]> {
    return {
      previousIndex,
      currentIndex,
      container: undefined,
      item: undefined,
      previousContainer: undefined,
      isPointerOverContainer: true,
      distance: { x: 0, y: 0 }
    // tslint:disable-next-line: no-any
    } as any;
  }

  private createContainer(model: IContainerModel<T>): CdkDropList<T[]> {
    // tslint:disable-next-line: no-any
    const container: any = { id: model.id, data: model.data };
    return container as CdkDropList<T[]>;
  }
}

export interface IContainerModel<T> {
  id: string;
  data: T[];
  index: number;
}
