/// <reference types="vite/client" />

// ============================================================
// Vite 环境变量类型声明
// ============================================================

interface ImportMetaEnv {
  readonly VITE_AMAP_JSAPI_KEY: string
  readonly VITE_AMAP_WEB_KEY: string
  /** 高德安全密钥 — 2021/12/02 后申请的 Key 必须配置，否则 Driving 等服务报 INVALID_USER_SCODE */
  readonly VITE_AMAP_SECURITY_CODE: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

// ============================================================
// 高德地图 AMap 全局类型声明
// ============================================================

/** 高德地图 JSAPI v2 命名空间 */
declare namespace AMap {
  interface MapOptions {
    center?: [number, number]
    zoom?: number
    viewMode?: '2D' | '3D'
    resizeEnable?: boolean
    pitch?: number
    [key: string]: any
  }

  class Map {
    constructor(container: HTMLElement | string, opts?: MapOptions)
    setCenter(center: [number, number]): void
    setZoom(zoom: number): void
    setZoomAndCenter(zoom: number, center: [number, number]): void
    resize(): void
    add(overlay: any): void
    remove(overlay: any): void
    clearMap(): void
    destroy(): void
    on(event: string, handler: (...args: any[]) => void): void
    off(event: string, handler: (...args: any[]) => void): void
    setStatus(status: Partial<{ doubleClickZoom: boolean; dragEnable: boolean; zoomEnable: boolean }>): void
    getStatus(): { doubleClickZoom: boolean; dragEnable: boolean; zoomEnable: boolean }
    setDefaultCursor(cursor: string): void
    getDefaultCursor(): string
    getCenter(): { lng: number; lat: number }
    lngLatToContainer(lnglat: { lng: number; lat: number }): { x: number; y: number }
    /** 设置底图要素显示：'bg'=背景, 'road'=道路, 'building'=建筑, 'point'=POI标注 */
    setFeatures(features: string[]): void
    getFeatures(): string[]
  }

  class Geocoder {
    constructor(opts?: Record<string, any>)
  }
  class AutoComplete {
    constructor(opts?: Record<string, any>)
  }
  class PlaceSearch {
    constructor(opts?: Record<string, any>)
  }
  /** 高德定位插件 — IP + 基站定位，精度低于浏览器 GPS */
  interface GeolocationOptions {
    /** 是否使用高精度定位，默认 true */
    enableHighAccuracy?: boolean
    /** 超时时间（毫秒），默认 Infinity */
    timeout?: number
    /** 定位成功后是否调整地图视野到定位精度范围，默认 false */
    zoomToAccuracy?: boolean
    /** 定位按钮的停靠位置：LT | RT | LB | RB */
    position?: 'LT' | 'RT' | 'LB' | 'RB'
    /** 定位按钮偏移量 [x, y] */
    offset?: [number, number]
    /** 是否显示定位按钮，默认 true */
    showButton?: boolean
    /** 定位成功后是否将定位点作为地图中心，默认 true */
    panToLocation?: boolean
    [key: string]: any
  }

  interface GeolocationResult {
    position: { lng: number; lat: number }
    accuracy: number
    formattedAddress: string
    addressComponent: {
      province: string
      city: string
      district: string
      township: string
      street: string
      streetNumber: string
    }
    message?: string
  }

  class Geolocation {
    constructor(opts?: AMap.GeolocationOptions)
    /** 获取当前位置 */
    getCurrentPosition(
      callback: (status: 'complete' | 'error', result: AMap.GeolocationResult) => void
    ): void
    /** 取消定位请求 */
    cancelWatch(): void
  }
  class MarkerClusterer {
    constructor(map: Map, markers: any[], opts?: Record<string, any>)
  }

  // ── 经纬度 ──
  class LngLat {
    constructor(lng: number, lat: number)
    lng: number
    lat: number
    getLng(): number
    getLat(): number
  }

  // ── 覆盖物基类 ──
  class Overlay {
    setMap(map: Map | null): void
    getMap(): Map | null
    destroy(): void
    show(): void
    hide(): void
  }

  // ── 点标记 ──
  interface MarkerOptions {
    position?: [number, number]
    content?: string
    icon?: string | Icon
    offset?: Pixel
    draggable?: boolean
    zIndex?: number
    [key: string]: any
  }

  class Marker extends Overlay {
    constructor(opts?: MarkerOptions)
    setPosition(position: [number, number]): void
    getPosition(): { lng: number; lat: number }
    on(event: string, handler: (...args: any[]) => void): void
    off(event: string, handler: (...args: any[]) => void): void
  }

  // ── 像素偏移 ──
  class Pixel {
    constructor(x: number, y: number)
  }

  // ── 图标 ──
  interface IconOptions {
    size?: [number, number]
    image?: string
    imageSize?: [number, number]
    imageOffset?: [number, number]
  }
  class Icon {
    constructor(opts?: IconOptions)
  }

  // ── 多边形 ──
  interface PolygonOptions {
    path?: [number, number][]
    fillColor?: string
    fillOpacity?: number
    strokeColor?: string
    strokeWeight?: number
    strokeOpacity?: number
    strokeStyle?: 'solid' | 'dashed'
    zIndex?: number
    [key: string]: any
  }

  class Polygon extends Overlay {
    constructor(opts?: PolygonOptions)
    setPath(path: [number, number][]): void
    getPath(): [number, number][]
  }

  // ── 折线（绘制围栏时连线预览）──
  interface PolylineOptions {
    path?: [number, number][]
    strokeColor?: string
    strokeWeight?: number
    strokeOpacity?: number
    strokeStyle?: 'solid' | 'dashed'
    borderWeight?: number
    zIndex?: number
    [key: string]: any
  }

  class Polyline extends Overlay {
    constructor(opts?: PolylineOptions)
    setPath(path: [number, number][]): void
    getPath(): [number, number][]
  }

  // ── 圆形 ──
  interface CircleOptions {
    center?: [number, number]
    radius?: number
    fillColor?: string
    fillOpacity?: number
    strokeColor?: string
    strokeWeight?: number
    strokeOpacity?: number
    zIndex?: number
    [key: string]: any
  }

  class Circle extends Overlay {
    constructor(opts?: CircleOptions)
    setCenter(center: [number, number]): void
    getCenter(): { lng: number; lat: number }
    setRadius(radius: number): void
    getRadius(): number
    contains(point: [number, number]): boolean
  }

  // ── 几何计算工具 ──
  namespace GeometryUtil {
    function isPointInRing(point: { lng: number; lat: number }, path: [number, number][]): boolean
    function distance(p1: [number, number], p2: [number, number]): number
  }

  // ── 鼠标绘制工具 ──
  interface MouseToolOptions {
    [key: string]: any
  }
  class MouseTool {
    constructor(map: Map, opts?: MouseToolOptions)
    polygon(opts?: Record<string, any>): void
    circle(opts?: Record<string, any>): void
    rectangle(opts?: Record<string, any>): void
    close(): void
    on(event: string, handler: (...args: any[]) => void): void
    off(event: string, handler: (...args: any[]) => void): void
  }

  // ── 信息窗体 ──
  interface InfoWindowOptions {
    content?: string
    position?: [number, number]
    offset?: Pixel
    [key: string]: any
  }
  class InfoWindow extends Overlay {
    constructor(opts?: InfoWindowOptions)
    open(map: Map, position?: [number, number]): void
    close(): void
    setContent(content: string): void
  }

  // ── 图片图层（ImageLayer）──
  interface ImageLayerOptions {
    /** 图片 URL */
    url: string
    /** 图片覆盖的地理范围（西南角 + 东北角） */
    bounds: Bounds | [number, number, number, number]
    /** 显示的缩放级别范围 [min, max] */
    zooms?: [number, number]
    /** 透明度 0-1，默认 1 */
    opacity?: number
    /** 图层叠加顺序，默认 6 */
    zIndex?: number
    [key: string]: any
  }

  class ImageLayer {
    constructor(opts: ImageLayerOptions)
    setMap(map: Map | null): void
    setBounds(bounds: Bounds | [number, number, number, number]): void
    setZooms(zooms: [number, number]): void
    setOpacity(opacity: number): void
    setzIndex(zIndex: number): void
    getBounds(): Bounds
    getOpacity(): number
    getzIndex(): number
    show(): void
    hide(): void
    destroy(): void
  }

  // ── 地理范围（Bounds）──
  class Bounds {
    constructor(southWest: [number, number], northEast: [number, number])
    /** 返回西南角坐标 */
    getSouthWest(): { lng: number; lat: number }
    /** 返回东北角坐标 */
    getNorthEast(): { lng: number; lat: number }
    /** 判断某点是否在范围内 */
    contains(point: [number, number] | { lng: number; lat: number }): boolean
  }

  // ── 驾车路线规划 ──
  interface DrivingOptions {
    map?: Map
    panel?: string | HTMLElement
    policy?: number  // 0-5 驾车策略
    [key: string]: any
  }

  interface DrivingStep {
    path: { lng: number; lat: number }[]
    instruction: string
    distance: number
    [key: string]: any
  }

  interface DrivingRoute {
    steps: DrivingStep[]
    distance: number
    time: number
    policy: string
    [key: string]: any
  }

  interface DrivingResult {
    routes: DrivingRoute[]
    info: string
    origin: { lng: number; lat: number }
    destination: { lng: number; lat: number }
    [key: string]: any
  }

  class Driving {
    constructor(opts?: DrivingOptions)
    search(
      origin: [number, number] | { keyword: string; city?: string },
      destination: [number, number] | { keyword: string; city?: string },
      callback: (status: string, result: DrivingResult) => void
    ): void
    clear(): void
  }
}

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<object, object, unknown>
  export default component
}

// ============================================================
// @micro-zoe/micro-app 全局类型声明
// ============================================================

interface Window {
  /**
   * micro-app 注入的环境标识 — 子应用是否运行在微前端环境中
   * 用于判断是否导出 mount/unmount 生命周期
   */
  __MICRO_APP_ENVIRONMENT__?: boolean

  /**
   * micro-app 注入的应用名称 — 等于主应用中配置的 name 字段
   */
  __MICRO_APP_NAME__?: string

  /**
   * micro-app 注入的基础路由 — 等于主应用中配置的 baseroute
   * 子应用的 Vue Router base 应使用此值
   */
  __MICRO_APP_BASE_ROUTE__?: string

  /**
   * micro-app 注入的公共路径 — 用于拼接静态资源路径
   */
  __MICRO_APP_PUBLIC_PATH__?: string

  /**
   * micro-app 子应用通信 API
   */
  microApp?: {
    /** 获取主应用 setData 传递的数据 */
    getData(): Record<string, any>
    /** 监听主应用推送的数据 */
    addDataListener(callback: (data: any) => void, autoTrigger?: boolean): void
    /** 移除数据监听 */
    removeDataListener(callback: (data: any) => void): void
    /** 向主应用发送数据 */
    dispatch(data: Record<string, any>): void

    // ============================================================
    // globalData API — 全局状态池（主应用 + 所有子应用共享）
    // ============================================================
    /** 获取全局数据 */
    getGlobalData(): Record<string, any> | null
    /** 设置全局数据（广播给主应用和所有子应用） */
    setGlobalData(data: Record<string, any>): void
    /** 监听全局数据变化 */
    addGlobalDataListener(callback: (data: any) => void, autoTrigger?: boolean): void
    /** 移除全局数据监听 */
    removeGlobalDataListener(callback: (data: any) => void): void
  }
}
