import Browserbase from "@browserbasehq/sdk";
import { BrowserContext, Page } from "@playwright/test";
import { LLMProvider } from "../lib/llm/LLMProvider";
import { LogLine } from "./log";
import { AvailableModel, ClientOptions } from "./model";
import { z } from "zod";

export interface ConstructorParams {
  env: "LOCAL" | "BROWSERBASE";
  apiKey?: string;
  projectId?: string;
  verbose?: 0 | 1 | 2;
  debugDom?: boolean;
  llmProvider?: LLMProvider;
  headless?: boolean;
  logger?: (message: LogLine) => void;
  domSettleTimeoutMs?: number;
  browserBaseSessionCreateParams?: Browserbase.Sessions.SessionCreateParams;
  enableCaching?: boolean;
  browserbaseResumeSessionID?: string;
  modelName?: AvailableModel;
  modelClientOptions?: ClientOptions;
}

export interface InitResult {
  debugUrl: string;
  sessionUrl: string;
}

export interface InitOptions {
  modelName?: AvailableModel;
  modelClientOptions?: ClientOptions;
  domSettleTimeoutMs?: number;
}

export interface InitResult {
  debugUrl: string;
  sessionUrl: string;
}

export interface InitFromPageOptions {
  page: Page;
  modelName?: AvailableModel;
  modelClientOptions?: ClientOptions;
}

export interface InitFromPageResult {
  context: BrowserContext;
}

export interface ActOptions {
  action: string;
  modelName?: AvailableModel;
  modelClientOptions?: ClientOptions;
  useVision?: "fallback" | boolean;
  variables?: Record<string, string>;
  domSettleTimeoutMs?: number;
}

export interface ActResult {
  success: boolean;
  message: string;
  action: string;
}

export interface ExtractOptions<T extends z.AnyZodObject> {
  instruction: string;
  schema: T;
  modelName?: AvailableModel;
  modelClientOptions?: ClientOptions;
  domSettleTimeoutMs?: number;
}

export type ExtractResult<T extends z.AnyZodObject> = z.infer<T>;

export interface ObserveOptions {
  instruction?: string;
  modelName?: AvailableModel;
  modelClientOptions?: ClientOptions;
  useVision?: boolean;
  domSettleTimeoutMs?: number;
}

export interface ObserveResult {
  selector: string;
  description: string;
}
