import * as React from "react";

import { FileService, CachingService } from "../../Services";
import { File } from "../../Models";
import FineUploaderTraditional from "fine-uploader-wrappers";
//import Gallery from "react-fine-uploader";
import FileInput from "react-fine-uploader/file-input";
import Thumbnail from "react-fine-uploader/thumbnail";
import ProgressBar from "react-fine-uploader/progress-bar";
import CancelButton from "react-fine-uploader/cancel-button";
import DeleteButton from "react-fine-uploader/delete-button";
import Filename from "react-fine-uploader/filename";
import Status from "react-fine-uploader/status";
import "react-fine-uploader/gallery/gallery.css";
import { Panel, PanelType, Icon, PrimaryButton, IconButton } from "office-ui-fabric-react";

import "./index.css";
import PdfThumbnail from "../PdfThumbnail";
import { FormattedMessage } from "react-intl";
import UploaderCallout from "../UploaderCallOut/UploaderCallout";
import { LoadingService } from "../../Services/LoadingService";
// import { Document, Page } from 'react-pdf';
import ReactPaginate from "react-paginate";
//import { FormattedMessage } from 'react-intl';

class SubmittedFile {
  id: number = 0;
  internalId: number = 0;
  path: string = "";
  name: string = "";
  contentType: string = "";
  file: File = new File();
}


export class MultipleFileUpload extends React.Component<any, any> {
  private _loadingService = new LoadingService();
  private _submittedFiles = new Array<SubmittedFile>();
  private _fileService: FileService = new FileService();
  private _cachingService: CachingService = new CachingService();
  private uploader: any;
  // private _cachingService = new CachingService();
  constructor(props: any) {
    super(props);

    this.state = {
      showPreview: false,
      numPages: 1,
      pageNumber: 1,
      showPanel: false,
      pdf: "sample.pdf",
      type: "",
      pdfThumbnails: [],
      showProgress: false
    };
    this.uploader = new FineUploaderTraditional({
      options: {
        chunking: {
          enabled: false
        },
        deleteFile: {
          enabled: true,
          method: "POST"
        },
        request: {
          enabled: true,
          requireSuccessJson: false
        },
      }
    });
    if (this.props.initialFiles) {
      this._submittedFiles = this.props.initialFiles.map(
        (initialFile: File) => {
          let _file = new SubmittedFile();
          _file.id = initialFile.id;
          _file.path = initialFile.path;
          _file.name = initialFile.name;
          _file.contentType = initialFile.contentType;
          _file.file = initialFile;
          return _file;
        }
      );
    }
  }
  componentDidMount() {
    if (this.props.initialFiles) {
      let initialFiles = this.props.initialFiles.map((initialFile: File) => {
        return {
          name: initialFile.name,
          uuid: initialFile.id,
          thumbnailUrl: this._fileService.getFullPath(initialFile),
          deleteFileParams: {
            enabled: true,
            method: "POST"
          }
        };
      });

      this.uploader.methods.addInitialFiles(initialFiles);
    }

    this.uploader.methods.getUploads().forEach((element: any) => {
      let _file = this._getFileById(parseInt(element.uuid));
      if (_file) _file.internalId = element.id;
    });

    //on submit complete , update files list and update field data.
    this.uploader.on(
      "Complete",
      (id: number, name: string, responseJSON: any, xhr: any) => {
        this._handleFileUploadComplete(id, name, responseJSON, xhr);
      }
    );

    //on delete complete , update files list and update field data.
    this.uploader.on(
      "onDeleteComplete",
      (id: number, xhr: any, isError: boolean) => {
        if (!isError) this._handleFileDeleteComplete(id);
      }
    );

    //set delete endpoint for item before delete operation
    this.uploader.on("onSubmitDelete", (id: number) => {
      let _file = this._getFileByInternalId(id);
      if (_file && _file.id > 0)
        this.uploader.methods.setDeleteFileEndpoint(
          this._fileService.getDeleteFileEndpoint(_file.id),
          id
        );
    });

    //set submit endpoint for item before submit operation
    this.uploader.on("onSubmit", (id: number, name: string) => {
      console.log(this._submittedFiles);

      let file_exists;
      file_exists = false;
      this._submittedFiles.forEach((sF: SubmittedFile) => {
        if (sF.name == name)
          file_exists = true;
      })

      if (file_exists == true)
        return false;

      this.setState({ showProgress: true });
      console.log(this.props);
      this.uploader.methods.setEndpoint(
        this._fileService.getUploadFileContentEndpoint(this.props.Record.id), id);

      this.uploader.methods.setCustomHeaders(
        {
          'TenantId': this._cachingService.read('TenantId'),
          'Language': this._cachingService.readPersistant('Language'),
          'Authorization': 'Bearer ' + this._cachingService.read('Token'),
          'UserId': this._cachingService.read('UserId')
        }, id);

      return true;
    });

    this.uploader.on("onCancel", (id: number, name: string) => {
      let _file = this._getFileByInternalId(id);
      if (_file && _file.id > 0) {
        this._submittedFiles.splice(this._submittedFiles.indexOf(_file), 1);

        if (this.props.onChanged) {
          this.props.onChanged(
            this._submittedFiles.map(x => x.id),
            this._submittedFiles.map(x => x.file)
          );
        }
      }

      //uploader.methods.setEndpoint(this._fileService.getUploadFileContentEndpoint(), id)
    });

    this.uploader.on("onTotalProgress", (totalUploadedBytes: number, totalBytes: number) => {
      //debugger;
      let percent = Math.floor(totalUploadedBytes / totalBytes * 100 || 0);
      this.setState({ progressPercent: percent });
    });
    this.uploader.on("onAllComplete", () => {
      this.setState({ showProgress: false });

    });

    // document.querySelector('.react-fine-uploader-gallery-file-input-content > span')!.textContent = this._cachingService.readPersistant('Language') == 0 ? "Select File" : "اختر ملف";
    // document.querySelector('.react-fine-uploader-gallery-dropzone-content')!.textContent = this._cachingService.readPersistant('Language') == 0 ? "Drop files here" : "ضع الملفات هنا";
  }

  _handleFileUploadComplete(
    id: number,
    name: string,
    responseJSON: any,
    xhr: any
  ): void {
    let _file = new SubmittedFile();
    _file.id = responseJSON.id;
    _file.path = responseJSON.path;
    _file.internalId = id;
    _file.contentType = responseJSON.contentType;
    _file.name = name;
    _file.file = responseJSON;
    this._submittedFiles.push(_file);

    if (this.props.onChanged) {
      //debugger;
      this.props.onChanged(
        this._submittedFiles.map(x => x.id),
        this._submittedFiles.map(x => x.file)
      );
    }

    this.forceUpdate();
  }

  _handleFileDeleteComplete(id: number): void {
    let _file = this._getFileByInternalId(id);
    if (_file && _file.id > 0)
      this._submittedFiles.splice(this._submittedFiles.indexOf(_file), 1);

    if (this.props.onChanged) {
      this.props.onChanged(
        this._submittedFiles.map(x => x.id),
        this._submittedFiles.map(x => x.file)
      );
    }
  }

  _getFileByInternalId(id: number): SubmittedFile {
    let _file = new SubmittedFile();
    this._submittedFiles.forEach((val: SubmittedFile, index: number) => {
      if (val.internalId == id) _file = val;
    });

    return _file;
  }

  _getFileById(id: number): SubmittedFile {
    let _file = new SubmittedFile();
    this._submittedFiles.forEach((val: SubmittedFile, index: number) => {
      if (val.id == id) _file = val;
    });

    return _file;
  }

  _getItemBasedOnElement(element: any) {
    let node = element.parentElement.parentElement.parentElement;

    if (!node.parentElement) return;

    let index = Array.prototype.indexOf.call(node.parentNode.childNodes, node);

    let SubmittedFile = this._submittedFiles[index];

    return SubmittedFile;
  }

  //   private makePDFThumb(page: any) {
  //     // draw page to fit into 96x96 canvas
  //     // debugger;
  //     let vp = page.getViewport(1);
  //     let canvas = document.createElement("canvas");
  //     canvas.width = canvas.height = 96;
  //     let scale = Math.min(canvas.width / vp.width, canvas.height / vp.height);

  //     return page
  //       .render({
  //         canvasContext: canvas.getContext("2d"),
  //         viewport: page.getViewport(scale)
  //       })
  //       .promise.then(function() {
  //         return canvas;
  //       });
  //   }

  //   private getPdf(pdf: any): JSX.Element {
  //     let _this = this;
  //     let thumbnail: any;
  //     debugger;
  //     //   let fReader = new FileReader();
  //     //   let newFile;
  //     //   if (pdf && pdf.contentType.match('application/pdf.*')) {
  //     //   fReader.readAsDataURL(pdf);
  //     //     fReader.onloadend = function(event){
  //     //       if(event.target){
  //     //         debugger;
  //     //         newFile = event.target;
  //     //       }
  //     //     }
  //     //   }

  //     if (pdf) {
  //       PDF.getDocument(pdf.path)
  //         .promise.then(function(doc: any) {
  //           debugger;
  //           let pages = [];
  //           while (pages.length < doc.numPages) pages.push(pages.length + 1);
  //           return Promise.all(
  //             pages.map(function(num) {
  //               // create a div for each page and build a small canvas for it
  //               //   let div = document.createElement("div");
  //               return doc
  //                 .getPage(num)
  //                 .then(_this.makePDFThumb)
  //                 .then(function(canvas: any) {
  //                   thumbnail = canvas;
  //                   _this.state.pdfThumbnails.push({
  //                     id: pdf.id,
  //                     canvas: canvas
  //                   });
  //                   _this.setState({ pdfThumbnails: _this.state.pdfThumbnails });
  //                 });
  //             })
  //           );
  //         })
  //         .catch(console.error);
  //     }

  //     return thumbnail;
  //   }

  //  private renderPdfThumnail = (file: any): JSX.Element => {
  //      let canvas;
  //      canvas = this.getPdf(file);
  //     return (
  //         <div children={canvas}></div>
  //         )
  // }
  private _downloadFile(submittedFile: SubmittedFile, uploader: any, ev: any, ...args: any[]) {
    this._loadingService.show();
    ev.preventDefault();
    ev.stopPropagation();

    if (!submittedFile)
      return;

    let file = new File();

    file.path = submittedFile.path;

    let fullPath = this._fileService.getFullPath(file)

    var link = document.createElement("a");
    //link.target = "_blank";
    link.download = 'download';
    link.href = fullPath;
    link.click();

    link.remove();
    this._loadingService.hide();

    return false;
  }

  private _previewFile(submittedFile: SubmittedFile, uploader: any, ev: any, ...args: any[]) {
    //debugger;
    ev.preventDefault();
    ev.stopPropagation();

    if (!submittedFile) {
      return;
    }

    if (submittedFile.contentType.indexOf('pdf') == -1) {
      alert('Preview is only enabled for pdf files.')
      return;
    }
    this.setState({ type: "view" });

    let file = new File();

    file.path = submittedFile.path;

    let fullPath = this._fileService.getFullPath(file);

    this._showPreview(fullPath, submittedFile.name);

    return false;
  }
  // private _editFile(uploader: any, ev: any, ...args: any[]) {
  //     ev.preventDefault();
  //     ev.stopPropagation();

  //     let SubmittedFile = this._getItemBasedOnElement(ev.currentTarget);

  //     if (!SubmittedFile) {
  //         return;
  //     }

  //     if (SubmittedFile.contentType.indexOf('pdf') == -1) {
  //         alert('Preview is only enabled for pdf files.')
  //         return;
  //     }
  //     this.setState({ type: "annot" });

  //     let file = new File();

  //     file.path = SubmittedFile.path;

  //     let fullPath = this._fileService.getFullPath(file);

  //     this._showPreview(fullPath, SubmittedFile.name);

  //     return false;
  // }

  private _showPreview = (selectedDocument: string, selectedDocumentName: string): void => {
    this.setState({ showPanel: true, selectedDocument: selectedDocument, selectedDocumentName: selectedDocumentName });
  };

  onDocumentLoadSuccess = (document: any) => {
    this.setState({ numPages: document.numPages });
  };

  private _hidePanel = (): void => {
    this.setState({ showPanel: false });
  };

  private _onReadnderHader = (item: any): JSX.Element | null => {
    debugger;
    return (
      <div className="ms-Panel-commands" data-is-visible="true">
        <div className="ms-Panel-navigation navigation_1033a520">
          <h2 className="panel-header-text ">
            <Icon iconName="PDF"></Icon>  <FormattedMessage id={item.headerText} />
          </h2>
          <IconButton
            className="ms-Panel-closeButton ms-PanelAction-close custom"
            onClick={item.onDismissed.bind(this)}
            iconProps={{ iconName: "ChromeClose", style: { fontSize: 12 } }}
          />
        </div>
      </div>
      // <div className="panel-header-text "><FormattedMessage id={item.headerText} /></div>
    );
  };

  private _handlePdfPageChange = (data: any): void => {
    this.setState({ pageNumber: data.selected + 1 });
  };

  public render() {
    // const thumbnailChildren = <span>Choose files</span>
    // const additionalButtons =
    //     <div>
    //         <Icon className="fileIcon round" iconName="Cancel"></Icon>
    //         <Icon onClick={this._downloadFile.bind(this, uploader)} className="fileIcon show-when-complete" style={{ position: "absolute", right: 6, top: 28 }} iconName="Download"></Icon>
    //         <Icon onClick={this._previewFile.bind(this, uploader)} className="fileIcon show-when-complete" style={{ position: "absolute", right: 6, top: 56 }} iconName="View"></Icon>
    //         <Icon onClick={this._editFile.bind(this, uploader)} className="fileIcon show-when-complete" style={{ position: "absolute", right: 6, top: 84 }} iconName="edit"></Icon>

    //     </div>;

    // const customDropZone =
    // <div style={ { border: '1px dotted ', height: 200, width: 200 } }>
    //         <span>Drop Files Here 1</span>
    //     </div>

    const deleteBtn = <Icon className="fileIcon round" iconName="Cancel" />;

    return (
      <div>
        <Panel
          isOpen={this.state.showPanel}
          onDismissed={this._hidePanel}
          type={PanelType.medium}
          closeButtonAriaLabel="Close"
          hasCloseButton={false}
          headerText={this.state.selectedDocumentName}
          onRenderHeader={this._onReadnderHader.bind(this)}
          className="document-preview-modal-container"
        >
          {/* <div className="document-preview-modal-header">
            <Icon style={{ float: 'left', marginTop: 0, marginRight: 6 }} iconName="PDF"></Icon>
            <span style={{ float: 'left', marginTop: 0 }}>{this.state.selectedDocumentName}</span>
          </div> */}
          <div id="subtitleId" className="document-preview-modal-body" >
            <div className='document-preview-container' style={{ maxWidth: '100%', overflow: 'hidden' }}>
              {/* <Document className="document-preview"
                style={{ 'maxWidth': '100%' }}
                file={this.state.selectedDocument}

                onLoadSuccess={this.onDocumentLoadSuccess}>
                <Page pageNumber={this.state.pageNumber} width={748} />
              </Document> */}
            </div>
            <ReactPaginate
              previousLabel={'<'}
              nextLabel={'>'}
              breakLabel={'...'}
              breakClassName={'break-me'}
              pageCount={this.state.numPages}
              marginPagesDisplayed={1}
              pageRangeDisplayed={4}
              containerClassName={'office-fabric-pagination document-preview-pagination'}
              onPageChange={this._handlePdfPageChange.bind(this)}
              activeClassName={'active'}
            />
            {/* <p>Page {this.state.pageNumber} of {this.state.numPages}</p> */}
          </div>
        </Panel>

        {/* <Gallery uploader={uploader} fileInput-children={<FormattedMessage id="SelectFiles" />}
                    cancelButton-children={additionalButtons} deleteButton-children={additionalButtons}>
                </Gallery> */}

        {/* <canvas id="thumbnailPreview"></canvas> */}
        <div className="uploader-container">
          <div className="mb-15">
            <FileInput
              multiple={true}
              children={
                <PrimaryButton>
                  <FormattedMessage id="selectFile" />
                </PrimaryButton>
              }
              uploader={this.uploader}
            />
          </div>
          {this.state.showProgress && <div className="mb-15 uploader-progress-container">
            <span className="uploader-progress-label">{this.state.progressPercent} %</span>
            <ProgressBar uploader={this.uploader} />
          </div>}

          <div className="uploader-thumbnail-container">
            {this._submittedFiles.map(file => (
              <div className="uploader-thumbnail" key={file.id}>
                {file.file.contentType == "application/pdf" ? (
                  <div>
                    <PdfThumbnail pdf={file} />
                  </div>
                ) : (
                    file.file.contentType.indexOf("image") > -1 ? (
                      <img style={{ maxWidth: '100%', maxHeight: '100%' }} src={this._fileService.getFullPath(file.file)}></img>) : (
                        <Thumbnail
                          id={file.internalId}
                          uploader={this.uploader}
                        />
                      )
                  )}
                <ProgressBar id={file.internalId} uploader={this.uploader} />
                <Filename id={file.internalId} uploader={this.uploader} />
                <div className='action-btns'>
                  {!this.props.readonly && <CancelButton
                    className={'btn-thumbnail btn-download action-btn'}
                    id={file.internalId}
                    uploader={this.uploader}
                    children={deleteBtn}
                  />}
                  {!this.props.readonly && <DeleteButton
                    className={'btn-thumbnail btn-download action-btn'}
                    id={file.internalId}
                    uploader={this.uploader}
                    children={deleteBtn}
                  />}
                  <button type="button" onClick={this._downloadFile.bind(this, file, this.uploader)}
                    className="btn-thumbnail btn-download action-btn"><Icon className="fileIcon round" iconName="Download" /></button>
                   {file.file.contentType == "application/pdf" && <button type="button" onClick={this._previewFile.bind(this, file, this.uploader)}
                    className="btn-thumbnail btn-view action-btn"><Icon className="fileIcon round" iconName="View" /></button>}
                  <div className="btn-desc action-btn"> <UploaderCallout /></div>
                </div>
                <Status id={file.internalId} uploader={this.uploader} />
              </div>
            ))}
          </div>
        </div>
      </div>
    );
  }
}

export default MultipleFileUpload;
