// Global type declarations for vendor libraries and Phoenix LiveView

// Leaflet is assigned to window.L in app.ts
declare const L: typeof import("leaflet")

declare module "leaflet" {
  interface Map {
    createPane(name: string): HTMLElement
  }

  interface GridLayerOptions {
    opacity?: number
  }

  function gridLayer(options?: GridLayerOptions): GridLayer
}

// Phoenix LiveView hook interface
interface ViewHook {
  el: HTMLElement
  liveSocket: any
  pushEvent(event: string, payload: Record<string, unknown>): void
  pushEventTo(
    selectorOrTarget: string | HTMLElement,
    event: string,
    payload: Record<string, unknown>
  ): void
  handleEvent(event: string, callback: (payload: any) => void): void
  upload(name: string, files: FileList): void
}

// Vendor module declarations
declare module "../vendor/topbar" {
  const topbar: {
    config(opts: { barColors: Record<number, string>; shadowColor: string }): void
    show(delay?: number): void
    hide(): void
  }
  export default topbar
}

declare module "../vendor/chart.js" {
  export default class Chart {
    constructor(ctx: CanvasRenderingContext2D, config: any)
    destroy(): void
    options: any
    data: any
  }
}

// canvas-confetti UMD attaches to window.confetti as a side effect.
declare module "../vendor/canvas-confetti" {
  const _default: void
  export default _default
}

type ConfettiOptions = {
  particleCount?: number
  angle?: number
  spread?: number
  startVelocity?: number
  decay?: number
  gravity?: number
  drift?: number
  ticks?: number
  origin?: { x?: number; y?: number }
  colors?: string[]
  shapes?: string[]
  scalar?: number
  zIndex?: number
  disableForReducedMotion?: boolean
}

declare module "../vendor/leaflet/leaflet.js" {
  export = L
}

declare module "phoenix" {
  export class Socket {
    constructor(url: string, opts?: Record<string, unknown>)
  }
}

declare module "phoenix_html" {
  const _default: void
  export default _default
}

declare module "phoenix_live_view" {
  import { Socket } from "phoenix"

  export class LiveSocket {
    constructor(url: string, socketClass: typeof Socket, opts?: Record<string, unknown>)
    connect(): void
    enableDebug(): void
    enableLatencySim(ms: number): void
    disableLatencySim(): void
  }
}

declare module "phoenix-colocated/microwaveprop" {
  export const hooks: Record<string, object>
}

declare module "../../deps/live_stash/assets/js/live-stash.js" {
  export default function initLiveStash(
    params: Record<string, unknown>
  ): (params: Record<string, unknown>) => Record<string, unknown>
}

interface Window {
  L: typeof import("leaflet")
  liveSocket: any
  liveReloader: any
  confetti: (opts?: ConfettiOptions) => Promise<void> | null
}
