import {
  customElement,
  DeesElement,
  TemplateResult,
  property,
  html,
  css,
  unsafeCSS,
  cssManager,
} from '@designestate/dees-element';

import * as domtools from '@designestate/dees-domtools';

declare global {
  interface HTMLElementTagNameMap {
    'dees-input-fileupload': DeesInputFileupload;
  }
}

@customElement('dees-input-fileupload')
export class DeesInputFileupload extends DeesElement {
  public static demo = () => html`<dees-input-fileupload></dees-input-fileupload>`;

  // INSTANCE
  public changeSubject = new domtools.rxjs.Subject();

  @property({
    type: String,
  })
  public label: string = null;

  @property({
    type: String,
  })
  public key: string;

  @property({
    attribute: false,
  })
  public value: File[] = [];

  @property()
  public state: 'idle' | 'dragOver' | 'dropped' | 'uploading' | 'completed' = 'idle';

  @property({
    type: Boolean,
  })
  public required: boolean = false;

  @property({
    type: Boolean,
  })
  public disabled: boolean = false;

  @property({
    type: String,
  })
  public buttonText: string = 'Upload File...';

  constructor() {
    super();
  }

  public static styles = [
    cssManager.defaultStyles,
    css`
      :host {
        position: relative;
        display: grid;
        margin: 10px 0px;
        margin-bottom: 24px;
      }

      .maincontainer {
        color: ${cssManager.bdTheme('#333', '#ccc')};
      }

      .label {
        font-size: 14px;
        margin-bottom: 5px;
      }

      .uploadButton {
        position: relative;
        cursor: pointer;
        padding: 8px;
        max-width: 600px;
        background: ${cssManager.bdTheme('#fafafa', '#333333')};
        border-radius: 3px;
        text-align: center;
      }
      .uploadButton::after {
        top: 2px;
        right: 2px;
        left: 2px;
        bottom: 2px;
        transform: scale3d(0.98, 0.9, 1);
        position: absolute;
        content: '';
        display: block;
        border: 2px dashed rgba(255, 255, 255, 0);
        transition: all 0.2s;
      }
      .uploadButton.dragOver::after {
        transform: scale3d(1, 1, 1);
        border: 2px dashed rgba(255, 255, 255, 0.3);
      }

      .uploadCandidate {
        text-align: left;
        border-bottom: 1px dashed #444;
        color: #fff;
        padding: 8px;
        font-family: 'Roboto Mono';
      }
      .uploadCandidate:last-child {
        margin-bottom: 8px;
      }
    `,
  ];

  public render(): TemplateResult {
    return html`
      <div class="maincontainer">
        ${this.label ? html`<div class="label">${this.label}</div>` : null}
        <div class="uploadButton ${this.state === 'dragOver' ? 'dragOver' : ''}">
          ${this.value.map((fileArg) => html` <div class="uploadCandidate">${fileArg.name} | ${fileArg.size}</div> `)}
          ${this.buttonText}
        </div>
      </div>
    `;
  }

  public async updateValue(eventArg: Event) {
    const target: any = eventArg.target;
    this.value = target.value;
    this.changeSubject.next(this);
  }

  public firstUpdated() {
    const dropArea = this.shadowRoot.querySelector('.uploadButton');
    const handlerFunction = (eventArg: DragEvent) => {
      eventArg.preventDefault();
      switch (eventArg.type) {
        case 'dragover':
          this.state = 'dragOver';
          this.buttonText = 'release to upload file...';
          break;
        case 'dragleave':
          this.state = 'idle';
          this.buttonText = 'Upload File...';
          break;
        case 'drop':
          this.state = 'idle';
          this.buttonText = 'Upload more files...';
      }
      console.log(eventArg);
      for (const file of Array.from(eventArg.dataTransfer.files)) {
        this.value.push(file);
        this.requestUpdate();
      }
      console.log(`Got ${this.value.length} files!`);
    };
    dropArea.addEventListener('dragenter', handlerFunction, false);
    dropArea.addEventListener('dragleave', handlerFunction, false);
    dropArea.addEventListener('dragover', handlerFunction, false);
    dropArea.addEventListener('drop', handlerFunction, false);
  }
}