import { type MouseEventHandler, forwardRef, useEffect, useMemo, useState } from 'react'
import type { BackendArt } from '../../functions/BackendTypes'
import { WEB_BASE } from '../../functions/Backend'
import { wtEvent } from '../../functions/Watchtower'
import { toast } from '../../functions/Context'
import './styles/ModalEmbed.css'

import VectorBackgroundEmbed from '../../vectors/background-embed.svg'
import HeaderMessage from './HeaderMessage'
import InputButtonRow from '../inputs/ButtonRow'
import InputButton from '../inputs/Button'
import InputDescription from '../inputs/Description'
import InputLabel from '../inputs/Label'

interface PropsForModalEmbed {
    item: BackendArt
    onClose: MouseEventHandler<HTMLButtonElement>
}

export default forwardRef<HTMLDialogElement, PropsForModalEmbed>(function ModalEmbed(
    { item, onClose }: PropsForModalEmbed,
    ref,
) {
    // Keep User Preferences
    const KEY_QUALITY = 'preference_embed_quality'
    const KEY_SCALE = 'preference_embed_scale'

    const [preferQuality, setQuality] = useState<'standard' | 'transparent'>(
        (() => {
            let raw = localStorage.getItem(KEY_QUALITY) ?? 'standard'
            if (raw !== 'standard' && raw !== 'transparent') {
                return 'standard'
            } else {
                return raw
            }
        })(),
    )

    const [preferScale, setScale] = useState<number>(
        (() => {
            let raw = localStorage.getItem(KEY_SCALE) ?? String('1')
            let val = parseFloat(raw)
            if (isNaN(val) || val < 0 || val > 1) return 1
            return val
        })(),
    )

    useEffect(() => localStorage.setItem(KEY_QUALITY, String(preferQuality)), [preferQuality])
    useEffect(() => localStorage.setItem(KEY_SCALE, String(preferScale)), [preferScale])

    // Calculate Embed Values
    const embedScale = useMemo(() => {
        const maxDim = Math.max(item.width, item.height)
        const baseScale = maxDim > 640 ? 640 / maxDim : 1
        return baseScale * preferScale
    }, [item.width, item.height, preferScale])

    const embedHeight = useMemo(() => (item.height * embedScale) | 0, [embedScale])
    const embedWidth = useMemo(() => (item.width * embedScale) | 0, [embedScale])

    // const embedQuality = useMemo(() => {
    //     if (preferQuality === 'standard.avif') return 'standard'
    //     return 'transparent'
    // }, [preferQuality])

    const embedHTML = useMemo(
        () =>
            `<iframe src="${WEB_BASE}/embed.html?id=${item.id}&quality=${preferQuality}" width="${embedWidth}" height="${embedHeight}" style="border:none; background: transparent" allowtransparency="true"></iframe>`,
        [preferQuality, embedScale],
    )

    function onCopy() {
        navigator.clipboard.writeText(embedHTML)
        toast('action-copy', 'Copied Code to Clipboard!')
        wtEvent('action_animation_embed_copy', {
            id: item.id,
            height: embedHeight,
            width: embedWidth,
            scale: (embedScale * 100) | 0,
            quality: preferQuality,
        })
    }

    return (
        <dialog ref={ref} className="modal-embed animation-fall-in animation-caution">
            <HeaderMessage label="MENU: Embed Generator" />
            <div className="wrapper">
                {/* Left-Pane */}
                <div className="preview">
                    <img className="background animation-fade-in" src={VectorBackgroundEmbed} />
                    <iframe
                        className="animation-fall-in"
                        style={{ border: 'none', background: 'transparent' }}
                        src={`${WEB_BASE}/embed.html?id=${item.id}&quality=${preferQuality}`}
                        width={embedWidth}
                        height={embedHeight}
                        allowTransparency
                    />
                </div>

                {/* Right-Pane */}
                <div className="toggles">
                    <InputLabel for="" label="Quality" />
                    <InputDescription>
                        We recommend using Standard quality, if you require transparency use Alpha quality.
                    </InputDescription>
                    <InputDescription>
                        Using more than three Alpha embeds may slow down your site, and up to twelve can be displayed at
                        any given time.
                    </InputDescription>
                    <InputButtonRow split={false}>
                        <InputButton
                            id="quality-alpha"
                            label="Alpha"
                            onClick={() => setQuality('transparent')}
                            selected={preferQuality === 'transparent'}
                            disabled={false}
                            rainbow={false}
                        />
                        <InputButton
                            id="quality-standard"
                            label="Standard"
                            onClick={() => setQuality('standard')}
                            selected={preferQuality === 'standard'}
                            disabled={false}
                            rainbow={false}
                        />
                    </InputButtonRow>

                    <InputLabel for="" label="Scale" />
                    <InputDescription>
                        Sizing is as follows: Small @ 320px; Medium @ 480px; Large @ 640px.
                    </InputDescription>
                    <InputDescription>If an image is too small, it wont get any larger.</InputDescription>
                    <InputButtonRow split={false}>
                        <InputButton
                            id="size-small"
                            label="Small"
                            selected={preferScale < 0.6}
                            onClick={() => setScale(0.5)}
                            disabled={false}
                            rainbow={false}
                        />
                        <InputButton
                            id="size-medium"
                            label="Medium"
                            selected={preferScale > 0.6 && preferScale < 0.9}
                            onClick={() => setScale(0.75)}
                            disabled={false}
                            rainbow={false}
                        />
                        <InputButton
                            id="size-large"
                            label="Large"
                            selected={preferScale > 0.9}
                            onClick={() => setScale(1)}
                            disabled={false}
                            rainbow={false}
                        />
                    </InputButtonRow>

                    <InputLabel for="" label="Code" />
                    <InputDescription>
                        Use this code snippet to display this {item.sticker ? 'sticker' : 'animation'} on your website.
                    </InputDescription>
                    <InputDescription>Clicking on the embed will direct users to gifuu in a new tab.</InputDescription>

                    <textarea
                        id="input-url"
                        className="input-url"
                        value={embedHTML}
                        onKeyDown={(e) => e.preventDefault()}
                    />

                    <InputLabel for="" label="" /* lazy divider */ />

                    <InputButtonRow split={true}>
                        <InputButton
                            id="action-copy"
                            label="Copy HTML"
                            onClick={onCopy}
                            selected={false}
                            disabled={false}
                            rainbow={false}
                        />
                        <InputButton
                            id="action-exit"
                            label="Exit"
                            onClick={onClose}
                            selected={false}
                            disabled={false}
                            rainbow={false}
                        />
                    </InputButtonRow>
                </div>
            </div>
        </dialog>
    )
})
