<script setup lang="ts">
import { usePowerItems } from '@/stores/powerItems'
import type { DataTableHeader } from '@/types/DataTableHeader'
import type { PowerItem } from '@/types/PowerItem'
import type { Ref } from 'vue'
import { computed, ref, watch } from 'vue'
import { useDisplay } from 'vuetify'
import type { VDataTable } from 'vuetify/components'

type ReadonlyHeaders = VDataTable['headers']
type SortItem = { key: string; order?: boolean | 'asc' | 'desc' }
const { lgAndUp } = useDisplay()

export interface Props {
  items: Map<string, PowerItem>
  minimumTotal: number
  maximumTotal: number
  averageTotal: number
}

const props = withDefaults(defineProps<Props>(), {
  items: () => new Map<string, PowerItem>()
})

const computedHeaders = computed((): ReadonlyHeaders => {
  let initialHeaders: DataTableHeader[] = [
    {
      title: 'Name',
      align: 'start',
      sortable: true,
      value: '1.itemName'
    },
    {
      title: 'Owned',
      align: 'end',
      sortable: true,
      key: `1.owned`
    },
    {
      title: 'Mean Total',
      align: 'end',
      sortable: false,
      key: `1.aveTotalPower`
    }
  ]
  if (lgAndUp.value) {
    initialHeaders!.unshift({
      title: 'Event',
      align: 'start',
      sortable: true,
      value: '1.origin'
    })
    initialHeaders.splice(2, 0, {
      title: 'Min.',
      align: 'end',
      sortable: true,
      key: '1.minItemPower'
    })
    initialHeaders.splice(3, 0, {
      title: 'Max.',
      align: 'end',
      sortable: true,
      key: '1.maxItemPower'
    })
    initialHeaders.splice(5, 0, {
      title: 'Min. Total',
      align: 'end',
      sortable: false,
      key: `1.minTotalPower`
    })
    initialHeaders.splice(6, 0, {
      title: 'Max. Total',
      align: 'end',
      sortable: false,
      key: `1.maxTotalPower`
    })
  }
  return initialHeaders as ReadonlyHeaders
})
const sortBy: Ref<SortItem[]> = ref([
  {
    key: '1.minItemPower',
    order: 'asc'
  }
])
const selectedEvents: Ref<string[]> = ref([])

const getEventImageUrl = function (eventName: string): string {
  return eventName !== undefined
    ? '/images/' + eventName.replace(/\s/g, '_').toLocaleLowerCase() + '.png'
    : ''
}
const toggle = function () {
  if (allSelected.value) {
    selectedEvents.value = []
  } else {
    selectedEvents.value = events.value.slice()
  }
}

const events = computed(() =>
  [...props.items.values()]
    .map((cur) => cur.origin)
    .filter((value: string, idx: number, arr: string[]) => arr.indexOf(value) === idx)
)
const filteredItems = computed(() =>
  [...props.items.entries()]
    .map((value) =>
      selectedEvents.value.indexOf('All') !== -1 ||
      selectedEvents.value.indexOf(value[1].origin) !== -1
        ? value
        : undefined
    )
    .filter((value): value is [string, PowerItem] => !!value)
)
const getColor = computed(() => (rarity: number): string => {
  if (rarity === 5) {
    return 'red'
  } else if (rarity === 4) {
    return 'amber'
  } else if (rarity === 3) {
    return 'purple'
  } else if (rarity === 2) {
    return 'blue'
  } else {
    return 'green'
  }
})
const allSelected = computed(() => events.value.length === selectedEvents.value.length)
const partialSelected = computed(() => selectedEvents.value.length > 0)
const isLoading = computed((): boolean => props.items.keys()?.next().done ?? false)
watch(isLoading, (newLoading) => {
  if (!newLoading) {
    toggle()
  }
})
if (!isLoading.value) {
  toggle()
}
</script>

<template>
  <v-card fluid :loading="isLoading">
    <v-card-title>Special Items</v-card-title>
    <v-card-subtitle>Items from events</v-card-subtitle>
    <v-card-item>
      <v-select
        clearable
        chips
        label="Event"
        :items="events"
        multiple
        density="compact"
        v-model="selectedEvents"
      >
        <template v-slot:prepend-item>
          <v-list-item title="Select All" @click="toggle">
            <template v-slot:prepend>
              <v-checkbox-btn
                :color="partialSelected ? 'indigo-darken-2' : undefined"
                :indeterminate="partialSelected && !allSelected"
                :model-value="partialSelected"
              ></v-checkbox-btn>
            </template>
          </v-list-item>
        </template>
      </v-select>
      <v-data-table
        density="compact"
        v-model:sort-by="sortBy"
        :items="filteredItems"
        :headers="computedHeaders"
      >
        <template v-slot:[`item.1.origin`]="{ item }">
          <v-card
            class="my-2"
            elevation="2"
            rounded
            width="39"
            v-if="getEventImageUrl(item[1].origin) !== ''"
            color="transparent"
          >
            <v-img :src="getEventImageUrl(item[1].origin)"></v-img>
            <v-tooltip activator="parent">{{ item[1].origin }}</v-tooltip> </v-card
          >
        </template>
        <template v-slot:[`item.1.itemName`]="{ item }">
          <v-tooltip
            activator="parent"
            v-if="item[1].tooltip != undefined"
            content-class="custom-tooltip"
          >
            <v-card variant="text" density="compact" max-width="25vw">
              <v-card-title class="px-2">Origin: {{ item[1].origin }}</v-card-title>
              <v-card-text class="px-2" v-if="item[1].tooltip !== ''">{{
                item[1].tooltip
              }}</v-card-text>
            </v-card>
          </v-tooltip>
          <v-chip :color="`${getColor(item[1].rarity)}`">
            {{ item[1].itemName }}
          </v-chip>
        </template>
        <template v-slot:[`item.1.owned`]="{ item }">
          <v-text-field
            density="compact"
            hide-details="auto"
            v-model.number="item[1].owned"
            @update:model-value="usePowerItems().updateOwned(item[0], item[1].owned)"
          ></v-text-field>
        </template>
        <template v-slot:[`item.1.minTotalPower`]="{ item }">
          {{ item[1].minItemPower * item[1].owned }}
        </template>
        <template v-slot:[`item.1.maxTotalPower`]="{ item }">
          {{ item[1].maxItemPower * item[1].owned }}
        </template>
        <template v-slot:[`item.1.aveTotalPower`]="{ item }">
          {{ ((item[1].minItemPower + item[1].maxItemPower) / 2) * item[1].owned }}
        </template>
        <template v-slot:tfoot>
          <tfoot>
            <tr>
              <td class="d-none d-lg-table-cell"></td>
              <td></td>
              <td class="d-none d-lg-table-cell"></td>
              <td class="d-none d-lg-table-cell"></td>
              <td></td>
              <td class="px-0 text-right font-weight-bold d-none d-lg-table-cell">
                {{ minimumTotal }}
              </td>
              <td class="px-0 text-right font-weight-bold d-none d-lg-table-cell">
                {{ maximumTotal }}
              </td>
              <td class="px-0 text-right font-weight-bold">{{ averageTotal }}</td>
            </tr>
          </tfoot>
        </template>
      </v-data-table>
    </v-card-item>
  </v-card>
</template>

<style lang="scss" scoped>
:global(.custom-tooltip) {
  padding: 0 !important;
}
</style>
