// Browser Module - Effects for browser/DOM interaction
//
// This module provides effects for interacting with the browser DOM,
// local storage, and other browser APIs.

// Opaque Element type (represents a DOM element)
type Element =
    | DomElement(Int)

// DOM manipulation effect
effect Dom {
    fn getElementById(id: String): Option<Element>
    fn querySelector(selector: String): Option<Element>
    fn querySelectorAll(selector: String): List<Element>
    fn createElement(tag: String): Element
    fn createTextNode(text: String): Element
    fn appendChild(parent: Element, child: Element): Unit
    fn removeChild(parent: Element, child: Element): Unit
    fn setAttribute(element: Element, name: String, value: String): Unit
    fn removeAttribute(element: Element, name: String): Unit
    fn setProperty(element: Element, name: String, value: String): Unit
    fn setTextContent(element: Element, text: String): Unit
    fn getBody(): Element
    fn focus(element: Element): Unit
    fn blur(element: Element): Unit
}

// Browser storage effect
effect Storage {
    fn getItem(key: String): Option<String>
    fn setItem(key: String, value: String): Unit
    fn removeItem(key: String): Unit
    fn clear(): Unit
}

// Browser navigation effect
effect Navigation {
    fn pushState(url: String): Unit
    fn replaceState(url: String): Unit
    fn back(): Unit
    fn forward(): Unit
    fn getLocation(): String
    fn getPathname(): String
}

// Browser window effect
effect Window {
    fn alert(message: String): Unit
    fn confirm(message: String): Bool
    fn scrollTo(x: Int, y: Int): Unit
    fn getInnerWidth(): Int
    fn getInnerHeight(): Int
}

// ============================================================================
// Subscription types for listening to external events
// ============================================================================

type Sub<M> =
    | OnAnimationFrame(fn(Float): M)
    | OnResize(fn(Int, Int): M)
    | OnKeyPress(fn(String): M)
    | OnKeyDown(fn(String): M)
    | OnKeyUp(fn(String): M)
    | OnMouseMove(fn(Int, Int): M)
    | OnClick(fn(Int, Int): M)
    | OnUrlChange(fn(String): M)
    | Every(Int, fn(Float): M)
    | NoSub

// Subscription constructors
fn onAnimationFrame<M>(toMsg: fn(Float): M): Sub<M> =
    OnAnimationFrame(toMsg)

fn onResize<M>(toMsg: fn(Int, Int): M): Sub<M> =
    OnResize(toMsg)

fn onKeyPress<M>(toMsg: fn(String): M): Sub<M> =
    OnKeyPress(toMsg)

fn every<M>(ms: Int, toMsg: fn(Float): M): Sub<M> =
    Every(ms, toMsg)

fn noSub<M>(): Sub<M> =
    NoSub

// Combine multiple subscriptions
fn batch<M>(subs: List<Sub<M>>): List<Sub<M>> =
    subs
