import { baseDomain } from "../../config"
import { get } from "svelte/store"
import { location } from "../store"
import type { SvelteComponent } from "svelte"

export function getCookie(name: string) {
    let cookieArr = document.cookie.split(";")
    for (let i = 0; i < cookieArr.length; i++) {
        let cookiePair = cookieArr[i].split("=")
        if (name === cookiePair[0].trim()) {
            return decodeURIComponent(cookiePair[1])
        }
    }
    return null
}

export function setCookie(name: string, value: string) {
    document.cookie = `${name}=${value}; domain=.${baseDomain}; path="/"; secure; samesite=none; max-age=31536000;`
}
export function deleteCookie(name: string) {
    document.cookie = `${name}=; domain=.${baseDomain}; path="/"; secure; SameSite=None; expires=Thu, 01 Jan 1970 00:00:00 GMT;`
}

function hasParentWithClass(element: HTMLElement, classname: string): any {
    if (typeof element.className == "string" && element.className.split(" ").indexOf(classname) >= 0) return true
    return element.parentNode && hasParentWithClass(element.parentNode as HTMLElement, classname)
}

export function clickOutside(node: Node, callback: Function) {
    const handleOutsideClick = ({ target }: MouseEvent) => {
        if (!node.contains(target as Node) && !hasParentWithClass(target as HTMLElement, "tooltip")) {
            callback(target)
        }
    }

    typeof window !== "undefined" && window.addEventListener("click", handleOutsideClick, true)

    return {
        destroy() {
            typeof window !== "undefined" && window.removeEventListener("click", handleOutsideClick, true)
        },
    }
}
export function getQueryParam(param: string) {
    return new URLSearchParams(get(location).search).get(param)
}

function removeWhitespaces(inputString: String) {
    return inputString.replace(/\s+/g, "")
}
interface Tooltip {
    when?: "hover" | "click"
    overflowContent?: any
    content:
        | string
        | {
              component: typeof SvelteComponent
              props?: {
                  [key: string]: any
              }
          }
    className?: string
    style?: string
}

export function tooltip(node: Node, data: Tooltip) {
    let span: HTMLElement
    let when: string
    let doOpen: (e?: any) => void, doClose: (e?: any) => void, clickOutside: (e?: any) => void

    function createTooltipContent(data: any) {
        if (!data) return

        if (typeof data.content === "string") {
            let clearedString = removeWhitespaces(data.content)
            if (!clearedString.length) return
        } else if (typeof data?.content?.props?.value === "string") {
            let clearedString = removeWhitespaces(data.content.props.value)
            if (!clearedString.length) return
        }

        const when = data.when || "hover"
        const span = document.createElement("div")

        const bubbleding = document.createElement("div")
        bubbleding.className = "bubbleding"
        span.appendChild(bubbleding)

        const content = document.createElement("div")
        content.className = "content"
        span.appendChild(content)

        const baseClass = "tooltip active " + (data.className || "")
        span.className = baseClass
        if (data.style) span.style.cssText = data.style
        let rendered = false
        doOpen = (e: MouseEvent) => {
            if (typeof data.content == "string") {
                content.innerHTML = ""
                // @ts-ignore

                if (node.scrollWidth > node.clientWidth && !data.forceShow) {
                    if (data.overflowContentIsComponent) {
                        const component = data.component.component
                        new component({
                            target: content,
                            props: {
                                ...data.component.props,
                            },
                        })
                    } else if (data.overflowContent && data.overflowContent !== "undefined")
                        content.innerHTML =
                            "<div style='width: 100%;'>" + "Vollständiger text: " + data.overflowContent + "</div>"
                } else {
                    if (data.content == "invalid") {
                        doClose()
                        return
                    }
                }
                if (data.content !== "invalid" && content.innerHTML) content.innerHTML += "<br />" + data.content
                else if (data.content !== "invalid") content.innerHTML = data.content
            } else if (typeof data.content == "object" && !rendered) {
                if (
                    data?.content?.props?.value == "invalid" &&
                    (data?.overflowContent || data?.overflowContentIsComponent)
                ) {
                    // @ts-ignore

                    if (node.scrollWidth > node.clientWidth) data.content.props.value = ""
                    else {
                        doClose()
                        return
                    }
                }
                rendered = true
                const component = data.content.component as typeof SvelteComponent

                new component({
                    target: content,
                    props: {
                        doClose,
                        ...data.content.props,
                    },
                })
                setTimeout(() => {
                    // @ts-ignore

                    if (node.scrollWidth > node.clientWidth) {
                        if (data.overflowContentIsComponent) {
                            const component = data.component.component
                            new component({
                                target: content,
                                props: {
                                    ...data.component.props,
                                },
                            })
                        } else if (data.overflowContent && data.overflowContent !== "undefined") {
                            content.innerHTML +=
                                "<br /><div style='width: 100%;'>" +
                                "Vollständiger text: " +
                                data.overflowContent +
                                "</div>"
                        }
                    }
                }, 100)
            }
            let dialog = document.getElementsByClassName("dialog-open")
            let fullWith = window.innerWidth
            let fullHeight = window.innerHeight

            let dialogOffset = { x: 0, y: 0 }
            if (dialog.length > 0) {
                fullWith = dialog[dialog.length - 1].clientWidth
                fullHeight = dialog[dialog.length - 1].clientHeight

                let rect = dialog[dialog.length - 1].getBoundingClientRect()
                dialogOffset.x = rect.left
                dialogOffset.y = rect.top
            }

            const mouseX = e.clientX
            const mouseY = e.clientY

            setTimeout(() => {
                let spanWidth = span.getBoundingClientRect().width

                let fixedCSSMarginLeft = 100
                let defaultOffset = spanWidth < 120 ? 120 : spanWidth - fixedCSSMarginLeft + 20

                let leftOffset = 0
                if (mouseX < defaultOffset) {
                    leftOffset = defaultOffset - mouseX
                }
                if (e.pageX > window.innerWidth - defaultOffset) {
                    leftOffset = defaultOffset * -1 + (fullWith - mouseX)
                }

                bubbleding.style.left = fixedCSSMarginLeft - leftOffset + "px"
                span.style.left = mouseX + leftOffset - dialogOffset.x + "px"

                if (data.className?.includes("bottom")) {
                    span.style.bottom = "auto"
                    span.style.top = mouseY + 20 - dialogOffset.y + "px"
                } else {
                    span.style.bottom = fullHeight - mouseY + 20 + dialogOffset.y + "px"
                }
            }, 0)

            if (!span.parentNode) {
                if (dialog.length > 0) {
                    dialog[dialog.length - 1].appendChild(span)
                } else {
                    document.body.appendChild(span)
                }
            }
        }
        doClose = (e) => {
            console.log("e:", e)
            e?.stopPropagation()
            e?.preventDefault()
            e?.stopImmediatePropagation()

            span.remove()
        }

        clickOutside = ({ target }) => {
            if (!span.contains(target)) {
                doClose()
            }
        }

        const closeBtn = document.createElement("span")
        closeBtn.innerHTML = "&#10005;"
        closeBtn.className = "tooltip-close"
        closeBtn.style.position = "absolute"
        closeBtn.style.top = "5px" // Positionieren Sie es oben
        closeBtn.style.right = "5px" // und rechts
        closeBtn.style.color = "#c4102d"
        closeBtn.style.cursor = "pointer" // Zeigen Sie den Cursor als Hand, um zu zeigen, dass es anklickbar ist
        closeBtn.addEventListener("click", doClose) // Fügt den Tooltip-Schließungs-Handler hinzu
        span.appendChild(closeBtn)
        span.addEventListener("click", (e) => {
            e.stopPropagation()
            e.preventDefault()
        })

        if (typeof window !== "undefined") {
            if (when == "click") {
                node.addEventListener("click", doOpen, true)
                window.addEventListener("click", clickOutside, true)
            } else {
                node.addEventListener("mouseover", doOpen, true)
                node.addEventListener("mousemove", doOpen, true)
                node.addEventListener("mouseout", doClose, true)
            }
            document.addEventListener("keydown", function (event) {
                if (event.key === "Escape") {
                    doClose()
                }
            })
        }

        return span
    }
    span = createTooltipContent(data)

    return {
        update(updatedData: any) {
            if (span && span.parentNode) {
                doClose() // This will handle the tooltip removal and its associated listeners
            }
            span = createTooltipContent(updatedData)
        },
        destroy() {
            Array.from(document.getElementsByClassName("tooltip")).forEach((el) => {
                el.remove()
            })

            if (typeof window !== "undefined") {
                if (when == "click") {
                    node.removeEventListener("click", doOpen, true)
                    window.removeEventListener("click", clickOutside, true)
                } else {
                    node.removeEventListener("mouseover", doOpen, true)
                    node.removeEventListener("mousemove", doOpen, true)
                    node.removeEventListener("mouseout", doClose, true)
                }
                document.addEventListener("keydown", function (event) {
                    if (event.key === "Escape") {
                        doClose()
                    }
                })
            }
        },
    }
}
export function stopScrolling(scrollPosition: { top: any; left: any }) {
    // Save the current scroll position
    scrollPosition.top = window.scrollY
    scrollPosition.left = window.scrollX

    // Add the no-scroll class to prevent scrolling
    document.body.classList.add("no-scroll")

    // Set the body's position to fixed, and adjust top/left to simulate the scroll position
    document.body.style.position = "fixed"
    document.body.style.top = `-${scrollPosition.top}px`
    document.body.style.left = `-${scrollPosition.left}px`
    document.body.style.right = "0"
    document.body.style.bottom = "0"
}

export function enableScrolling(scrollPosition: { top: any; left: any }) {
    // Remove the no-scroll class
    document.body.classList.remove("no-scroll")

    // Reset the body's positioning styles
    document.body.style.position = ""
    document.body.style.top = ""
    document.body.style.left = ""
    document.body.style.right = ""
    document.body.style.bottom = ""

    // Restore the scroll position after the styles are reset
    window.scrollTo(scrollPosition.left, scrollPosition.top)
}
