<script setup lang="ts">
import RightClickMenuEntry from '@/components/Dashboard/TRC/RightClickMenuEntry.vue'
import ConfirmDeleteDialog from '@/components/Dialogs/ConfirmDeleteDialog.vue'
import MoveTorrentDialog from '@/components/Dialogs/MoveTorrentDialog.vue'
import RenameTorrentDialog from '@/components/Dialogs/RenameTorrentDialog.vue'
import ShareLimitDialog from '@/components/Dialogs/ShareLimitDialog.vue'
import SpeedLimitDialog from '@/components/Dialogs/SpeedLimitDialog.vue'
import { useDashboardStore } from '@/stores/dashboard'
import { useDialogStore } from '@/stores/dialog'
import { useMaindataStore } from '@/stores/maindata'
import { usePreferenceStore } from '@/stores/preferences'
import { TRCMenuEntry } from '@/types/vuetorrent'
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'

const props = defineProps<{
  modelValue: boolean
}>()
const emit = defineEmits(['update:modelValue'])

const { t } = useI18n()
const router = useRouter()
const dashboardStore = useDashboardStore()
const dialogStore = useDialogStore()
const maindataStore = useMaindataStore()
const preferenceStore = usePreferenceStore()

const trcVisible = computed({
  get: () => props.modelValue,
  set: value => emit('update:modelValue', value)
})

const isMultiple = computed(() => dashboardStore.selectedTorrents.length > 1)
const hashes = computed(() => dashboardStore.selectedTorrents)
const hash = computed(() => hashes.value[0])
const torrent = computed(() => maindataStore.getTorrentByHash(hash.value))
const torrents = computed(() => dashboardStore.selectedTorrents.map(maindataStore.getTorrentByHash).filter(torrent => !!torrent))
const availableCategories = computed(() => [{ name: '' }, ...maindataStore.categories])

async function resumeTorrents() {
  await maindataStore.resumeTorrents(hashes)
}

async function forceResumeTorrents() {
  await maindataStore.forceResumeTorrents(hashes)
}

async function pauseTorrents() {
  await maindataStore.pauseTorrents(hashes)
}

function deleteTorrents() {
  dialogStore.createDialog(ConfirmDeleteDialog, { hashes: [...dashboardStore.selectedTorrents] })
}

function moveTorrents() {
  dialogStore.createDialog(MoveTorrentDialog, { hashes: [...dashboardStore.selectedTorrents] })
}

function renameTorrents() {
  dialogStore.createDialog(RenameTorrentDialog, { hash: dashboardStore.selectedTorrents[0] })
}

async function forceRecheck() {
  await maindataStore.recheckTorrents(hashes)
}

async function forceReannounce() {
  await maindataStore.reannounceTorrents(hashes)
}

async function toggleSeqDl() {
  await maindataStore.toggleSeqDl(hashes)
}

async function toggleFLPiecePrio() {
  await maindataStore.toggleFLPiecePrio(hashes)
}

async function toggleAutoTMM() {
  await maindataStore.toggleAutoTmm(hashes, !torrent.value?.auto_tmm)
}

function hasTag(tag: string) {
  return torrents.value.every(torrent => torrent && torrent.tags && torrent.tags.includes(tag))
}

async function toggleTag(tag: string) {
  if (hasTag(tag)) await maindataStore.removeTorrentTags(hashes.value, [tag])
  else await maindataStore.addTorrentTags(hashes.value, [tag])
}

async function copyValue(valueToCopy: string) {
  await navigator.clipboard.writeText(valueToCopy)
}

function setDownloadLimit() {
  dialogStore.createDialog(SpeedLimitDialog, { hash: hash.value, mode: 'download' })
}

function setUploadLimit() {
  dialogStore.createDialog(SpeedLimitDialog, { hash: hash.value, mode: 'upload' })
}

function setShareLimit() {
  dialogStore.createDialog(ShareLimitDialog, { hash: hash.value })
}

async function exportTorrents() {
  hashes.value.forEach(hash => {
    maindataStore.exportTorrent(hash).then(blob => {
      const url = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.style.opacity = '0'
      link.setAttribute('download', `${hash}.torrent`)
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    })
  })
}

const menuData = computed<TRCMenuEntry[]>(() => [
  {
    text: t('dashboard.right_click.advanced.title'),
    icon: 'mdi-head-cog',
    children: [
      {
        text: t('dashboard.right_click.advanced.change_location'),
        icon: 'mdi-folder',
        action: moveTorrents
      },
      {
        text: t('dashboard.right_click.advanced.rename'),
        icon: 'mdi-rename-box',
        hidden: isMultiple.value,
        action: renameTorrents
      },
      {
        text: t('dashboard.right_click.advanced.recheck'),
        icon: 'mdi-playlist-check',
        action: forceRecheck
      },
      {
        text: t('dashboard.right_click.advanced.reannounce'),
        icon: 'mdi-bullhorn',
        action: forceReannounce
      },
      {
        text: t('dashboard.right_click.advanced.seq_dl'),
        icon: torrent.value?.seq_dl ? 'mdi-checkbox-marked' : 'mdi-checkbox-blank-outline',
        action: toggleSeqDl
      },
      {
        text: t('dashboard.right_click.advanced.f_l_prio'),
        icon: torrent.value?.f_l_piece_prio ? 'mdi-checkbox-marked' : 'mdi-checkbox-blank-outline',
        action: toggleFLPiecePrio
      },
      {
        text: t('dashboard.right_click.advanced.auto_tmm'),
        icon: torrent.value?.auto_tmm ? 'mdi-checkbox-marked' : 'mdi-checkbox-blank-outline',
        action: toggleAutoTMM
      }
    ]
  },
  {
    text: t('dashboard.right_click.priority.title'),
    icon: 'mdi-priority-high',
    hidden: !preferenceStore.preferences!.queueing_enabled,
    children: [
      {
        text: t('dashboard.right_click.priority.top'),
        icon: 'mdi-priority-high',
        action: async () => await maindataStore.setTorrentPriority(hashes.value, 'topPrio')
      },
      {
        text: t('dashboard.right_click.priority.increase'),
        icon: 'mdi-arrow-up',
        action: async () => await maindataStore.setTorrentPriority(hashes.value, 'increasePrio')
      },
      {
        text: t('dashboard.right_click.priority.decrease'),
        icon: 'mdi-arrow-down',
        action: async () => await maindataStore.setTorrentPriority(hashes.value, 'decreasePrio')
      },
      {
        text: t('dashboard.right_click.priority.bottom'),
        icon: 'mdi-priority-low',
        action: async () => await maindataStore.setTorrentPriority(hashes.value, 'bottomPrio')
      }
    ]
  },
  {
    text: t('dashboard.right_click.tags.title'),
    icon: 'mdi-tag',
    disabled: maindataStore.tags.length === 0,
    disabledText: t('dashboard.right_click.tags.disabled_title'),
    disabledIcon: 'mdi-tag-off',
    children: maindataStore.tags.map(tag => ({
      text: tag,
      icon: hasTag(tag) ? 'mdi-checkbox-marked' : 'mdi-checkbox-blank-outline',
      action: async () => await toggleTag(tag)
    }))
  },
  {
    text: t('dashboard.right_click.category.title'),
    icon: 'mdi-label',
    disabled: maindataStore.categories.length === 0,
    disabledText: t('dashboard.right_click.category.disabled_title'),
    disabledIcon: 'mdi-label-off',
    children: availableCategories.value.map(category => ({
      text: category.name === '' ? t('dashboard.right_click.category.clear') : category.name,
      action: async () => await maindataStore.setTorrentCategory(hashes.value, category.name)
    }))
  },
  {
    text: t('dashboard.right_click.speed_limit.title'),
    icon: 'mdi-speedometer-slow',
    children: [
      {
        text: t('dashboard.right_click.speed_limit.download'),
        icon: 'mdi-download',
        action: setDownloadLimit
      },
      {
        text: t('dashboard.right_click.speed_limit.upload'),
        icon: 'mdi-upload',
        action: setUploadLimit
      },
      {
        text: t('dashboard.right_click.speed_limit.share'),
        icon: 'mdi-account-group',
        action: setShareLimit
      }
    ]
  },
  {
    text: t('dashboard.right_click.copy.title'),
    icon: 'mdi-content-copy',
    hidden: isMultiple.value,
    children: [
      {
        text: t('dashboard.right_click.copy.name'),
        icon: 'mdi-alphabetical-variant',
        action: async () => torrent.value && (await copyValue(torrent.value.name))
      },
      {
        text: t('dashboard.right_click.copy.hash'),
        icon: 'mdi-pound',
        action: async () => await copyValue(hash.value)
      },
      {
        text: t('dashboard.right_click.copy.magnet'),
        icon: 'mdi-magnet',
        action: async () => torrent.value && (await copyValue(torrent.value.magnet))
      }
    ]
  },
  {
    text: t('dashboard.right_click.export', dashboardStore.selectedTorrents.length),
    icon: isMultiple.value ? 'mdi-download-multiple' : 'mdi-download',
    action: exportTorrents
  },
  {
    text: t('dashboard.right_click.info'),
    icon: 'mdi-information',
    hidden: isMultiple.value,
    action: () => router.push({ name: 'torrentDetail', params: { hash: hash.value } })
  }
])
</script>

<template>
  <v-menu v-if="trcVisible" v-model="trcVisible" activator="parent" :close-on-content-click="true" transition="slide-y-transition" scroll-strategy="none">
    <v-list>
      <v-list-item>
        <div class="d-flex justify-space-around">
          <v-tooltip location="top">
            <template v-slot:activator="{ props }">
              <v-btn density="compact" variant="plain" icon="mdi-play" v-bind="props" @click="resumeTorrents" />
            </template>
            <span>Resume</span>
          </v-tooltip>

          <v-tooltip location="top">
            <template v-slot:activator="{ props }">
              <v-btn density="compact" variant="plain" icon="mdi-fast-forward" v-bind="props" @click="forceResumeTorrents" />
            </template>
            <span>Force Resume</span>
          </v-tooltip>

          <v-tooltip location="top">
            <template v-slot:activator="{ props }">
              <v-btn density="compact" variant="plain" icon="mdi-pause" v-bind="props" @click="pauseTorrents" />
            </template>
            <span>Pause</span>
          </v-tooltip>

          <v-tooltip location="top">
            <template v-slot:activator="{ props }">
              <v-btn color="red" density="compact" variant="plain" icon="mdi-delete-forever" v-bind="props" @click="deleteTorrents" />
            </template>
            <span>Delete</span>
          </v-tooltip>
        </div>
      </v-list-item>

      <RightClickMenuEntry v-for="entry in menuData" v-bind="entry" />
    </v-list>
  </v-menu>
</template>

<style scoped lang="scss">
.menu-scrollable {
  max-height: 500px;
  overflow: visible;
}
</style>