<style scoped>
.layout {
  height: 100%;
  background: #dddddd;
}

.header {
  background: #dddddd;
}

.ivu-layout-header {
  line-height: normal;
  height: auto;
  padding: 0px;
}

.content {
  background: #dddddd;
}

.ivu-layout-content {
  padding: 0px;
}


.layout-footer-center {
  background: #dddddd;
  text-align: center;
}

.ivu-card-bordered {
  border: 0px solid #dcdee2;
  border-color: #e8eaec;
}

.fnmodal {
  align-items: center;
  justify-content: center;
}

/* button span {
  margin-left: 0px !important;
  font-size: 18px !important;
  font-family: apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,Source Han Sans SC,Noto Sans CJK SC,WenQuanYi Micro Hei,sans-serif;
  margin-bottom: 6px;
} */



@media print {

  @page {
    size: portrait;
    margin: 20px;
  }

  body {
    margin: 0.8cm;
    background-color: #ffffff;
  }

  .header {
    display: none;
  }

  .layout-footer-center {
    display: none;
  }

}
</style>

<template>
  <div class="layout">

    <Layout>

      <Header class="header">
        <Row>
          <Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
            :lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">

          <Affix :offset-top="0">
            <div :class="[showHeaderShade ? 'noteHeaderShade' : 'noteHeader']">

              <img style="height:40px;float:left;cursor: pointer;" alt="refresh flagnote" src="/static/logo.png"
                v-on:click="refreshPage()" />

              <div style="float:left;width:auto;">
                <Button-group size="large">
                  <Button aria-label="to top" v-show="toTopState" type="text"
                    style="margin-left:5px; border-radius: 0px; font-size: 28px;color:red;line-height: 20px;"
                    @click="toTop()" icon="ios-arrow-up" ghost></Button>
                </Button-group>
              </div>
              <div style="float:right;width:auto;">
                <Button-group size="large">
                  <Button aria-label="publish" type="error" :loading="model.submitting"
                    style="margin-left:5px; border-radius: 0px;font-size: 21px;" @click="submitNote()"
                    icon="md-cloud-upload"></Button>
                  <Button aria-label="menu" type="error" style="margin-left:3px; border-radius: 0px;font-size: 24px;"
                    @click="switchMenu()" @blur.native="hideMenu()" icon="md-menu"></Button>
                </Button-group>
              </div>
            </div>

            <div id="noteMenu" :class="[showMenuState ? 'showBlock' : 'hideBlock']"
              style="z-index: 100; position: absolute;top:43px;right:0px;left:auto;">
              <Button-group vertical size="large">
                <Button aria-label="create note" type="error" style="border-radius: 0px;font-size: 24px;"
                  @click="createNote(); switchMenu(); " icon="md-add"></Button>

                <Button aria-label="crop" v-show="model.showDownloadText" type="error"
                  style="border-radius: 0px;font-size: 24px;" @click="saveImage(); switchMenu();" icon="md-crop"></Button>

                <Button aria-label="download text" v-show="model.showDownloadText" type="error"
                  style="border-radius: 0px;font-size: 24px;" @click="downLoadText(); switchMenu();"
                  icon="md-download"></Button>

                <Button type="error" icon="md-trash" style="border-radius: 0px;font-size: 24px;"
                  @click="showDeleteModel(); switchMenu(); "></Button>

              </Button-group>


            </div>
          </Affix>



          </Col>
        </Row>
      </Header>

      <Content class="content">
        <div style="min-height: 650px;">
          <Row>
            <Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
              :lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
            <Card :padding="0">
              <Form :model="noteForm" :label-width="80">
                <div ref="html2canvas" id="wrapper" style="border-left: 2px solid #ed4014;">
                  <Input element-id="noteText" type="textarea" :border="false" v-model="noteForm.text" autofocus
                    :autosize="{ minRows: 35, maxRows: 100000 }" :placeholder="$t('content.noteTip')" @input="recordText"
                    @on-keydown="recordEventKdown" />
                  
                </div>
              </Form>
            </Card>
            <WordCount :value="noteForm.text" :total="100000" style="border-top:1px solid #ed4014;float:left" />
            </Col>

          </Row>
        </div>

      </Content>

      <Footer class="layout-footer-center">2023 &copy; flagnote.com</Footer>
    </Layout>

    <Modal v-model="model.showDelete" width="360" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
      <p style="text-align: center;font-size:medium ;margin-bottom: 20px;">
        {{ $t("message.askTodelete") }}
      </p>
      <p style="text-align: center;">
        <Button type="error" :loading="model.deleting" style="border-radius: 0px;font-size: 19px;" @click="dropNote()">{{
          $t("button.yes")
        }}</Button>
      </p>
    </Modal>

    <Modal v-model="model.showError" width="360" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
      <p style="text-align: center;font-size:medium ;margin-bottom: 20px;">
        {{ errorInfo }}
      </p>
      <p style="text-align: center;">
        <Button type="error" style="border-radius: 0px;font-size: 19px;" @click="cloaseErrorMessage()">{{
          $t("button.close")
        }}</Button>
      </p>
    </Modal>


  </div>
</template>

<script>
import { unwrap } from '../libs/secret'
import { saveNote } from "@/api/note";
import { getStoreKey } from "@/api/lock";
import storage from "@/libs/storage";
import { setStoreText, setNewStoreText } from "@/libs/noteStorage";
import { saveAs } from 'file-saver';
import { isWeixin } from "@/libs/utils";
import NoteConstant from "@/libs/constants";
import html2canvas from "html2canvas";

export default {
  name: 'EditNote',
  props: {},
  components: {},
  data() {
    return {
      noteForm: {
        text: '',
        key: '',
      },
      secret: {
        storeKey: '',
        secretKey: '',
        cipher: '',
        password: '',
      },
      state: {
        lock: 0,
        locking: 0,
        commited: 0,
        deleted: 0,
        serverTime: '',
        initTime: '',
      },
      model: {
        submitting: false,
        showDelete: false,
        deleting: false,
        showDownloadText: false,
        showError: false,
      },
      toTopState: false,
      showMenuState: false,
      showHeaderShade: false,
      errorInfo: '',
      lastEditTime: 0,
      backStoreTextInterval: null,
      lastStoreCount: 0,
      lastStoreTime: 0,
    }
  },
  created() {
    this.editTime = new Date().getTime();

    // read $route
    this.noteForm.key = this.$route.params.name;
    let keyMeta = this.$route.meta.keyMeta;

    //ipad chrome url not redirect
    // let path = location.pathname;
    // if ("/" == path) {
    //   history.pushState('', '', '/' + this.noteForm.key);
    // }

    //wx does not show downloadText
    this.model.showDownloadText = !isWeixin();

    // let noteMeta = this.$route.meta.noteMeta;
    let storeKey = getStoreKey(this.noteForm.key);
    this.secret.storeKey = storeKey;

    // first edit
    if (keyMeta) {
      this.state.lock = 0;
      this.secret.cipher = keyMeta.cipher;
      this.secret.secretKey = keyMeta.secretKey;
      this.state.serverTime = keyMeta.serverTime;
      // key init Time
      this.state.initTime = keyMeta.serverTime;
      // clear
      storage.local.dynamicClear();

      //if local less 1m ,then deep clear,let local greater than 2m
      // if (storage.local.getAvailableSize < 1 * 1024 * 1024) {
      //   storage.local.dynamicDeepClear(this.state.serverTime, storeKey);
      // }

      storage.local.setText(storeKey, "0|" + this.secret.cipher + "|0|" + this.state.initTime + "|");
      storage.session.delete(keyMeta.key + ".keyMeta");
    } else {
      // second edit
      let noteMeta = this.$route.meta.noteMeta;
      this.secret.secretKey = noteMeta.secretKey;

      let storeInfo = storage.local.getText(storeKey);
      let starray = storeInfo.split('|');
      this.state.lock = parseInt(starray[0]);
      this.secret.cipher = starray[1];
      this.state.initTime = parseInt(starray[3]);

      //draw text;
      if (starray[4]) {
        this.noteForm.text = unwrap(starray[4], this.secret.secretKey);
      }
    }

    this.lastStoreCount = this.noteForm.text.length;
    this.lastEditTime = new Date().getTime();
    this.lastStoreTime = this.lastEditTime;

    this.bindCtrlAllEvent();
    this.bindToTopEvent();

    window.wasm_bindgen(window.wasm_flate_bg_path);
  },
  mounted() {
    const myObserver = new ResizeObserver(entries => {
      // iterate over the entries, do something.
      entries.forEach(entry => {
        let affix = document.querySelector('.ivu-affix');
        if (affix) {
          affix.setAttribute("style", "top: 0px; width: " + (entry.contentRect.width + 2) + "px;");
        }

      });
    });

    const someOtherEl = document.querySelector('#wrapper');

    myObserver.observe(someOtherEl);

    window.addEventListener('beforeunload', e => this.beforeunloadHandler(e))
  },
  updated() {
  },
  beforeDestroy() {
  },
  destroyed() {
    window.removeEventListener('beforeunload', e => this.beforeunloadHandler(e))
  },
  computed: {},
  watch: {},
  methods: {

    toTop() {
      window.scrollTo(0, 0);
      let elent = document.querySelector('#noteText');
      elent.selectionStart = 0;
      elent.selectionEnd = 0;
      elent.focus();
    },
    refreshPage() {
      window.location.reload();
    },
    switchMenu() {
      this.showMenuState = !this.showMenuState;
    },
    hideMenu() {
      let hbt = document.querySelector('#noteMenu > div > button:hover');
      if (!hbt) {
        this.showMenuState = false;
      }
    },
    downLoadText() {
      var blob = new Blob([this.noteForm.text], { type: "application/octet-stream;charset=utf-8" });
      saveAs(blob, this.noteForm.key + ".txt");
    },
    recordText() {
      let text = this.noteForm.text;
      if (text.length > NoteConstant.noteMaxCount) {
        this.errorInfo = this.$t('error.100012', [NoteConstant.noteMaxDesc]);
        this.model.showError = true;
        return;
      }

      let nowEditCount = this.noteForm.text.length;
      let nowEditTime = new Date().getTime();

      if (nowEditCount < 1024) {
        setStoreText(this.noteForm, this.state, this.secret);
        this.lastStoreTime = nowEditTime;
        this.lastStoreCount = nowEditCount;
      } else {
        if (null == this.backStoreTextInterval) {
          this.backStoreTextInterval = window.setInterval(this.backStoreFunction(), 500);
        }
      }

      this.lastEditTime = nowEditTime;
    },
    backStoreFunction() {
      let that = this;
      return function () {
        that.backStoreText();
      }
    },
    backStoreText() {
      let nowEditCount = this.noteForm.text.length;
      let nowEditTime = new Date().getTime();
      if (Math.abs(nowEditCount - this.lastStoreCount) > 10) {
        setStoreText(this.noteForm, this.state, this.secret);
        this.lastStoreTime = this.lastEditTime;
        this.lastStoreCount = nowEditCount;
      } else {
        if (nowEditTime - this.lastEditTime >= 1000 && nowEditTime - this.lastEditTime < 20000) {
          if (this.lastEditTime != this.lastStoreTime) {
            setStoreText(this.noteForm, this.state, this.secret);
            this.lastStoreTime = this.lastEditTime;
            this.lastStoreCount = nowEditCount;
          }
        } else if (nowEditTime - this.lastEditTime >= 20000) {
          if (this.backStoreTextInterval != null) {
            let ivl = this.backStoreTextInterval;
            this.backStoreTextInterval = null;
            window.clearInterval(ivl);
          }
        }
      }
    },
    // recordEventKup(event) {
    // let tn = event.currentTarget.value;
    // let ss = event.currentTarget.selectionStart;
    // let cline = tn.substring(0, ss).split('\n').length;

    // var noteTop = parseFloat(window.getComputedStyle(event.currentTarget).lineHeight) * cline;
    // console.log(noteTop)
    // var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    // console.log(scrollTop)
    // if (noteTop < scrollTop+10) {
    //   window.scrollTo(0, noteTop-10);
    // }
    // },
    recordEventKdown(event) {

      if (event.key == "Tab") {

        let start = event.currentTarget.selectionStart;
        let end = event.currentTarget.selectionEnd;
        let text = event.currentTarget.value;

        if (text.length > NoteConstant.noteMaxCount) {
          this.errorInfo = this.$t('error.100012', [NoteConstant.noteMaxDesc]);
          this.model.showError = true;
          return;
        }

        let tab = '\t';//\t
        text = text.substr(0, start) + tab + text.substr(start);
        event.currentTarget.value = text;
        event.currentTarget.selectionStart = start + tab.length;
        event.currentTarget.selectionEnd = end + tab.length;
        event.stopPropagation();
        if (event.preventDefault) {
          event.preventDefault();
        }

        this.noteForm.text = event.currentTarget.value;
        this.recordText();

      } else if (event.ctrlKey && (event.which == 13)) {
        //save
        this.submitNote();
      }
    },
    save() {
      return saveNote(this.noteForm, this.secret);
    },
    validateForm() {
      let text = this.noteForm.text;
      if (text.length > NoteConstant.noteMaxCount) {
        this.errorInfo = this.$t('error.100012', [NoteConstant.noteMaxDesc]);
        this.model.showError = true;
        return false;
      }
      if (text.length == 0) {
        this.errorInfo = this.$t('error.100011');
        this.model.showError = true;
        return false;
      }
      return true;
    },
    cloaseErrorMessage() {
      this.errorInfo = '';
      this.model.showError = false;
    },
    submitNote() {
      if (this.state.locking == 1) {
        return;
      }

      if (!this.validateForm()) {
        this.state.locking = 0;
        return;
      }

      this.model.submitting = true;

      let that = this;
      this.save().then(res => {
        if (res.data && res.data.code == "000000") {
          storage.session.setText(that.secret.storeKey + "_share", '1');

          that.state.commited = 1;
          setStoreText(this.noteForm, this.state, this.secret);

          location.reload();
          this.state.locking = 0;
        } else {
          alert(res.data.code);
          this.model.submitting = false;
          this.state.locking = 0;
          if (res.data.code == "100013" || res.data.code == "800001") {
            let key = setNewStoreText(this.noteForm);
            location.href = "/" + key;
          }

        }
      }).catch(error => {
        alert(error);
      });
    },
    refresh() {
      location.reload();
    },
    createNote() {
      window.open("/");
    },
    showDeleteModel() {
      this.model.showDelete = true;
    },
    dropNote() {
      this.model.deleting = true;
      this.state.deleted = 1;
      storage.local.delete(this.secret.storeKey);
      storage.session.setText(this.secret.storeKey + "_delete", 1);
      location.reload();
    },
    bindToTopEvent() {
      let that = this;
      window.onscroll = function () {
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        if (scrollTop >= 20) {
          that.toTopState = true;
          that.showHeaderShade = true;
        } else {
          that.toTopState = false;
          that.showHeaderShade = false;
        }
      }
    },
    bindCtrlAllEvent() {
      if (window.getSelection && document.createRange) {
        document.onkeydown = (e) => {
          if ((e.ctrlKey || e.metaKey) && e.key == "a") {
            e.preventDefault();
            var element = document.getElementById("noteText");
            element.select();
          }
        }
      }
    },
    dataURLToBlob(dataurl) {
      let arr = dataurl.split(',');
      let mime = arr[0].match(/:(.*?);/)[1];
      let bstr = window.atob(arr[1]);
      let n = bstr.length;
      let u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], { type: mime });
    },
    saveImage() {
      let canvasID = this.$refs["html2canvas"];

      let that = this;
      let a = document.createElement('a');
      html2canvas(canvasID, {
        scale: 1,
        windowWidth: parseInt(document.getElementById("noteText").offsetWidth) + 2,
        onclone: (clonedDocument) => {
          let nt = clonedDocument.getElementById("noteText");
          const div = clonedDocument.createElement('div')
          div.innerText = nt.value

          div.style.color = "black";
          div.style.padding = "10px";
          div.style.textAlign = "left";
          div.style.wordBreak = "break-word";
          div.style.whiteSpace = "pre-wrap";
          div.style.verticalAlign = "top";
          div.style.fontSize = "15px";
          div.style.width = "100%";
          div.style.border = "0px";
          div.style.fontFamily = "'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif";

          nt.style.display = 'none'

          nt.parentElement.parentElement.style.borderLeftColor = "white";

          nt.parentElement.append(div)
        }
      }).then(canvas => {
        let dom = document.body.appendChild(canvas);
        dom.style.display = 'none';
        a.style.display = 'none';
        document.body.removeChild(dom);
        let blob = that.dataURLToBlob(dom.toDataURL('image/png'));
        a.setAttribute('href', URL.createObjectURL(blob));
        a.setAttribute('download', that.noteForm.key + '.png');
        document.body.appendChild(a);
        a.click();
        URL.revokeObjectURL(blob);
        document.body.removeChild(a);
      });
    },
    beforeunloadHandler() {
      if(this.state.deleted==0){
        setStoreText(this.noteForm, this.state, this.secret);
      }
    },
  }
}
</script>
