import type { GoToOptions } from 'puppeteer'

export interface obj {
  [key: string]: any
}

export interface Target {
  /**等待元素加载的css选择器 */
  waitCss?: string
  actions?: Array<{
    /** 动作类型 */
    type: string // 'click' | 'input' |'scroll' | 'wait' | 'custom'
    /** 动作目标css选择器 */
    css: string
    /** value值 */
    value?: string | number
    /** 动作执行延迟时间 */
    delay?: number
    /** 以来的css */
    waitCss?: string
  }>
  /** 爬取属性设置 */
  values: Array<{
    /** 返回的对象属性名 */
    label: string
    /** 要爬取的链接css选择器 */
    css?: string | string[]
    /** 要爬取的属性, 如果不设置则默认取元素的textContent */
    attr?: string
    /** 是否爬取全部: 默认false, <true: querySelectorAll, false: querySelector> */
    all?: boolean
    /** 弱水三千，只取一瓢：配合all=true使用 */
    allIdx?: number
    /** 循环对象 */
    loopOpt?: CrawlOptions
  }>
}

export interface CrawlOptionsCore extends CrawlOptions {
  /** 插件配置列表 */
  plugs?: {
    /** 前置函数 */
    beforePlug?: () => boolean | Promise<boolean>
    /** 后置函数, 返回false则 */
    afterPlug?: (o: obj) => false | Promise<obj>
    /** 回调函数 */
    callbackPlug?: (o: obj) => obj | Promise<obj>
    /** 报错函数 */
    errorPlug?: (err: any) => void
    /** 最终执行函数 */
    finallyPlug?: (o?: obj) => void
    /** 爬取插件 */
    crawlPlug?: (values?: Target['values'], win?: Window) => obj[] | Promise<obj[]>
  }
}

export interface CrawlOptions {
  /** 名 */
  name?: string
  /** 爬取模式: 默认dynamic */
  mode?: 'static' | 'dynamic'
  /** 要爬取的页面地址 */
  url?: string
  /** 超时时间: 默认60s */
  timeout?: number
  /** 延迟时间 */
  delayTime?: number
  /** 页面加载配置 */
  pageOpts?: GoToOptions
  /** 要爬取的目标 */
  target: Target
  /** 前置函数 */
  before?: () => boolean | Promise<boolean>
  /** 后置函数, 如果返回false则终止爬取，否者会把值传给后续继续处理 */
  after?: (obj: object) => false | Promise<obj>
  /** 回调函数 */
  callback?: (obj: object) => obj | Promise<obj>
  /** 报错函数 */
  error?: (err: any) => void
  /** 最终执行函数 */
  finally?: (obj?: object) => void
  /** 自循环递归 */
  recursion?: {
    /** 循环的key */
    loopKey: string
    /** 循环需要取值target.values的label值，会统计成一个object */
    loopVals: string[]
  }
}

export interface IProps {
  host?: string
  showLog?: boolean /** 是否打印日志信息 */
}
