<template>
  <div class="is-fullwidth is-fullheight-container p-l-lg p-r-lg">
    <transition name="fade">
      <div class="book-uploading-overlay" v-if="uploading">
        <div class="section book-uploading-overlay-content has-text-centered">
          <h1 class="title">Uploading...</h1>
          <h1 class="subtitle">Be pacient, This can take a while</h1>
          <progress class="progress is-small is-primary" max="100">15%</progress>
        </div>
      </div>
    </transition>
    <div class="columns is-flex is-fullheight-container">
      <div class="column is-3">
        <!-- Properties -->
        <div class="card m-b-md">
          <div class="card-content">
            <h1 class="subtitle">
              <i class="fa fa-book"></i> Properties
            </h1>
            <div class="book-properties">
              <div class="field">
                <label class="label">Book Title:</label>
                <input class="input" type="text" placeholder="My Book" v-model="book.title" />
              </div>
              <div class="field">
                <label class="label">Book Author:</label>
                <input class="input" type="text" placeholder="Savta Cochi" v-model="book.author" />
              </div>
              <div class="field">
                <label class="label">Language Direction:</label>
                <label>
                  <input
                    class="checkbox"
                    type="checkbox"
                    v-model="book.ltr"
                    aria-label="Book direction"
                  />
                  {{book.ltr ? "Left To Right" : "Right To Left"}}
                  <i
                    :class="`fa fa-fw fa-arrow-${book.ltr?'right':'left'}`"
                  ></i>
                </label>
              </div>
              <div class="field">
                <label class="label">Total page count: #{{pages.length}}</label>
              </div>
            </div>
          </div>
          <footer class="card-footer">
            <a class="card-footer-item is-success" @click="onUploadClicked()">
              <i class="fa fa-fw fa-upload"></i> Upload Book
            </a>
          </footer>
        </div>
        <!-- Pages -->
        <div class="card">
          <aside class="menu card-content">
            <p class="menu-label">Pages</p>
            <ul class="menu-list">
              <li v-for="page in pages" :key="page.id">
                <a
                  :class="{'is-active' : currentPage === page.id}"
                  @click="onPageClicked(page.id)"
                >{{page.text}}</a>
              </li>
            </ul>
          </aside>
          <footer class="card-footer">
            <a class="card-footer-item" @click="onAddPageClicked()">
              <i class="fa fa-fw fa-plus"></i> Add Page
            </a>
          </footer>
        </div>
      </div>
      <div class="column is-9">
        <div class="card is-fullheight-container bg-flower height-max-view">
          <div class="card-content is-fullheight-container">
            <div class="tabs-container has-text-centered m-b-lg">
              <div class="tabs is-centered">
                <ul>
                  <li :class="editMode ? 'is-active' : ''" @click="editMode=true">
                    <a>
                      <span class="icon is-small">
                        <i class="fa fa-pencil" aria-hidden="true"></i>
                      </span>
                      <span>Edit</span>
                    </a>
                  </li>
                  <li :class="!editMode ? 'is-active' : ''" @click="onEditClicked()">
                    <a>
                      <span class="icon is-small">
                        <i class="fa fa-eye" aria-hidden="true"></i>
                      </span>
                      <span>Preview</span>
                    </a>
                  </li>
                </ul>
              </div>
            </div>
            <div class="content is-fullheight-container">
              <!-- Book Edit -->
              <transition name="fade">
                <div class="edit" v-if="editMode">
                  <div class="has-text-centered" v-if="currentPage < -1">
                    <h1 class="subtitle m-t-xl m-b-xl">This is exciting...</h1>
                    <div class="has-text-left">
                      <p>Here will be some more instructions in the future...</p>
                      <p>Also maybe some gifs fo help...</p>
                      <ul>
                        <li>Add a title and author for the book</li>
                        <li>Add first image (Cover of the book)</li>
                        <li>Try to fit the image as close as possible to edges of the "page"</li>
                        <li>You can modify the width/height while editing the cover</li>
                        <li>You can always zoom in/out and drag the image to make it fit better</li>
                        <li>Please click on preview to actualy see how the book will look like before uploading</li>
                        <li>Once all done. Click on "Upload Book"</li>
                      </ul>
                    </div>
                    <a class="button is-large is-rounded" @click="onAddPageClicked()">
                      <i class="fa fa-fw fa-plus"></i> Add Cover
                    </a>
                  </div>
                  <div class="page-editor" v-else>
                    <div class="columns">
                      <!-- Croppa -->
                      <div class="column has-text-centered">
                        <div v-if="pages[currentPage].loaded">
                          <h1 class="subtitle is-3">{{pages[currentPage].text}}</h1>
                          <div class="is-relative is-flex is-justify-centered">
                            <div
                              class="stitch-preview-left is-relative"
                              v-if="currentPage != 0 && currentPage % 2 === 0 && book.ltr"
                              :style="`width:${croppaWidth}px;height:${croppaHeight}px;`"
                            >
                              <img :src="pages[currentPage-1].image" alt />
                            </div>
                            <croppa
                              v-model="pages[currentPage].croppa"
                              :prevent-white-space="false"
                              :show-remove-button="false"
                              :accept="'image/*'"
                              :initial-image="pages[currentPage].image"
                              :width="croppaWidth"
                              :height="croppaHeight"
                              :disable-drag-to-move="false"
                              :disable-scroll-to-zoom="true"
                              :zoom-speed="1"
                              canvas-color="white"
                              @loading-end="onCroppaImageLoaded()"
                            ></croppa>
                            <div
                              class="stitch-preview-right is-relative"
                              v-if="currentPage != 0 && currentPage % 2 === 0 && !book.ltr"
                              :style="`width:${croppaWidth}px;height:${croppaHeight}px;`"
                            >
                              <img :src="pages[currentPage-1].image" alt />
                            </div>
                          </div>
                        </div>
                      </div>
                      <!-- Controllers -->
                      <div
                        class="edit-page-controllers column is-3 is-flex-column is-justify-centered has-text-centered"
                      >
                        <div class="field" v-if="currentPage===0 && pages.length===1">
                          <label class="label">Page width</label>
                          <input
                            type="range"
                            :min="DEFAULT_PAGE_WIDTH-100"
                            :max="DEFAULT_PAGE_WIDTH"
                            v-model="bookWidth"
                            :disabled="!pages[currentPage].imageLoaded"
                          />
                          <div class="is-flex is-justify-between">
                            <button
                              type="button"
                              class="button is-rounded is-outlined is-small"
                              :disabled="!pages[currentPage].imageLoaded || bookWidth<= DEFAULT_PAGE_WIDTH - 100"
                              @click="bookWidth-=2"
                            >
                              <i class="fa fa-fw fa-minus"></i>
                            </button>
                            <button
                              type="button"
                              class="button is-rounded is-outlined is-small"
                              :disabled="!pages[currentPage].imageLoaded || bookWidth >= DEFAULT_PAGE_WIDTH"
                              @click="bookWidth+=2"
                            >
                              <i class="fa fa-fw fa-plus"></i>
                            </button>
                          </div>
                        </div>
                        <div class="prev-page-preview" v-else>
                          <div
                            class="is-flex is-justify-centered"
                            v-if="pages[currentPage - 1] && pages[currentPage - 1].base64"
                          >
                            <div class="book-thumb page-preview">
                              <div class="book-text">
                                <div>Previouse Page</div>
                              </div>
                              <div class="book-cover">
                                <img
                                  :src="pages[currentPage - 1] ? pages[currentPage - 1].base64: ''"
                                />
                              </div>
                              <div class="book-text">
                                <div>{{pages[currentPage - 1].text}}</div>
                              </div>
                            </div>
                          </div>
                        </div>
                        <hr class="is-fullwidth-container" />
                        <div class="field" v-if="currentPage===0 && pages.length===1">
                          <label class="label">Page height</label>
                          <input
                            type="range"
                            :min="DEFAULT_PAGE_HEIGHT-50"
                            :max="DEFAULT_PAGE_HEIGHT"
                            v-model="bookHeight"
                            :disabled="!pages[currentPage].imageLoaded"
                          />
                          <div class="is-flex is-justify-between">
                            <button
                              type="button"
                              class="button is-rounded is-outlined is-small"
                              :disabled="!pages[currentPage].imageLoaded || bookWidth<= DEFAULT_PAGE_HEIGHT - 50"
                              @click="bookHeight-=2"
                            >
                              <i class="fa fa-fw fa-minus"></i>
                            </button>
                            <button
                              type="button"
                              class="button is-rounded is-outlined is-small"
                              :disabled="!pages[currentPage].imageLoaded || bookWidth >= DEFAULT_PAGE_HEIGHT"
                              @click="bookHeight+=2"
                            >
                              <i class="fa fa-fw fa-plus"></i>
                            </button>
                          </div>
                        </div>
                        <div class="field"></div>
                        <div class="field">
                          <label class="label">Zoom Image</label>
                          <input
                            type="range"
                            min="0"
                            max="1000"
                            v-model="pageZoom"
                            :disabled="!pages[currentPage].imageLoaded"
                          />
                          <div class="is-flex is-justify-between">
                            <button
                              type="button"
                              class="button is-rounded is-outlined is-small"
                              :disabled="!pages[currentPage].imageLoaded"
                              @click="pageZoom-=2"
                            >
                              <i class="fa fa-fw fa-minus"></i>
                            </button>
                            <button
                              type="button"
                              class="button is-rounded is-outlined is-small"
                              :disabled="!pages[currentPage].imageLoaded"
                              @click="pageZoom+=2"
                            >
                              <i class="fa fa-fw fa-plus"></i>
                            </button>
                          </div>
                        </div>
                        <div class="rotations is-flex is-justify-between m-b-lg">
                          <button
                            class="button"
                            @click="onRotateClicked(false)"
                            :disabled="!pages[currentPage].imageLoaded"
                          >
                            <i class="fa fa-fw fa-rotate-left"></i>
                          </button>
                          <button
                            class="button"
                            @click="onRotateClicked(true)"
                            :disabled="!pages[currentPage].imageLoaded"
                          >
                            <i class="fa fa-fw fa-rotate-right"></i>
                          </button>
                        </div>
                        <div class="change-image">
                          <button
                            class="button is-fullwidth-container"
                            @click="pages[currentPage].croppa.chooseFile()"
                          >
                            <i class="fa fa-fw fa-refresh"></i> Change Image
                          </button>
                        </div>
                        <div class="remove-image" v-if="currentPage === pages.length-1">
                          <button
                            class="button is-danger is-fullwidth-container"
                            @click="deleteLastPage()"
                          >
                            <i class="fa fa-fw fa-trash"></i> Delete Page
                          </button>
                        </div>

                        <!-- TODO: Fix this shit - maybe fork the project? -->
                        <!-- <div class="field">
                          <label class="label">Rotate Image</label>
                          <input
                            type="range"
                            min="-180"
                            max="180"
                            v-model="pageRotation"
                            :disabled="!pages[currentPage].croppa.hasImage"
                          />
                        </div>-->
                      </div>
                    </div>
                  </div>
                </div>
              </transition>
              <!-- Book Preview -->
              <transition name="fade">
                <div
                  :class="`is-fullheight-container ${flipbookRef ? '' : 'is-transparent'}`"
                  v-if="!editMode"
                >
                  <div class="book-view m-sm m-r-md">
                    <div
                      class="go-left m-r-sm"
                      style="display: inline-block; align-items: center; position: absolute; left:0px; top:0px"
                    >
                      <button
                        class="button book-flip-buttons"
                        :disabled="!canFlipLeft"
                        @click="onLeftClicked()"
                      >
                        <i class="fa fa-fw fa-arrow-left"></i>
                      </button>
                    </div>
                    <flipbook
                      class="flipbook"
                      :pages="previewPages"
                      :forwardDirection="book.ltr ? 'right':  'left'"
                      :zooms="null"
                      :enabled="true"
                      ref="flipbook"
                      v-slot="flipbook"
                      @on-mounted="bookMounted()"
                    >
                      <div class="page-progress has-text-centered m-b-none">
                        <p>Page {{ flipbook.page }} of {{ flipbook.numPages }}</p>
                      </div>
                    </flipbook>
                    <div
                      class="go-right m-l-sm"
                      style="display: inline-block; align-items: center; position: absolute; right:0px; top:0px"
                    >
                      <button
                        class="button book-flip-buttons"
                        :disabled="!canFlipRight"
                        @click="onRightClicked()"
                      >
                        <i class="fa fa-fw fa-arrow-right"></i>
                      </button>
                    </div>
                  </div>
                </div>
              </transition>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { mapGetters, mapActions } from "vuex";
import Flipbook from "../components/flipbook/flipbook.cjs.js";
import Croppa from "vue-croppa";
import Services from "../../services";

const DEFAULT_PAGE_WIDTH = 350;
const DEFAULT_PAGE_HEIGHT = 350;

const DEFAULT_ZOOM = 500;
const MIME_TYPE = "image/jpeg";
const COMPRESSION_RATE = 0.4;
export default {
  name: "EditBook",
  props: ["editBook"],
  components: {
    Flipbook,
    Croppa: Croppa.component
  },
  watch: {
    editMode: function(newVal) {
      if (!newVal) {
        this.currentPage = -7;
        //Update previewPages
        this.previewPages = [null, ...this.pages.map(page => page.image)];
      } else {
        if (this.currentPage < 0 && this.pages.length) this.currentPage = 0;
        this.flipbookRef = false;
      }
    },
    currentPage: async function(currentPage, lastPage) {
      /// Save progress on latest page
      console.log(lastPage, currentPage);
      if (this.pages[lastPage] && lastPage >= 0) {
        const imageBlob = await this.pages[lastPage].croppa.promisedBlob(
          MIME_TYPE,
          COMPRESSION_RATE
        );
        if (imageBlob) {
          let url = URL.createObjectURL(imageBlob);
          this.pages[lastPage].base64 = this.pages[
            lastPage
          ].croppa.generateDataUrl(MIME_TYPE, COMPRESSION_RATE);
          this.pages[lastPage].image = url;
        }
      }
      if (currentPage >= 0) {
        // Load new page croppa
        this.pages[currentPage].loaded = false;
        this.$nextTick(function() {
          console.log("tick");
          this.pages[currentPage].loaded = true;
        });
      }
      this.pageRotation = 0;
      this.pageZoom = DEFAULT_ZOOM;
      return true;
    },
    pageRotation: function(newAngle) {
      console.log(newAngle);
      const page = this.pages[this.currentPage];
      const canvas: HTMLCanvasElement = page.croppa.getCanvas();
      const ctx: CanvasRenderingContext2D = page.croppa.getContext();
      ctx.rotate((newAngle * Math.PI) / 180);
      ctx.drawImage(canvas, 0, 0);
      ctx.setTransform(1, 0, 0, 1, 0, 0);
      this.$nextTick(function() {
        // page.croppa.moveDownwards(1);
      });
      // page.croppa.rotate(newAngle / 90);
    },
    pageZoom: function(newVal, oldVal) {
      const page = this.pages[this.currentPage];
      console.log(newVal, oldVal);
      const delta = Math.abs(newVal - oldVal);
      if (newVal < oldVal) {
        //zoomOut
        for (let i = delta; i > 0; i--) page.croppa.zoomOut();
      } else {
        //zoomIn
        for (let i = delta; i > 0; i--) page.croppa.zoomIn();
      }
    }
  },
  created() {
    if (this.editBook) this.book = this.editBook;
    else
      this.book = {
        name: "",
        ltr: true,
        pages: 0,
        user_id: this.user.id
      };
  },
  methods: {
    ...mapActions(["notify", "getUser"]),
    ///
    deleteLastPage() {
      this.pages.pop();

      if (!this.pages.length) this.currentPage = -7;
      else this.currentPage = this.pages.length - 1;
    },
    onRotateClicked(clockwise: boolean) {
      const page = this.pages[this.currentPage];
      page.croppa.rotate(clockwise ? 1 : -1);
    },
    onPageClicked(pageIndex) {
      this.currentPage = pageIndex;
      this.editMode = true;
    },
    onCroppaImageLoaded() {
      this.pages[this.currentPage].imageLoaded = true;
    },
    async promiseAllProgress(
      promises: Promise<any>[],
      callback: (done: number, total: number) => void
    ): Promise<any> {
      let counter = 0;
      callback(counter, promises.length);
      for (let i = 0; i < promises.length; i++) {
        const promise = promises[i];
        promise.then(async val => {
          counter++;
          callback(counter, promises.length);
          return val;
        });
      }
      return Promise.all(promises);
    },
    async onUploadClicked() {
      //TODO: Better validations
      if (!this.book.title || !this.book.title.length) {
        this.notify({
          message: "Book needs a title!",
          level: "warning"
        });
        return;
      }
      if (!this.book.author || !this.book.author.length) {
        this.notify({
          message: "Book sure has an author!",
          level: "warning"
        });
        return;
      }
      if (this.pages.length < 4) {
        this.notify({
          message: "A book need to have at least 4 pages",
          level: "warning"
        });
        return;
      }
      if (!this.pages[this.pages.length - 1].base64) {
        this.notify({
          message: "You last page is empty. Delete or update",
          level: "warning"
        });
        return;
      }
      this.uploading = true;
      try {
        const resp = await Services.ApiService.uploadBook({
          title: this.book.title,
          author: this.book.author,
          ltr: this.book.ltr,
          pages: this.pages.map(
            p =>
              p.base64 || p.croppa.generateDataUrl(MIME_TYPE, COMPRESSION_RATE)
          )
        });
        if (resp.code === 0) {
          this.notify({
            message: `Woop Woop!! ${this.book.title} has been added!`,
            level: "success"
          });
          this.getUser();
          this.$router.replace({ path: `/` });
        } else {
          this.notify({
            message: `Something went wrong!`,
            level: "danger"
          });
        }
      } catch (e) {
        console.log(`Error... ${e.message}`);
      }
      this.uploading = false;
    },
    async onEditClicked() {
      const lastPage = this.currentPage;
      if (lastPage >= 0) {
        const imageBlob = await this.pages[lastPage].croppa.promisedBlob(
          MIME_TYPE,
          COMPRESSION_RATE
        );
        if (!imageBlob) {
          this.notify({
            message: "Cant have an empty page.",
            level: "warning"
          });
          this.currentPage = lastPage;
          return;
        }
        let url = URL.createObjectURL(imageBlob);
        this.pages[lastPage].base64 = this.pages[
          lastPage
        ].croppa.generateDataUrl(MIME_TYPE, COMPRESSION_RATE);
        this.pages[lastPage].image = url;
        this.currentPage = -7;
        this.editMode = false;
      } else {
        this.notify({
          message: `Please add pages before preview`,
          level: "warning"
        });
      }
    },
    async onAddPageClicked() {
      const lastPage = this.pages.length - 1;
      if (lastPage < 0) {
        this.pages.push({
          text: "Cover",
          id: 0,
          loaded: false,
          croppa: {},
          image: null,
          imageLoaded: false,
          base64: null
        });
        this.currentPage = 0;
        //return;
      } else {
        console.log("In else");
        const nextPage = lastPage + 1;
        const imageBlob = await this.pages[lastPage].croppa.promisedBlob(
          MIME_TYPE,
          COMPRESSION_RATE
        );
        if (!imageBlob) {
          this.notify({
            message: "Your last page is still empty",
            level: "warning"
          });
          this.currentPage = lastPage;
          return;
        }
        this.editMode = true;
        let url = URL.createObjectURL(imageBlob);
        this.pages[lastPage].base64 = this.pages[
          lastPage
        ].croppa.generateDataUrl(MIME_TYPE, COMPRESSION_RATE);
        this.pages[lastPage].image = url;
        this.pages.push({
          text: `Page ${nextPage}`,
          id: nextPage,
          loaded: false,
          croppa: {},
          image: null,
          imageLoaded: false,
          base64: null
        });
        this.currentPage = nextPage;
      }
    },
    bookMounted() {
      if (this.$refs.flipbook) {
        console.log("Found!");
        this.flipbookRef = true;
        // this.$refs.flipbook.onResize();
        // console.log("resized");
      } else {
        console.log("Still Null!!");
      }
    },
    onLeftClicked() {
      console.time("Flip Left");
      this.$refs.flipbook.flipLeft();
      console.timeEnd("Flip Left");
      return true;
    },
    onRightClicked() {
      this.$refs.flipbook.flipRight();
      return true;
    }
  },
  computed: {
    ...mapGetters(["user"]),
    //
    bookPages() {
      return this.pages.slice(1);
    },
    croppaClass() {
      if (this.currentPage != 0 && this.currentPage % 2 == 0) {
        return `book-stitch-preview-${this.book.ltr ? "left" : "right"}`;
      }
      return true;
    },
    canFlipLeft() {
      return this.flipbookRef && this.$refs.flipbook.canFlipLeft;
    },
    canFlipRight() {
      return this.flipbookRef && this.$refs.flipbook.canFlipRight;
    },
    croppaWidth() {
      return Number(this.bookWidth);
    },
    croppaHeight() {
      return Number(this.bookHeight);
    }
  },
  data() {
    return {
      book: {
        title: "",
        author: "",
        rtl: true
      },
      pages: [],
      bookWidth: DEFAULT_PAGE_WIDTH,
      bookHeight: DEFAULT_PAGE_HEIGHT,
      previewPages: [],
      editMode: true,
      currentPage: -7,
      flipbookRef: false,
      pageRotation: 0,
      pageZoom: DEFAULT_ZOOM,
      uploading: false,
      errors: {},
      DEFAULT_PAGE_WIDTH,
      DEFAULT_PAGE_HEIGHT
    };
  }
};
</script>
