<script setup>
import { useDatabaseStore } from "@/stores/database"
import Api from "@/services/Api"
import appwrite from '@/services/appwrite';
import { DateTime } from "luxon";
</script>

<script>
import { defineComponent, toRaw, reactive } from 'vue';
import { HotTable } from '@handsontable/vue3';
import { registerAllModules } from 'handsontable/registry';
import 'handsontable/dist/handsontable.full.css';
import '../assets/colors.css';
import Handsontable from 'handsontable/base';
// register Handsontable's modules
registerAllModules();

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

function getHourClass(i) {
  const colorMapping = {
    0: "black",
    1: "red",
    2: "cyan",
    3: "pink",
    4: "blue",
    5: "green",
    6: "yellow",
    7: "orange",
    8: "purple",
    9: "darkred",
    10: "lime"
  }
  if(i > 10){
    i = Math.round(i/10) - 1
  }
  if (i == null) {
      return "";
    }
    else {
      return "color-" + colorMapping[i];
    }
}

function hourCol(t) {
  return {
    data: "hours." + t,
    type: 'numeric',
    renderer(instance, td, row, col, prop, value) {
      td.className = getHourClass(value);
      td.innerText = value == null ? value : parseFloat(value);
              return td;
            }
  }
}

const colHeaders = ["DATE", "DAY", "12 AM"]
    .concat(Array.from(new Array(11), (x, y) => y+1 + " AM") )
    .concat(Array.from(new Array(12), (x, y) => y+1 + " PM") )
    .concat(["Mood", "Comments"])

const ExampleComponent = defineComponent({
  data() {
    return {
        entries: [],
        numEntries: 25,
        offset: 0,
      hotSettings: {
        autoRowSize: true,
        columns: [
          {
            readOnly: true,
            data: "date",
            renderer(instance, td, row, col, prop, value) {
              var date = DateTime.fromISO(value).toUTC().toFormat("MM/dd");
              var today = DateTime.now().toFormat("MM/dd");
              if(today == date){
                td.className = "color-black invert";
              }
              else{td.className = "color-black";}
              td.innerText = date;
              return td;
            }
          },
          {
            readOnly: true,
            data: "date",
            renderer(instance, td, row, col, prop, value) {
              var date = DateTime.fromISO(value).toUTC();
              var today = DateTime.now().toFormat("MM/dd");
              if(date.toFormat("MM/dd") == today){
                td.className = "color-black invert day-of-week";
              }
              else{td.className = "color-black day-of-week";}
              td.innerText = date.toFormat("EEE");
              return td;
            }
          },
          Array.from(new Array(24), (_, t) => hourCol(t)),
          { data: "mood", type: "numeric" },
          { data: "comments", className: "align-left" }
        ].flat(),
        colHeaders: colHeaders,
        rowHeaders: false,
        readOnly: false,
        width: '100%',
        height: 'auto',
        rowHeights: '22px',
        colWidths(i) {
          if((i > 1) && (i < 26)){
            return "50px";
          }
          else if(i == 27){
            return "1000px";
          }
          else{
            return "50px";
          }
        },
        afterSelection: (row, column, row2, column2, preventScrolling, selectionLayerLevel) => {
          
        },
        afterChange: (changes) => {
          this.fixSelectionBug();
          //this.setActiveHourHeader();
          if (changes != null) {
            var entry = this.entries[changes[0][0]];
            entry.date = entry.date.replace(/T.*/, "");
            appwrite.updateEntry(entry);
          }
        },
        licenseKey: 'non-commercial-and-evaluation'
      },
      hotRef: null
    }
  },
  async mounted(){
        this.user = await appwrite.getUser();
        this.entries = await appwrite.getEntries(null,5);
        this.updateTable();
        this.subscribe();
        this.fixSelectionBug();
    },
    created () {
    window.addEventListener('wheel', debounce(this.handleScroll, 300, true));
  },
  unmounted () {
    window.removeEventListener('wheel', debounce(this.handleScroll, 300, true));
  },
  methods: {
    setActiveHourHeader(){
      var timeString = DateTime.now().toFormat("hh a");
      var currentTimeHeader = Array.from(document.querySelectorAll("th"))
        .find(el => el.innerText == timeString);
      currentTimeHeader.className = "invert";
    },
    async handleScroll(e){
      var offset;
      if(e.deltaY > 0){
        var lastDate = DateTime.fromISO(
          this.entries[
            this.hotRef
              .getPlugin('autoRowSize')
              .getLastVisibleRow()
          ].date).toUTC().plus({ days: 1 });
        console.log("Grabbing 5 more entries starting at " + lastDate.toISO());
        var newEntries = await appwrite.getEntries(
          lastDate.plus({ days: 1 })
          , 5);
          newEntries.forEach((e) => {
        this.entries.push(e);
      })
      }
      else{
        var firstDate = DateTime.fromISO(
          this.entries[
            this.hotRef
              .getPlugin('autoRowSize')
              .getFirstVisibleRow()
          ].date).toUTC().minus({ days: 1 });
        console.log("Grabbing 5 previous entries ending at " + firstDate.toISO());
        var newEntries = await appwrite.getEntries(
          firstDate.minus({ days: 6 })
          , 5);
        var entries = this.entries;
        newEntries.reverse().forEach((e) => {
         entries.unshift(e);
       })
       this.entries = entries;
      }
    },
    fixSelectionBug(){
      if(this.hotRef){
          var offset =  (this.hotRef.getRowHeight()) * (this.entries.length + 1) + 2;//document.querySelector(".wtHider").clientHeight;
          document.querySelector(".htBorders div").style.top = "-" + offset + "px";
      }
},
    subscribe(){
      appwrite.subscribe((payload) => {
                var event = payload.events.filter((e) => 
                    e.match(/databases\.\*\.collections\.\*\.documents\.\*\.\w+/)
                )[0].replace(/.+\./,"");
                switch (event) {
                case 'create':
                    this.entries.push(payload.payload)
                    this.entries = this.entries
                    break
                case 'update':
                    this.entries = this.entries.map((day) => {
                    if (day.$id === payload.payload.$id) {
                        return payload.payload
                    } else {
                        return day
                    }
                    })
                    break
                case 'delete':
                    this.entries = this.entries.filter((day) => day.$id !== payload.payload.$id)
                    break
                }
            })
          },
    updateTable(){
     this.hotRef = this.$refs.wrapper.hotInstance;
     this.hotRef.loadData(this.entries);
    }
  },
  components: {
    HotTable,
  }
});

export default ExampleComponent;

</script>

<template>
  <button @click="concatEntries">Fuck</button>
<!-- <div>{{ entries }}</div>

<ul>
    <li v-for="e in entries" :key="e">
      {{ e }}
    </li>
  </ul> -->
  <hot-table ref="wrapper" :settings="hotSettings" :data="entries"></hot-table>
</template>

<style>
 
</style>