<script setup lang="ts">
import {onMounted, ref, watch} from "vue";
import draggable from "vuedraggable";
import {timeFormatter} from "@/helpers/TimeFormatter.ts";

const emit = defineEmits([
  'updateTracks'
])

const props = defineProps({
  tracks: {
    type: Array,
    required: true
  }
})

const hiddenCriteria = [
    'sort',
    'repeat_tracks',
    'overflow_tracks'
]

const trackList = ref([])
const openElements = ref([])

const rehydratateTracks = () => {
  trackList.value = props.tracks.map((track, key) => {
    const track_info = {
      type: null,
      id: 0,
      title: '',
      order: key,
      db_element: null,
    }
    console.log(track)
    if (Object.hasOwn(track, 'file') && track.file !== null) {
      track_info.type = 'audioclip'
      track_info.title = track.file.track_title
      track_info.subtitle = track.file.artist_name
      track_info.db_element = track.file
      track_info.file = track.file
      track_info.id = track.file_id
    }
    if (!Object.hasOwn(track, 'file') && track.type === 'audioclip') {
      track_info.type = 'audioclip'
      track_info.title = track.track_title
      track_info.subtitle = track.artist_name
      track_info.db_element = track
      track_info.file = track
      track_info.id = track.id
    }
    if (Object.hasOwn(track, 'block') && track.block !== null) {
      track_info.type = 'block'
      track_info.title = track.block.name
      track_info.subtitle = track.block.creator.login
      track_info.db_element = track.block
      track_info.block = track.block
      track_info.id = track.block_id
    }
    if (!Object.hasOwn(track, 'block') && track.type === 'block') {
      track_info.type = 'block'
      track_info.title = track.name
      track_info.subtitle = track.creator.login
      track_info.db_element = track
      track_info.block = track
      track_info.id = track.id
    }
    return track_info
  })
}

onMounted(() => {
  rehydratateTracks()
})

const checkMove = (e) => {
  console.log(e)
  //if block element close criteria to avoid errors
  if (openElements.value.includes(e.draggedContext.index)) {
    delete openElements.value[openElements.value.indexOf(e.draggedContext.index)]
  }
}

watch(props, (newVal, oldVal) => {
  console.log(newVal)
  rehydratateTracks()
})

const change = (event) => {
  console.log(event)
  if (Object.hasOwn(event, 'added')) {
    if (Object.hasOwn(trackList.value[event.added.newIndex], 'track_title')) {
      console.log('ye')
      trackList.value[event.added.newIndex].type = 'audioclip';
      trackList.value[event.added.newIndex].title = trackList.value[event.added.newIndex].track_title;
      trackList.value[event.added.newIndex].subtitle = trackList.value[event.added.newIndex].artist_name;
    }
    if (Object.hasOwn(trackList.value[event.added.newIndex], 'criteria')) {
      trackList.value[event.added.newIndex].type = 'block';
      trackList.value[event.added.newIndex].title = trackList.value[event.added.newIndex].name;
      trackList.value[event.added.newIndex].subtitle = trackList.value[event.added.newIndex].creator.login;
    }
  }
  emit('updateTracks', trackList.value)
}

const remove = (item, index) => {
  trackList.value.splice(index, 1)
  emit('updateTracks', trackList.value)
}

const toggleElement = (index) => {
  if (openElements.value.includes(index)) {
    delete openElements.value[openElements.value.indexOf(index)]
  } else {
    openElements.value.push(index)
  }
  console.log(openElements.value)
}

const printCriteria = (criteria) => {
  if (criteria.criteria === 'limit') {
    return `Limite a ${criteria.value} ${criteria.modifier}`
  } else {
    return `${criteria.criteria} ${criteria.modifier} ${criteria.value}`
  }
}

defineExpose({ draggable });
</script>

<template>
  <v-list>
    <draggable
      :list="trackList"
      item-key="position"
      group="tracklist"
      :move="checkMove"
      @change="change"
      class="draggable-list"
    >
      <template #item="{ element, index }">
        <v-list-item>
          <template v-slot:prepend>
            <div class="index">
              {{ index + 1 }}
<!--              {{ element }}-->
            </div>
          </template>
          <v-list-item-title v-html="element.title"></v-list-item-title>
          <v-list-item-subtitle v-html="element.subtitle"></v-list-item-subtitle>
          <v-list-item-subtitle
              v-if="openElements.includes(index)"
              v-for="criteria in element.db_element.criteria.filter(el => hiddenCriteria.indexOf(el.criteria) === -1)"
              v-html="printCriteria(criteria)"
              class="criteria"
          >

          </v-list-item-subtitle>
          <template v-slot:append>
            <v-icon
                v-if="element.type === 'block' && !openElements.includes(index)"
                @click="toggleElement(index)"
            >mdi-unfold-more-horizontal</v-icon>
            <v-icon
                v-if="element.type === 'block' && openElements.includes(index)"
                @click="toggleElement(index)"
            >mdi-unfold-less-horizontal</v-icon>
            <span
              v-if="element.db_element?.length"
            >{{ timeFormatter(element.db_element.length) }}</span>
            <v-icon
                @click="remove(element, index)"
            >mdi-close</v-icon>
          </template>
        </v-list-item>
      </template>
    </draggable>
  </v-list>
</template>

<style scoped>
  .draggable-list {
    min-height: 200px;
    background-color: gray;
  }
  .criteria {
    margin: 2px 0;
    opacity: 1
  }
  .v-list-item-subtitle:not(.criteria) + .criteria {
    margin-top: 8px;
  }
</style>