<script lang="ts" setup>

import { Check, Delete, Promotion } from "@element-plus/icons-vue"
import { ElMessage } from "element-plus"
import { inject, onMounted, ref } from "vue"
import { LoggerKey } from "../ts/class/Logger"
import { itemNameDict } from "../ts/dictionary/translation"
import Sleep from "../ts/func/utils/Sleep"
import equipItem from "../ts/func/utils/equipItem"
import useItem from "../ts/func/utils/useItem"

const logger = inject(LoggerKey)

type Item = {
  id: number
  name: string
  nameZh: string
  amount: number
  isEquipped: boolean
  details: ItemDetails
  isDetailsLoading: boolean
  armoryId: number
  damage: number
  accuracy: number
  defence: number
  // 只赋值可装备物品
  type?: number
  bonus: string
}

type ItemDetails = {
  itemType: string
  itemCost: string
  itemValue: string
  itemRareTitle: string
  extras: { icon: string; cl: string; type: string; title: string; value: string }[]
  itemInfo: string
  itemSell: string
  itemID: number
  itemName: string
  itemInfoContent: string
  itemCirculation: string
  armoryID: boolean
  // TODO 翻译
  itemRareIcon: string
}

const itemList = ref<Item[]>([])
const disabledInfiniteLoading = ref(false)
const categorySelected = ref('Drug')
const categories = [
  { label: '📦 ', value: '' },
  { label: '主', value: 'Primary' },
  { label: '副', value: 'Secondary' },
  { label: '🔪 ', value: 'Melee' },
  { label: '💣 ', value: 'Temporary' },
  { label: '🛡 ', value: 'Defensive' },
  { label: '👔 ', value: 'Clothing' },
  { label: '🏥 ', value: 'Medical' },
  { label: '💊 ', value: 'Drug' },
  { label: '🥤 ', value: 'Energy+Drink' },
  { label: '🍺 ', value: 'Alcohol' },
  { label: '🍬 ', value: 'Candy' },
  { label: '⬆️ ', value: 'Booster' },
  { label: '🪄 ', value: 'Enhancer' },
  { label: '📦 ', value: 'Supply+Pack' },
  { label: '🔌 ', value: 'Electronic' },
  { label: '💎 ', value: 'Jewelry' },
  { label: '🌹 ', value: 'Flower' },
  { label: '🧸 ', value: 'Plushie' },
  { label: '🚗 ', value: 'Car' },
  { label: '🦠 ', value: 'Virus' },
  { label: '📖 ', value: 'Book' },
  { label: '🌟', value: 'Special' },
  { label: '🛍 ', value: 'Other' },
  // TODO
  { label: '🗼 ', value: '' },
  { label: '🏆 ', value: '' },
]

const fetchList = async (start: number = 0): Promise<string> => {
  let json: { html?: string, error?: string, text?: string }
  try {
    json = await (await fetch(window.addRFC("https://www.torn.com/item.php"), {
      "headers": {
        "accept": "*/*",
        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
        "sec-ch-ua-mobile": "?0",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "x-requested-with": "XMLHttpRequest"
      },
      "referrer": "https://www.torn.com/item.php",
      "referrerPolicy": "strict-origin-when-cross-origin",
      "body": categorySelected.value ? `step=getCategoryList&itemName=${ categorySelected.value }&start=${ start }&test=true&prevtotal=0` : `step=getNotAllItemsListWithoutGroups&start=${ start }&queue=All`,
      "method": "POST",
      "mode": "cors",
      "credentials": "include"
    })).json()
  } catch (e) {
    logger.error(e.stack)
    ElMessage.error('物品获取失败 ' + e.message)
    throw e
  }
  if (json.html) return json.html
  else {
    const err = json.error || json.text || '获取物品列表时没有内容'
    logger.error(err)
    ElMessage.error('获取物品失败 ' + err)
    throw new Error(err)
  }
}

const fetchItemDetails = async (id: number): Promise<ItemDetails> => {
  let ret: ItemDetails = null
  try {
    ret = await (await fetch(window.addRFC("https://www.torn.com/page.php?sid=inventory"), {
      "headers": {
        "accept": "*/*",
        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
        "sec-ch-ua-mobile": "?0",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "x-requested-with": "XMLHttpRequest"
      },
      "referrer": "https://www.torn.com/item.php",
      "referrerPolicy": "strict-origin-when-cross-origin",
      "body": "itemID=" + id,
      "method": "POST",
      "mode": "cors",
      "credentials": "include"
    })).json()
  } catch (e) {
    logger.error(e.stack)
    ElMessage.error('物品详情获取失败 ' + e.message)
    throw e
  }
  return ret
}

const parseListHtml = (html: string) => {
  const ret: Item[] = []
  let tmp = document.createElement('div')
  tmp.innerHTML = html
  tmp.querySelectorAll(':scope > li').forEach(li => {
    const item: Item = {
      type: 0,
      defence: 0,
      accuracy: 0, damage: 0,
      armoryId: 0,
      details: undefined,
      isDetailsLoading: false,
      amount: -1, isEquipped: false, id: -1, name: "", nameZh: "",
      bonus: ""
    }
    let elem = li as HTMLElement
    // 物品名
    let name: HTMLElement = elem.querySelector('.name-wrap .name')
    item.name = name.innerText.trim()
    item.nameZh = itemNameDict[item.name]
    // 堆叠数量
    item.amount = Number(elem.getAttribute('data-qty'))
    // id
    item.id = Number(elem.getAttribute('data-item'))
    // 装备
    item.isEquipped = elem.getAttribute('data-equipped').trim() === 'true'
    // 装备id
    item.armoryId = Number(elem.getAttribute('data-armoryid'))
    // 武器攻击
    item.damage = Number(elem.querySelector('.bonus-attachment-item-damage-bonus')?.nextElementSibling.innerText?.trim())
    // 武器命中
    item.accuracy = Number(elem.querySelector('.bonus-attachment-item-accuracy-bonus')?.nextElementSibling.innerText?.trim())
    // 装备防御
    item.defence = Number(elem.querySelector('.bonus-attachment-item-defence-bonus')?.nextElementSibling.innerText?.trim())
    // 装备类型
    item.type = Number(elem.querySelector('li[data-type][data-action="equip"][data-item][data-id]')?.getAttribute('data-type').trim())
    // 装备特效
    item.bonus = elem.querySelector('li.bonus i[class*="bonus-attachment"][title]')?.getAttribute('title').trim()

    ret.push(item)
  })
  return ret
}

let mouseOverItemId: number
const itemHover = async (item: Item) => {
  const thisId = item.id
  mouseOverItemId = item.id
  await Sleep(300)
  if (thisId === mouseOverItemId && !item.isDetailsLoading && !item.details) {
    item.isDetailsLoading = true
    try {
      item.details = await fetchItemDetails(item.id)
    } catch (e) {
    }
    item.isDetailsLoading = false
  }
}

const loadMore = async () => {
  if (disabledInfiniteLoading.value) return
  disabledInfiniteLoading.value = true
  let newItems: Item[]
  try {
    newItems = parseListHtml(await fetchList(itemList.value.length))
  } catch (e) {
    if (e.message !== '获取物品列表时没有内容') {
      ElMessage.error(e.message)
      logger.error(e.stack)
      throw e
    }
  }
  newItems.forEach(item => itemList.value.push(item))
  window.setTimeout(() => disabledInfiniteLoading.value = newItems.length < 1, 500)
}
const loadCategory = async (type: string) => {
  disabledInfiniteLoading.value = true
  categorySelected.value = type
  itemList.value = []
  itemList.value = parseListHtml(await fetchList(itemList.value.length))
  window.setTimeout(() => disabledInfiniteLoading.value = false, 500)
}

const _equipItem = async (item: Item) => {
  await equipItem(String(item.id), String(item.armoryId), item.type)
  item.isEquipped = !item.isEquipped
}

onMounted(async () => {
  itemList.value = parseListHtml(await fetchList())
})

</script>

<template>
  <el-button-group>
    <el-button v-for="item in categories" :disabled="item.value === categorySelected" @click="loadCategory(item.value)">
      {{ item.label }}
    </el-button>
  </el-button-group>
  <el-skeleton v-if="itemList.length === 0" :rows="5" animated/>
  <el-space size="default" style="margin-top: 0.5em;" wrap>
    <div v-for="item in itemList" v-infinite-scroll="loadMore" :infinite-scroll-delay="500"
         :infinite-scroll-disabled="disabledInfiniteLoading">
      <el-badge :hidden="item.amount < 2" :max="999" :value="item.amount">
        <el-popover :show-after="300" :width="240" trigger="hover">
          <template #reference>
            <el-card :body-style="{ padding: '0px' }" :style="item.isEquipped ? { borderColor: '#32CD32' } : null"
                     shadow="hover">
              <el-image :alt="item.id.toString()" :mouseover="itemHover(item)"
                        :src="`/images/items/${item.id}/medium.png`" style="width: 60px;height: 30px"/>
              <el-tag v-if="item.bonus">🌟</el-tag>
              <el-row v-if="item.damage > 0 && item.accuracy > 0">
                <el-col :span="12">
                  <el-tag>{{ item.damage }}</el-tag>
                </el-col>
                <el-col :span="12">
                  <el-tag>{{ item.accuracy }}</el-tag>
                </el-col>
              </el-row>
              <el-row v-if="item.defence > 0">
                <el-col :span="24">
                  <el-tag>{{ item.defence }}</el-tag>
                </el-col>
              </el-row>
            </el-card>
          </template>
          <el-row>
            <el-text v-if="item.nameZh" size="large">{{ item.nameZh }}</el-text>
          </el-row>
          <el-row>
            <el-text>{{ item.name }}<span v-if="item.armoryId"> - {{ item.armoryId }}</span></el-text>
          </el-row>
          <el-row v-if="item.damage">
            <el-text>攻击: {{ item.damage }}</el-text>
          </el-row>
          <el-row v-if="item.accuracy">
            <el-text>命中: {{ item.accuracy }}</el-text>
          </el-row>
          <el-row v-if="item.defence">
            <el-text>防御: {{ item.defence }}</el-text>
          </el-row>
          <el-row v-if="item.bonus">
            <el-text>特效: <span v-html="item.bonus"></span></el-text>
          </el-row>
          <el-row :gutter="4">
            <el-col :span="8">
              <el-button :icon="Check" @click="item.type ? _equipItem(item) : useItem(item.id.toString())"/>
            </el-col>
            <el-col :span="8">
              <el-button :icon="Delete" disabled/>
            </el-col>
            <el-col :span="8">
              <el-button :icon="Promotion" disabled/>
            </el-col>
          </el-row>
          <template v-if="item.details">
            <div v-if="item.isDetailsLoading || item.details?.itemInfoContent"
                 v-html="item.details?.itemInfoContent.replace(item.details?.itemInfo, '') || ''"></div>
            <el-row v-if="item.details.itemRareIcon">
              <el-text>稀有度: {{ item.details.itemRareIcon }}</el-text>
            </el-row>
            <el-row v-if="item.details.itemCirculation">
              <el-text>流通数: {{ item.details.itemCirculation }}</el-text>
            </el-row>
            <el-row v-if="item.details.itemValue">
              <el-text>估值: {{ item.details.itemValue }}</el-text>
            </el-row>
          </template>
        </el-popover>
      </el-badge>
    </div>
  </el-space>
</template>

<style scoped></style>
