/**
 * VibeOS SDK v1 — TypeScript definitions for window.vos.
 * https://apps.vibeoscloud.com/docs/sdk
 *
 * Add to your project (e.g. src/vibeos.d.ts) and window.vos is fully typed.
 * Errors reject with a plain Error — branch on err.message, not err.code.
 */
export {};

declare global {
  namespace VibeOS {
    interface DirEntry {
      name: string;
      /** "folder" for directories, otherwise the file type (usually its extension). */
      type: "folder" | (string & {});
    }

    interface FsChangeDetail {
      /** The folder that changed. Missing when the change can't be narrowed down. */
      affectedPath?: string;
    }

    interface FS {
      readDir(path: string): Promise<DirEntry[]>;
      /** Resolves to null when the file does not exist. */
      readFile(path: string, name: string): Promise<string | null>;
      /** Overwrites; creates parent folders automatically. */
      writeFile(path: string, name: string, content: string): Promise<boolean>;
      deleteFile(path: string, name: string): Promise<boolean>;
      /** Recursive. Refuses Home and the app's sandbox root. */
      deleteDir(path: string): Promise<boolean>;
      /** Full paths on both sides. */
      rename(fromPath: string, toPath: string): Promise<boolean>;
      move(fromPath: string, toPath: string): Promise<boolean>;
      /** Returns an unsubscribe function. */
      onChange(cb: (detail: FsChangeDetail) => void): () => void;
      /** Returns an unsubscribe function. */
      watch(path: string, cb: (detail: FsChangeDetail) => void, opts?: { debounceMs?: number }): () => void;
    }

    interface ChatMessage {
      role: "system" | "user" | "assistant";
      content: string;
    }

    interface CanUseResult {
      ok: boolean;
      code?:
        | "auth_required"
        | "upgrade_required"
        | "quota_exceeded"
        | "rate_limited"
        | "ai_disabled"
        | (string & {});
      requiredPlan?: string;
      message?: string;
    }

    interface AI {
      /** Entitlement check; never rejects. Fails open on network errors. */
      canUse(category?: "chat" | { category: string } | (string & {})): Promise<CanUseResult>;
      /** Resolves to the assistant's reply text. No streaming. */
      chat(messages: ChatMessage[]): Promise<string>;
    }

    interface NetResponse {
      status: number;
      statusText: string;
      headers: Record<string, string>;
      /** Text responses (text/*, JSON, XML…). */
      body?: string;
      /** Binary responses, base64-encoded. */
      bodyBase64?: string;
    }

    interface NetRequestInit {
      method?: "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS" | (string & {});
      headers?: Record<string, string>;
      body?: string | ArrayBuffer | ArrayBufferView;
    }

    interface Net {
      /** Resolves on any HTTP status; rejects on permission or network errors. */
      fetch(url: string, init?: NetRequestInit): Promise<NetResponse>;
    }

    interface AppInfo {
      name: string;
      id: string;
      closeBehavior: "close" | "minimize" | (string & {});
      sandboxPath: string;
      permissions: {
        hasRead: boolean;
        hasWrite: boolean;
        hasAi: boolean;
        hasNet: boolean;
        network: string[];
      };
    }

    interface App {
      getInfo(): Promise<AppInfo>;
    }

    interface Vos {
      fs: FS;
      ai: AI;
      net: Net;
      app: App;
    }

    /** Local-development helpers from vibeos-dev.js. Not available inside VibeOS. */
    interface DevTools {
      version: string;
      setKey(key: string): boolean;
      clearKey(): boolean;
      hasKey(): boolean;
      files(): Record<string, string>;
      exportFiles(): string;
      importFiles(data: string | Record<string, string>): number;
      resetFiles(): boolean;
      /** What the dev runtime is doing right now. */
      status(): {
        version: string;
        hasKey: boolean;
        fileCount: number;
        /** "vibe.json" | "inline" | "config" when permissions are checked; "missing" | "unreadable" | "none" when not. */
        permissionsFrom: "vibe.json" | "inline" | "config" | "missing" | "unreadable" | "none";
        permissionsChecked: boolean;
        openedAsFile: boolean;
        persistent: boolean;
      };
    }
  }

  interface Window {
    vos?: VibeOS.Vos;
    vosDev?: VibeOS.DevTools;
    VIBEOS_DEV?: {
      key?: string;
      apiBase?: string;
      manifest?: string;
      manifestData?: Record<string, unknown>;
      permissions?: { read?: string[]; write?: string[]; ai?: boolean; network?: string[] };
      name?: string;
      appId?: string;
      badge?: boolean;
      force?: boolean;
    };
  }

  interface WindowEventMap {
    "vos-ready": Event;
    "vos-fs-change": CustomEvent<VibeOS.FsChangeDetail>;
  }
}
