<script>
import Dropzone from './dropzone.html';
import ScrollPane from './scroll-pane.html';
import File from './file.html';
import Service from './service.html'; // actually imports services/uploads.js

// Third party libraries imports
import * as tus from 'tus-js-client';

const parseType = type => type.indexOf('/') > 0 ? type.slice(0, type.indexOf('/')) : type;

let instanceId = 0;

export default {
  components: { ScrollPane, Dropzone, File, Service },

  data() {
    return {
      instanceId: ++instanceId,
      loading: true,
      error: null,
      files: [],
      dragging: false,
      filetypes: '*',
      deleteMode: false,
      selected: [],
      selectedForDeletion: [],
      allowDelete: true,
      allowClear: true,
      uploadProgress: 0, // Upload Progress percentage
    };
  },

  helpers: {
    isSelected(id, deleteMode, selected, selectedForDeletion) {
      return deleteMode
        ? selectedForDeletion.includes(id)
        : selected.includes(id);
    },
  },

  oncreate() {
    // create a reference to the Uploads service
    this.Uploads = this.refs.Uploads.instance();

    // read the max file size from the Uploads service
    this.set({ maxFilesize: this.Uploads.getMaxFileSize() });

    // read the chunkSize from the Uploads service
    this.set({ chunkSize: this.Uploads.getChunkSize() });
    
    // load uploaded files
    this.refresh();

    // scroll to uploads files list to bottom
    this.scrollToListBottom();
  },
  ondestroy() {
    this.observer.cancel();
  },

  methods: {

    /**
     * CONTENT LIST HANDLERS
     */

    // on selecting a file square
    toggle(file) {
      // console.log("on toggle file:", file);

      if (file.error) {
        this.Uploads.remove(file);
        return this.refresh();
      }

      this.get('deleteMode')
        ? this._toggleDelete(file)
        : this._toggleSelect(file);
    },

    activate() {
      if (!this.refs.scrollPane) return;

      // update the scroll pane
      this.refs.scrollPane.update();

      // scroll to the bottom
      this.scrollToListBottom();
    },

    refresh(ev) {
      // console.log("refreshing...");
      if (ev) ev.preventDefault();

      return this.Uploads.getFiles(this.get('filetypes'))
        .then(files => {
          // console.log("uploadedFiles: ", files);

          // sort files by id
          // files = files.sort((a, b) => {
          //   // console.log("a & b: ", a.id, b.id);
          //   if(!a.id.indexOf) return -1;
          //   let noIdA = a.id.substr(a.id.indexOf('_t')+2, 4);
          //   let noIdB = b.id.substr(a.id.indexOf('_t')+2, 4);
          //   // console.log("noIdA & noIdB: ", noIdA, noIdB, (noIdA - noIdB));
          //   return noIdA - noIdB;
          // });
          // console.log("uploadedFiles before sort: ", files);

          // sort files by last modified(uploadTime) date
          files = files.sort((a, b) => {

            //  read a lastModified timestamp
            let x = a.lastModified;

            // read the lastModified date from the id
            if(!x && a.id) {
              let indexOft = a.id.indexOf('_u');
              if(indexOft) x = a.id.substring(indexOft+3);
            }

            // if still not available then set it to 0
            if(!x) x = 0;
            // a.lastModified = x;


            // read b lastModified timestamp
            let y = b.lastModified;

            // read the lastModified date from the id
            if(!y && b.id) {
              let indexOft = b.id.indexOf('_u');
              if(indexOft) y = b.id.substring(indexOft+3);
            }

            // if still not available then set it to 0
            if(!y) y = 0;
            // b.lastModified = y;


            // console.log("x & y: ", a.lastModified, x, b.lastModified, y);

            return x - y; 
          });
          // console.log("uploadedFiles after sort: ", files);

          return this.set({ files })
        })
        .then(this.activate.bind(this))
        .catch(this._reportError.bind(this))
        .then(_ => {
          // hide loading spinner
          this.set({ loading: false, error: null })

          // scroll to uploads files list to bottom
          this.scrollToListBottom();
        });
    },

    deleteSelected() {
      const selected = this.get('selected');
      this.get('selectedForDeletion').forEach(id => {
        const file = this.Uploads.get(id);
        if (selected.includes(id)) this._toggleSelect(file);
        this.Uploads.remove(file);
      });
      this.set({ deleteMode: false, selectedForDeletion: [] });
    },

    /*** options { afterUpload: boolean } */
    _toggleSelect(file, options) {
      this.fire('toggle', { file, options });
    },

    _toggleDelete(file) {
      let selectedForDeletion = this.get('selectedForDeletion');

      if (selectedForDeletion.includes(file.id)) {
        selectedForDeletion = selectedForDeletion.filter(id => id !== file.id);
      } else {
        selectedForDeletion.push(file.id);
      }

      this.set({ selectedForDeletion });
    },

    _reportError(error) {
      let processedError = error;

      if (typeof error === 'string') {
        processedError = { message: error };
      }

      if (error.jqXHR) {
        processedError = {
          message: `${error.jqXHR.statusText} (${error.jqXHR.responseText})`,
        };
      }

      console.error(error);
      this.set({ error: processedError });
      this.fire('error', processedError);
    },

    /**
     * UPLOAD DROPZONE HANDLERS
     */

    _onDropZoneUploadStart(event) {
      // console.log("Editor Dropzone onUploadStart:", event);

      // scroll the list to the bottom 
      this.scrollToListBottom();
    },
    
    // scroll to uploads files list to bottom
    scrollToListBottom() {
      // console.log("on DropZone New Upload:", event);
      this.refs.scrollPane && this.refs.scrollPane.scrollBottom();
    },

    _onDropZoneUploadToggle(event) {
      console.log("Editor DropZone Upload Toggle:", event);

      this.toggle( event );
    },

    /**
     * UPLOAD SERVICE HANDLERS
     */

    _onUploadsUpdate(event) {
      // console.log("Editor Upload Service onUploadsUpdate:", event);

      // refresh uploaded files list
      this.refresh();
    },

    _onUploadComplete([file, instanceId]) {
      // console.log("Editor Upload Service Complete:", file, instanceId);

      // toggle the file only if it's upload originated from this instance
      if (instanceId === this.get('instanceId')) this._toggleSelect(file, { afterUpload: true });

      // reload list of files
      // this.refresh();
    },
  },
};
</script>


<Service ref:Uploads
  service="Uploads"
  on:update="_onUploadsUpdate(event)"
  on:complete="_onUploadComplete(event)"
  />

<svg style="position: absolute; width: 0; height: 0; overflow: hidden" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <symbol id="icon-upload" viewBox="0 0 32 32">
    <title>upload</title>
    <path d="M30.038 19.938c-0.706 0-1.275 0.569-1.275 1.275v7.544h-25.525v-7.544c0-0.706-0.569-1.275-1.275-1.275s-1.275 0.569-1.275 1.275v8.825c0 0.706 0.569 1.275 1.275 1.275h28.075c0.706 0 1.275-0.569 1.275-1.275v-8.825c0-0.706-0.569-1.275-1.275-1.275z"></path>
    <path d="M9.137 10.625l5.588-5.581v16.194c0 0.706 0.569 1.275 1.275 1.275s1.275-0.569 1.275-1.275v-16.194l5.587 5.581c0.769 0.713 1.556 0.25 1.806 0 0.5-0.5 0.5-1.306 0-1.806l-7.769-7.756c-0.5-0.5-1.306-0.5-1.806 0l-7.756 7.756c-0.5 0.5-0.5 1.306 0 1.806 0.494 0.5 1.306 0.5 1.8 0z"></path>
  </symbol>
  <symbol id="icon-error" viewBox="0 0 21.9 21.9">
    <title>error</title>
    <path d="M14.1 11.3c-.2-.2-.2-.5 0-.7l7.5-7.5c.2-.2.3-.5.3-.7s-.1-.5-.3-.7L20.2.3c-.2-.2-.5-.3-.7-.3-.3 0-.5.1-.7.3l-7.5 7.5c-.2.2-.5.2-.7 0L3.1.3C2.9.1 2.6 0 2.4 0s-.5.1-.7.3L.3 1.7c-.2.2-.3.5-.3.7s.1.5.3.7l7.5 7.5c.2.2.2.5 0 .7L.3 18.8c-.2.2-.3.5-.3.7s.1.5.3.7l1.4 1.4c.2.2.5.3.7.3s.5-.1.7-.3l7.5-7.5c.2-.2.5-.2.7 0l7.5 7.5c.2.2.5.3.7.3s.5-.1.7-.3l1.4-1.4c.2-.2.3-.5.3-.7s-.1-.5-.3-.7l-7.5-7.5z" fill="#de2618"/>
  </symbol>
</svg>

{{#if !loading}}
  {{#if error}}
    <div class="error-panel">
      <h2 class="blogvio-browser-title">Failed to load uploaded files.</h2>
      <p>{{ error.message }}</p>
      <a href="#" on:click="refresh( event )">Click here to try again</a><br/>
      <span>or <a href="mailto:support@widgetic.com">contact support</a> if the error persists.</span>
    </div>
  {{else}}
    <div class="browser-nav">
      {{#if deleteMode}}
        <div class="browser-logout" data-tooltip-text="Permanently remove selected files from server (action cannot be undone)" data-tooltip-position="80% 3%" data-icon="✓" on:click="deleteSelected()"></div>
        <div class="browser-logout" data-tooltip-text="Cancel action" data-icon="x" on:click="set({ deleteMode: false, selectedForDeletion: [] })"></div>
        {{#if selectedForDeletion.length}}
          <span>{{selectedForDeletion.length}} files selected for removal</span>
        {{else}}
          <span>Select files to be removed from the server</span>
        {{/if}}
      {{else}}
        {{#if allowDelete}}
          <div class="browser-logout" data-tooltip-text="Permanently remove files from server" data-tooltip-position="80% 3%" data-icon="⏍" on:click="set({ deleteMode: true })"></div>
        {{/if}}
        {{#if allowClear}}
          <div class="browser-logout clear-content" data-tooltip-text="Clear Content" on:click="fire('clearContent')"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M490.667 85.333h-64v-64C426.667 9.551 417.115 0 405.333 0h-384C9.551 0 0 9.551 0 21.333V448c0 11.782 9.551 21.333 21.333 21.333h64v21.333c0 11.782 9.551 21.333 21.333 21.333h384c11.782 0 21.333-9.551 21.333-21.333v-384c.001-11.781-9.55-21.333-21.332-21.333zm-448 341.334v-384H384v42.667H106.667c-11.782 0-21.333 9.551-21.333 21.333v320H42.667zm426.666 42.666H128V128h341.333v341.333z"/><path d="M389.176 208.158c-8.331-8.331-21.839-8.331-30.17 0l-60.339 60.339-60.339-60.339c-8.331-8.331-21.839-8.331-30.17 0s-8.331 21.839 0 30.17l60.339 60.339-60.339 60.339c-8.331 8.331-8.331 21.839 0 30.17s21.839 8.331 30.17 0l60.339-60.339 60.339 60.339c8.331 8.331 21.839 8.331 30.17 0s8.331-21.839 0-30.17l-60.339-60.339 60.339-60.339c8.331-8.332 8.331-21.839 0-30.17z"/></svg></div>
        {{/if}}
      {{/if}}
    </div>
    <section class="{{ dragging ? 'dropzone--dragging' : '' }}">
      
      <!-- Uploaded Content List -->
      {{#if files.length}}
        <ScrollPane ref:scrollPane class="content-list">
          {{#each files as file}}
            <File
              file="{{file}}"
              on:select="toggle( event )"
              selected="{{ isSelected(file.id, deleteMode, selected, selectedForDeletion) }}"
              selectedIcon="{{ deleteMode ? 'delete' : 'check' }}">
            </File>
          {{/each}}
        </ScrollPane>
      {{else}}
        <div class="error-panel" style="height: 100%">
          <h2 class="blogvio-browser-title">Hey there!</h2>
          <h3>You haven't uploaded any {{ filetypes }} files yet.</h3>
          <span>Drag some over or click below!</span>
        </div>
      {{/if}}


      <!-- Dropzone Holder -->
      <div class="dropzone_plchldr {{ !files.length ? 'dropzone--large' : '' }}">

        <!-- Dropzone Component  -->
        <Dropzone
          ref:dropzone
          on:new="_onDropZoneUploadStart(event)"
          on:upload="_onDropZoneUploadToggle( event )"
          on:dragging="set({ dragging: event })"
          on:error="fire( 'error', event )"
          filetypes="{{ filetypes }}/*"
          maxFilesize="{{ maxFilesize }}"
          chunkSize="{{ chunkSize }}"
          instanceId="{{ instanceId }}"
          ></Dropzone>   
          
      </div>
      

    </section>
  {{/if}}
{{/if}}

<style>
  section {
    display: flex;
    flex-direction: column;
    padding-left: 20px;
    height: calc(100% - 25px);
    color: #665b68;
  }

  a:focus {
    outline: none;
  }

  .error-panel {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    padding-right: 20px;
  }

  .browser-nav {
    position: static;

    font-family: ProximaNova-Regular;
    font-size: 16px;
    color: #0055FF;
  }

  .blogvio-browser-title {
    margin-top: 0;
    font: 30px/60px "ProximaNova-Regular";
    color: #0055FF;
  }

  .nano {
    flex: 1;
  }

  strong {
    color: #0055FF;
  }

  .dropzone_plchldr {
    position: relative;
    margin: 20px 20px 20px 0;
    height: 75px;
  }

  .dropzone {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 22px;
  }
  .upload-input {
    
  }

  .scrolling-container {
    transition: opacity 200ms ease-in;
  }

  .dropzone--dragging .scrolling-container {
    opacity: 0.4;
  }

  .dropzone--dragging .dropzone {
    top: -100px;
  }

  .dropzone--large .dropzone,
  .dropzone--dragging .dropzone--large .dropzone {
    top: -200px;
  }

  .icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    stroke-width: 0;
    stroke: currentColor;
    fill: currentColor
  }

  .clear-content svg {
    width: 14px;
    fill: #a0a0a0;
    position: relative;
    top: 1px;
    right: 2px;
  }

  .clear-content:hover svg {
    fill: #665b68;
  }
</style>