import type { Page } from "@playwright/test"

/**
 * Injects a visible CSS cursor overlay that follows mouse movements.
 * Features a glowing blue dot with an expanding ripple ring on click.
 *
 * Must be called BEFORE the first page.goto() (uses addInitScript).
 */
export async function injectVisibleCursor(page: Page, options?: { color?: string; size?: number }): Promise<void> {
    const color = options?.color ?? "59, 130, 246" // blue-500
    const size = options?.size ?? 24

    await page.addInitScript(
        ({ color, size }) => {
            document.addEventListener("DOMContentLoaded", () => {
                // Avoid duplicates on soft-navigations
                if (document.getElementById("pw-cursor")) return

                // ── Cursor dot ──
                const cursor = document.createElement("div")
                cursor.id = "pw-cursor"
                Object.assign(cursor.style, {
                    width: `${size}px`,
                    height: `${size}px`,
                    borderRadius: "50%",
                    background: `radial-gradient(circle, rgba(${color}, 0.9) 0%, rgba(${color}, 0.4) 60%, transparent 100%)`,
                    boxShadow: `0 0 ${size / 2}px rgba(${color}, 0.5), 0 0 ${size}px rgba(${color}, 0.2)`,
                    position: "fixed",
                    zIndex: "999999",
                    pointerEvents: "none",
                    transition: "transform 0.12s cubic-bezier(0.25, 0.46, 0.45, 0.94), box-shadow 0.12s ease",
                    transform: "translate(-50%, -50%)",
                    top: "-100px",
                    left: "-100px",
                })
                document.body.appendChild(cursor)

                // ── Click ripple animation ──
                const style = document.createElement("style")
                style.textContent = `
                    @keyframes pw-ripple {
                        0%   { transform: translate(-50%, -50%) scale(0.3); opacity: 0.8; }
                        100% { transform: translate(-50%, -50%) scale(2.5); opacity: 0; }
                    }
                    .pw-ripple {
                        position: fixed;
                        width: ${size * 2.5}px;
                        height: ${size * 2.5}px;
                        border-radius: 50%;
                        border: 2.5px solid rgba(${color}, 0.7);
                        pointer-events: none;
                        z-index: 999998;
                        animation: pw-ripple 0.5s cubic-bezier(0, 0, 0.2, 1) forwards;
                    }
                `
                document.head.appendChild(style)

                let cx = -100,
                    cy = -100

                document.addEventListener("mousemove", (e) => {
                    cx = e.clientX
                    cy = e.clientY
                    cursor.style.left = cx + "px"
                    cursor.style.top = cy + "px"
                })

                document.addEventListener("mousedown", () => {
                    // Shrink cursor + intensify glow
                    cursor.style.transform = "translate(-50%, -50%) scale(0.5)"
                    cursor.style.boxShadow = `0 0 ${size}px rgba(${color}, 0.8), 0 0 ${size * 1.5}px rgba(${color}, 0.4)`

                    // Spawn expanding ripple ring
                    const ripple = document.createElement("div")
                    ripple.className = "pw-ripple"
                    ripple.style.left = cx + "px"
                    ripple.style.top = cy + "px"
                    document.body.appendChild(ripple)
                    ripple.addEventListener("animationend", () => ripple.remove())
                })

                document.addEventListener("mouseup", () => {
                    cursor.style.transform = "translate(-50%, -50%) scale(1)"
                    cursor.style.boxShadow = `0 0 ${size / 2}px rgba(${color}, 0.5), 0 0 ${size}px rgba(${color}, 0.2)`
                })
            })
        },
        { color, size }
    )
}

/**
 * Moves the visible cursor smoothly to a target element before clicking.
 * This ensures mousemove events fire so the injected cursor follows along.
 */
export async function moveThenClick(page: Page, locator: ReturnType<Page["locator"]>): Promise<void> {
    const box = await locator.boundingBox()
    if (box) {
        const x = box.x + box.width / 2
        const y = box.y + box.height / 2
        // Smooth move in steps
        await page.mouse.move(x, y, { steps: 15 })
        await page.waitForTimeout(150)
    }
    await locator.click()
}

/**
 * Moves the visible cursor to a target element and types text character by character.
 * Simulates realistic typing for demo purposes.
 */
export async function moveThenType(
    page: Page,
    locator: ReturnType<Page["locator"]>,
    text: string,
    options?: { delay?: number }
): Promise<void> {
    const box = await locator.boundingBox()
    if (box) {
        const x = box.x + box.width / 2
        const y = box.y + box.height / 2
        await page.mouse.move(x, y, { steps: 15 })
        await page.waitForTimeout(150)
    }
    await locator.click()
    await page.waitForTimeout(200)
    await page.keyboard.type(text, { delay: options?.delay ?? 80 })
}

/**
 * Scrolls the page smoothly to a given position.
 */
export async function smoothScroll(page: Page, y: number, duration = 600): Promise<void> {
    await page.evaluate(
        ({ y, duration }) => {
            window.scrollTo({ top: y, behavior: "smooth" })
            return new Promise((r) => setTimeout(r, duration))
        },
        { y, duration }
    )
}
