// @ts-nocheck

import videojs from 'video.js'
import 'videojs-contrib-quality-levels'
import type { QualityLevelList, QualityLevel } from 'videojs-contrib-quality-levels'
import i18n from '@/i18n'
import { getSetting } from '@/settingsManager'

export const createQualitySelector = (player: any) => {
  const qualityLevels: QualityLevelList = player.qualityLevels()
  const MenuButton = videojs.getComponent('MenuButton')
  const MenuItem = videojs.getComponent('MenuItem')
  let formatedQualities: { name: string; index: number; id: string; height: number }[] = []
  let startupQualityApplied = false

  const t = i18n.global.t
  const translatedAuto = t('player.auto')
  const autoLabel = translatedAuto === 'player.auto' ? 'Auto' : translatedAuto

  const setAutoQuality = () => {
    for (const quality of qualityLevels.levels_) {
      // Keep video renditions enabled and skip the audio-only pseudo-level.
      quality.enabled = quality.height !== undefined
    }

    qualityLevels.selectedIndex_ = -1
    qualityLevels.trigger({ type: 'change', selectedIndex: -1 })

    player.play().catch(() => {
      // Ignore autoplay restrictions; user interaction can resume.
    })
  }

  const setQuality = (id?: string) => {
    if (!id) {
      setAutoQuality()
      return
    }

    const found = formatedQualities.find((i) => i.id === id)
    if (!found) {
      setAutoQuality()
      return
    }

    for (const quality of qualityLevels.levels_) {
      if (quality.height === undefined) {
        quality.enabled = false
        continue
      }

      // Keep adaptive bitrate enabled up to the selected quality.
      quality.enabled = quality.height <= found.height
    }

    qualityLevels.selectedIndex_ = found?.index
    qualityLevels.trigger({ type: 'change', selectedIndex: found?.index })

    player.play().catch(() => {
      // Ignore autoplay restrictions; user interaction can resume.
    })
  }

  class CustomMenuButton extends MenuButton {
    options_: any
    player: any
    createItems() {
      const player = this.player()

      return this.options_.items.map((item: { name: string }) => {
        const qualitySelectorButton = new MenuItem(player, { label: item.name })

        qualitySelectorButton.handleClick = (data) => {
          const qualityClicked = data.currentTarget.innerText
          if (qualityClicked === autoLabel) {
            setAutoQuality()
            return
          }

          const id = formatedQualities.find((i) => i.name === qualityClicked)?.id

          if (id) {
            setQuality(id)
          }
        }

        return qualitySelectorButton
      })
    }

    buildCSSClass() {
      return `vjs-icon-cog ${super.buildCSSClass()}`
    }
  }
  videojs.registerComponent('CustomMenuButton', CustomMenuButton)
  const formattedLevels = []

  const updateLevels = () => {
    player.controlBar.removeChild('CustomMenuButton')
    player.controlBar.addChild('CustomMenuButton', {
      title: t('player.quality'),
      items: [{ name: autoLabel }, ...formatedQualities]
    })

    if (!startupQualityApplied) {
      startupQualityApplied = true
      const startingQuality = String(getSetting('defaultQuality'))
      const targetHeight = Number(startingQuality.replace(/[^0-9]/g, ''))

      if (!Number.isFinite(targetHeight) || targetHeight <= 0) {
        setAutoQuality()
        return
      }

      // Prefer exact/default match; otherwise keep auto mode so ABR can adapt.
      const id = formatedQualities.find((i) => i.height === targetHeight)?.id
      setQuality(id)
    }
  }

  qualityLevels.on('addqualitylevel', () => {
    formatedQualities = qualityLevels.levels_.map((quality: QualityLevel, index: number) => {
      let qualityFramerate = ''

      if (quality.frameRate > 30) {
        qualityFramerate = quality.frameRate
      }

      return {
        name: quality.height?.toString() + 'p' + qualityFramerate,
        index,
        id: quality.id,
        height: quality.height || 0
      }
    })

    // remove audio only
    const audioOnlyQuality = formatedQualities[formatedQualities.length - 1]
    if (audioOnlyQuality.name === 'undefinedp') {
      formatedQualities.splice(formatedQualities.length - 1, 1)
    }

    formattedLevels.push(formatedQualities)
    updateLevels()
  })
}
