import { html, TemplateResult } from 'lit';
import './nile-file-upload.css';
import { DragHandler } from './utils/drag-drop.util';
import { classMap } from 'lit-html/directives/class-map.js';
import { FileUploadDefaults, FileUploadState } from './types/file-upload.enums';
import { truncateString } from './utils/file-validation.util';
import { NileFileUpload } from './nile-file-upload';

const baseHorizontalState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  disabled: boolean,
  dragHandler: DragHandler,
  state: FileUploadState,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => {
  truncateString(nileFileUpload);
  return html`
  <div class="wrapper" part="horizontal-wrapper">
    <div part="horizontal-div" class=${classMap({ 'hover-border': state === "hover", 'horizontal-div': true, 'disable': disabled })}>
      <div part="inner-div" class="inner-div">
        <slot class="upload-icon-slot" name="upload-icon">
          <nile-icon name="upload" size="24"></nile-icon>
        </slot>
        <div part="content" class="content">
          <div part="horizontal-title" class="title">${title}</div>
          <div part="horizontal-subtitle" class="subtitle">${subtitle}</div>
        </div>
      </div>
      <input
        type="file"
        ?disabled=${disabled}
        @change=${(e: Event | DragEvent) => { dragHandler.handleFiles(e) }}
        ?multiple=${nileFileUpload.allowMultiple}
        accept=${allowedTypes.join(',')}
      />
      <slot class="browse-file-button" @click=${disabled ? undefined : browseFiles} name="browse-file-button">
        <nile-button variant="tertiary" ?disabled=${disabled}>
          Browse File
        </nile-button>
      </slot>
    </div>
    ${errorMessage || nileFileUpload.state === FileUploadState.ERROR ?
      html`
      <slot name="error-message">
        <div class="upload-error" part="horizontal-upload-error">
      <nile-icon name="warning" size="12" color="var(--nile-colors-red-700)"></nile-icon>
      ${
        nileFileUpload.isStringTruncated
          ? html`<nile-lite-tooltip .content=${errorMessage || FileUploadDefaults.CUSTOM_ERROR}>
              <span>${errorMessage || FileUploadDefaults.CUSTOM_ERROR}</span>
            </nile-lite-tooltip>`
          : html`<span>${errorMessage || FileUploadDefaults.CUSTOM_ERROR}</span>`
      }
    </div>
      </slot>
    `:
      html``
    }
  </div>
  `;
}

export const getHorizontalDefaultState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  dragHandler: DragHandler,
  state: FileUploadState,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => baseHorizontalState(browseFiles, title, subtitle, false, dragHandler, state, errorMessage, allowedTypes, nileFileUpload);

export const getHorizontalDisabledState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  dragHandler: DragHandler,
  state: FileUploadState,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => baseHorizontalState(browseFiles, title, subtitle, true, dragHandler, state, errorMessage, allowedTypes, nileFileUpload);

export const getHorizontalErrorState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  dragHandler: DragHandler,
  state: FileUploadState,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => baseHorizontalState(browseFiles, title, subtitle, false, dragHandler, state, errorMessage, allowedTypes, nileFileUpload);

export const getHorizontalDragState = (): TemplateResult => html`
  <div part="horizontal-drag-state" class="horizontal-div dragging">
    <div class="icons-container">
      <nile-icon
        color="var(--nile-colors-blue-500)"
        name="general"
        size="20"
        class="general-icon"
      ></nile-icon>
      <nile-icon
        color="var(--nile-colors-blue-500)"
        name="image"
        size="24"
        class="image-icon"
      ></nile-icon>
    </div>
    <p>${FileUploadDefaults.DRAG_STATE_DEFAULT}</p>
  </div>
`;

//  Vertical States
const baseVerticalState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  disabled: boolean,
  dragHandler: DragHandler,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => {
  truncateString(nileFileUpload);
  return html`
  <div part="vertical-wrapper" class="wrapper">
    <div part="vertical-default" class="vertical-default vertical-div ${disabled ? 'disable' : ''}">
      <slot name="upload-icon">
        <nile-icon name="upload" size="24"></nile-icon>
      </slot>
      <div part="vertical-content-container" class="content-container">
        <div part="vertical-title" class="title">${title}</div>
        <div part="vertical-subtitle" class="subtitle">${subtitle}</div>
      </div>
      <input
        type="file"
        ?disabled=${disabled}
        @change=${(e: Event | DragEvent) => dragHandler.handleFiles(e)}
        multiple
        accept=${allowedTypes.join(',')}
      />
      <slot @click=${disabled ? undefined : browseFiles} name="browse-file-button">
        <nile-button variant="tertiary" ?disabled=${disabled}>
          Browse File
        </nile-button>
      </slot>
    </div>
    ${errorMessage || nileFileUpload.state === FileUploadState.ERROR ?
      html`<div class="vertical-upload-error" part="vertical-upload-error">
        <nile-icon name="warning" size="12" color="var(--nile-colors-red-700)"></nile-icon>
        ${
          nileFileUpload.isStringTruncated
            ? html`<nile-lite-tooltip .content=${errorMessage || FileUploadDefaults.CUSTOM_ERROR}>
                <span>${errorMessage || FileUploadDefaults.CUSTOM_ERROR}</span>
              </nile-lite-tooltip>`
            : html`<span>${errorMessage || FileUploadDefaults.CUSTOM_ERROR}</span>`
        }
      </div>` :
      html``
    }
  </div>
  `;
}

export const getVerticalDefaultState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  dragHandler: DragHandler,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => baseVerticalState(browseFiles, title, subtitle, false, dragHandler, errorMessage, allowedTypes, nileFileUpload);

export const getVerticalDisabledState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  dragHandler: DragHandler,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => baseVerticalState(browseFiles, title, subtitle, true, dragHandler, errorMessage, allowedTypes, nileFileUpload);

export const getVerticalErrorState = (
  browseFiles: Function,
  title: string,
  subtitle: string,
  dragHandler: DragHandler,
  errorMessage: string,
  allowedTypes: string[],
  nileFileUpload: NileFileUpload
): TemplateResult => baseVerticalState(browseFiles, title, subtitle, false, dragHandler, errorMessage, allowedTypes, nileFileUpload);


export const getVerticalDragState = (): TemplateResult => html`
  <div part="vertical-drag-state" class="vertical-div vertical-drag">
    <div class="icons-container">
      <nile-icon
        color="var(--nile-colors-blue-500)"
        name="general"
        size="20"
        class="general-icon"
      ></nile-icon>
      <nile-icon
        color="var(--nile-colors-blue-500)"
        name="image"
        size="24"
        class="image-icon"
      ></nile-icon>
    </div>
    <p>${FileUploadDefaults.DRAG_STATE_DEFAULT}</p>
  </div>
`;