import {
    readFile,
    updateHTMLOptions,
    showRelatedHTML,
    syncHTMLValue,
    insertHTMLChild,
} from '@/components/helper'
import '@/components/background.css'
import buildConfig from '!/config.json'

export default class Background {
    #el = document.createElement('div')
    #parentEl
    #videoEl
    #default = {
        location: `${import.meta.env.BASE_URL}${buildConfig.build_assets_dir}${buildConfig.background_folder}/`,
        image: buildConfig.default_background,
    }
    #config = {
        video: {
            name: null,
            volume: 100,
        },
        useVideo: false,
        name: null,
    }

    constructor(el) {
        this.#parentEl = el
        this.#el.id = 'background-box'
        this.image = this.#default.location + this.#default.image
        this.#el.innerHTML = `
      <video autoplay loop disablepictureinpicture id="video-src" />
    `
        insertHTMLChild(this.#parentEl, this.#el)
    }

    async init() {
        this.#videoEl = document.getElementById('video-src')
    }

    resetImage() {
        document.getElementById('custom-background').value = ''
        document.getElementById('custom-background-clear').disabled = true
        this.#config.name = null
        this.image = this.#default.location + this.#default.image
    }

    resetVideo() {
        this.#config.video.name = null
        this.#videoEl.src = ''
        document.getElementById('custom-video-background').value = ''
        document.getElementById('custom-video-background-clear').disabled = true
    }

    reset() {
        this.resetImage()
        this.resetVideo()
    }

    get useVideo() {
        return this.#config.useVideo
    }

    set useVideo(v) {
        this.#config.useVideo = v
    }

    set image(v) {
        this.#el.style.backgroundImage = `url("${v}")`
    }

    set video(v) {
        if (!v) {
            this.resetVideo()
            return
        }
        const update = (url, v = null) => {
            this.#config.video.name = {
                isLocalFile: v !== null,
                value: v ? v.name : url,
            }
            this.#videoEl.src = url
            this.#videoEl.load()
            document.getElementById('custom-video-background-clear').disabled =
                false
        }
        if (typeof v === 'object') {
            readFile(v, (blobURL) => update(blobURL, v))
        } else {
            update(v)
        }
    }

    get volume() {
        return this.#config.video.volume
    }

    set volume(v) {
        v = parseInt(v)
        this.#config.video.volume = v
        this.#videoEl.volume = v / 100
    }

    get current() {
        return this.#config.name || this.#default.image
    }

    set default(v) {
        this.#default.image = v
        if (!this.#config.name)
            this.image = this.#default.location + this.#default.image
    }

    set custom(v) {
        if (!v) {
            this.resetImage()
            return
        }
        const update = (url, v = null) => {
            this.#config.name = {
                isLocalFile: v !== null,
                value: v ? v.name : url,
            }
            this.image = url
            document.getElementById('custom-background-clear').disabled = false
        }
        if (typeof v === 'object') {
            readFile(v, (blobURL) => update(blobURL, v))
        } else {
            update(v)
        }
    }

    get config() {
        return {
            default: this.#default.image,
            ...this.#config,
        }
    }

    get backCompatibilityFns() {
        const _this = this
        return {
            currentBackground: _this.current,
            setBackgoundImage: (v) => (_this.image = v),
            setDefaultBackground: (v) => (_this.default = v),
            setBackground: (v) => (_this.custom = v),
            resetBackground: _this.resetImage,
            setVideo: (e) => (_this.video = e.target.files[0]),
            getVideoVolume: () => _this.volume,
            setVideoVolume: (v) => (_this.volume = v),
            setVideoFromWE: (url) => (_this.video = url),
            resetVideo: _this.resetVideo,
        }
    }

    get HTML() {
        return `
    <div>
      <div>
        <label for="default-background-select">Choose a default background:</label>
        <select name="default-backgrounds" id="default-background-select">
            ${updateHTMLOptions(buildConfig.background_files, null, this.#default.image)}
        </select>
      </div>
      <div>
        <label for="custom-background">Custom Background (Store Locally)</label>
        <input type="file" id="custom-background" accept="image/*"/>
        <button type="button" id="custom-background-clear" ${this.#config.name ? (this.#config.name.isLocalFile ? '' : 'disabled') : 'disabled'}>Clear</button>
      </div>
      <div>
        <label for="custom-background-url">Custom Background URL:</label>
        <input type="text" id="custom-background-url" name="custom-background-url" value="${this.#config.name ? this.#config.name.value : ''}">
        <button type="button" id="custom-background-url-apply">Apply</button>
      </div>
    </div>
    <div>
      <label for="video">Video</label>
      <input type="checkbox" id="video" name="video" ${this.useVideo ? 'checked' : ''}/>
      <div id="video-realted" ${this.useVideo ? '' : 'hidden'}>
        <div>
          <label for="custom-video-background">Custom Video Background (Store Locally)</label>
          <input type="file" id="custom-video-background" accept="video/*"/>
          <button type="button" id="custom-video-background-clear" ${this.#config.video.name ? (this.#config.video.name.isLocalFile ? '' : 'disabled') : 'disabled'}>Clear</button>
        </div>
        <div>
          <label for="custom-video-background-url">Custom Video Background URL:</label>
          <input type="text" id="custom-video-background-url" name="custom-video-background-url"  value="${this.#config.video.name ? this.#config.video.name.value : ''}">
          <button type="button" id="custom-video-background-url-apply">Apply</button>
        </div>
        <div>
          <label for="video-volume">Video Volume</label>
          <input type="range" min="0" max="100" step="1" id="video-volume-slider" value="${this.volume}" />
          <input type="number" id="video-volume-input"  min="0" max="100" step="1" name="video-volume" value="${this.volume}" />
        </div>
      </div>
    </div>
    `
    }

    get listeners() {
        return [
            {
                id: 'default-background-select',
                event: 'change',
                handler: (e) => {
                    this.default = e.currentTarget.value
                },
            },
            {
                id: 'custom-background',
                event: 'change',
                handler: (e) => (this.custom = e.target.files[0]),
            },
            {
                id: 'custom-background-clear',
                event: 'click',
                handler: () => this.resetImage(),
            },
            {
                id: 'custom-background-url-apply',
                event: 'click',
                handler: () =>
                    (this.custom = document.getElementById(
                        'custom-background-url'
                    ).value),
            },
            {
                id: 'video',
                event: 'click',
                handler: (e) => {
                    showRelatedHTML(e.currentTarget, 'video-realted')
                    this.useVideo = e.currentTarget.checked
                    if (!e.currentTarget.checked) this.resetVideo()
                },
            },
            {
                id: 'custom-video-background',
                event: 'change',
                handler: (e) => (this.video = e.target.files[0]),
            },
            {
                id: 'custom-video-background-clear',
                event: 'click',
                handler: () => this.resetVideo(),
            },
            {
                id: 'custom-video-background-url-apply',
                event: 'click',
                handler: () =>
                    (this.video = document.getElementById(
                        'custom-video-background-url'
                    ).value),
            },
            {
                id: 'video-volume-slider',
                event: 'input',
                handler: (e) => {
                    syncHTMLValue(e.currentTarget, 'video-volume-input')
                    this.volume = e.currentTarget.value
                },
            },
            {
                id: 'video-volume-input',
                event: 'change',
                handler: (e) => {
                    syncHTMLValue(e.currentTarget, 'video-volume-slider')
                    this.volume = e.currentTarget.value
                },
            },
        ]
    }

    applyConfig(key, value) {
        switch (key) {
            case 'default':
                this.default = value
                break
            case 'custom':
                this.custom = value
                break
            case 'video':
                this.video = value
                break
            case 'volume':
                this.volume = value
                break
            default:
                return
        }
    }
}
