import AtRule from './at-rule.js'
import Comment from './comment.js'
import Declaration from './declaration.js'
import Node, { ChildNode, ChildProps, NodeProps } from './node.js'
import Rule from './rule.js'

declare namespace Container {
  export class ContainerWithChildren<
    Child extends Node = ChildNode
  > extends Container_<Child> {
    nodes: Child[]
  }

  export interface ValueOptions {
    /**
     * String that’s used to narrow down values and speed up the regexp search.
     */
    fast?: string

    /**
     * An array of property names.
     */
    props?: string[]
  }

  export interface ContainerProps extends NodeProps {
    nodes?: (ChildNode | ChildProps)[]
  }

  // eslint-disable-next-line @typescript-eslint/no-use-before-define
  export { Container_ as default }
}

/**
 * The `Root`, `AtRule`, and `Rule` container nodes
 * inherit some common methods to help work with their children.
 *
 * Note that all containers can store any content. If you write a rule inside
 * a rule, PostCSS will parse it.
 */
declare abstract class Container_<Child extends Node = ChildNode> extends Node {
  /**
   * An array containing the container’s children.
   *
   * ```js
   * const root = postcss.parse('a { color: black }')
   * root.nodes.length           //=> 1
   * root.nodes[0].selector      //=> 'a'
   * root.nodes[0].nodes[0].prop //=> 'color'
   * ```
   */
  nodes: Child[] | undefined

  /**
   * Inserts new nodes to the end of the container.
   *
   * ```js
   * const decl1 = new Declaration({ prop: 'color', value: 'black' })
   * const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
   * rule.append(decl1, decl2)
   *
   * root.append({ name: 'charset', params: '"UTF-8"' })  // at-rule
   * root.append({ selector: 'a' })                       // rule
   * rule.append({ prop: 'color', value: 'black' })       // declaration
   * rule.append({ text: 'Comment' })                     // comment
   *
   * root.append('a {}')
   * root.first.append('color: black; z-index: 1')
   * ```
   *
   * @param nodes New nodes.
   * @return This node for methods chain.
   */
  append(
    ...nodes: (
      | ChildProps
      | ChildProps[]
      | Node
      | Node[]
      | string
      | string[]
      | undefined
    )[]
  ): this

  assign(overrides: Container.ContainerProps | object): this
  clone(overrides?: Partial<Container.ContainerProps>): Container<Child>
  cloneAfter(overrides?: Partial<Container.ContainerProps>): Container<Child>
  cloneBefore(overrides?: Partial<Container.ContainerProps>): Container<Child>

  /**
   * Iterates through the container’s immediate children,
   * calling `callback` for each child.
   *
   * Returning `false` in the callback will break iteration.
   *
   * This method only iterates through the container’s immediate children.
   * If you need to recursively iterate through all the container’s descendant
   * nodes, use `Container#walk`.
   *
   * Unlike the for `{}`-cycle or `Array#forEach` this iterator is safe
   * if you are mutating the array of child nodes during iteration.
   * PostCSS will adjust the current index to match the mutations.
   *
   * ```js
   * const root = postcss.parse('a { color: black; z-index: 1 }')
   * const rule = root.first
   *
   * for (const decl of rule.nodes) {
   *   decl.cloneBefore({ prop: '-webkit-' + decl.prop })
   *   // Cycle will be infinite, because cloneBefore moves the current node
   *   // to the next index
   * }
   *
   * rule.each(decl => {
   *   decl.cloneBefore({ prop: '-webkit-' + decl.prop })
   *   // Will be executed only for color and z-index
   * })
   * ```
   *
   * @param callback Iterator receives each node and index.
   * @return Returns `false` if iteration was broke.
   */
  each(
    callback: (node: Child, index: number) => false | void
  ): false | undefined

  /**
   * Returns `true` if callback returns `true`
   * for all of the container’s children.
   *
   * ```js
   * const noPrefixes = rule.every(i => i.prop[0] !== '-')
   * ```
   *
   * @param condition Iterator returns true or false.
   * @return Is every child pass condition.
   */
  every(
    condition: (node: Child, index: number, nodes: Child[]) => boolean
  ): boolean
  /**
   * Returns a `child`’s index within the `Container#nodes` array.
   *
   * ```js
   * rule.index( rule.nodes[2] ) //=> 2
   * ```
   *
   * @param child Child of the current container.
   * @return Child index.
   */
  index(child: Child | number): number

  /**
   * Insert new node after old node within the container.
   *
   * @param oldNode Child or child’s index.
   * @param newNode New node.
   * @return This node for methods chain.
   */
  insertAfter(
    oldNode: Child | number,
    newNode:
      | Child
      | Child[]
      | ChildProps
      | ChildProps[]
      | string
      | string[]
      | undefined
  ): this
  /**
   * Insert new node before old node within the container.
   *
   * ```js
   * rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop }))
   * ```
   *
   * @param oldNode Child or child’s index.
   * @param newNode New node.
   * @return This node for methods chain.
   */
  insertBefore(
    oldNode: Child | number,
    newNode:
      | Child
      | Child[]
      | ChildProps
      | ChildProps[]
      | string
      | string[]
      | undefined
  ): this

  /**
   * Traverses the container’s descendant nodes, calling callback
   * for each comment node.
   *
   * Like `Container#each`, this method is safe
   * to use if you are mutating arrays during iteration.
   *
   * ```js
   * root.walkComments(comment => {
   *   comment.remove()
   * })
   * ```
   *
   * @param callback Iterator receives each node and index.
   * @return Returns `false` if iteration was broke.
   */

  /**
   * Inserts new nodes to the start of the container.
   *
   * ```js
   * const decl1 = new Declaration({ prop: 'color', value: 'black' })
   * const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
   * rule.prepend(decl1, decl2)
   *
   * root.append({ name: 'charset', params: '"UTF-8"' })  // at-rule
   * root.append({ selector: 'a' })                       // rule
   * rule.append({ prop: 'color', value: 'black' })       // declaration
   * rule.append({ text: 'Comment' })                     // comment
   *
   * root.append('a {}')
   * root.first.append('color: black; z-index: 1')
   * ```
   *
   * @param nodes New nodes.
   * @return This node for methods chain.
   */
  prepend(
    ...nodes: (
      | ChildProps
      | ChildProps[]
      | Node
      | Node[]
      | string
      | string[]
      | undefined
    )[]
  ): this
  /**
   * Add child to the end of the node.
   *
   * ```js
   * rule.push(new Declaration({ prop: 'color', value: 'black' }))
   * ```
   *
   * @param child New node.
   * @return This node for methods chain.
   */
  push(child: Child): this

  /**
   * Removes all children from the container
   * and cleans their parent properties.
   *
   * ```js
   * rule.removeAll()
   * rule.nodes.length //=> 0
   * ```
   *
   * @return This node for methods chain.
   */
  removeAll(): this

  /**
   * Removes node from the container and cleans the parent properties
   * from the node and its children.
   *
   * ```js
   * rule.nodes.length  //=> 5
   * rule.removeChild(decl)
   * rule.nodes.length  //=> 4
   * decl.parent        //=> undefined
   * ```
   *
   * @param child Child or child’s index.
   * @return This node for methods chain.
   */
  removeChild(child: Child | number): this

  replaceValues(
    pattern: RegExp | string,
    replaced: { (substring: string, ...args: any[]): string } | string
  ): this

  /**
   * Passes all declaration values within the container that match pattern
   * through callback, replacing those values with the returned result
   * of callback.
   *
   * This method is useful if you are using a custom unit or function
   * and need to iterate through all values.
   *
   * ```js
   * root.replaceValues(/\d+rem/, { fast: 'rem' }, string => {
   *   return 15 * parseInt(string) + 'px'
   * })
   * ```
   *
   * @param pattern      Replace pattern.
   * @param {object} opts                Options to speed up the search.
   * @param callback   String to replace pattern or callback
   *                                     that returns a new value. The callback
   *                                     will receive the same arguments
   *                                     as those passed to a function parameter
   *                                     of `String#replace`.
   * @return This node for methods chain.
   */
  replaceValues(
    pattern: RegExp | string,
    options: Container.ValueOptions,
    replaced: { (substring: string, ...args: any[]): string } | string
  ): this

  /**
   * Returns `true` if callback returns `true` for (at least) one
   * of the container’s children.
   *
   * ```js
   * const hasPrefix = rule.some(i => i.prop[0] === '-')
   * ```
   *
   * @param condition Iterator returns true or false.
   * @return Is some child pass condition.
   */
  some(
    condition: (node: Child, index: number, nodes: Child[]) => boolean
  ): boolean

  /**
   * Traverses the container’s descendant nodes, calling callback
   * for each node.
   *
   * Like container.each(), this method is safe to use
   * if you are mutating arrays during iteration.
   *
   * If you only need to iterate through the container’s immediate children,
   * use `Container#each`.
   *
   * ```js
   * root.walk(node => {
   *   // Traverses all descendant nodes.
   * })
   * ```
   *
   * @param callback Iterator receives each node and index.
   * @return  Returns `false` if iteration was broke.
   */
  walk(
    callback: (node: ChildNode, index: number) => false | void
  ): false | undefined

  /**
   * Traverses the container’s descendant nodes, calling callback
   * for each at-rule node.
   *
   * If you pass a filter, iteration will only happen over at-rules
   * that have matching names.
   *
   * Like `Container#each`, this method is safe
   * to use if you are mutating arrays during iteration.
   *
   * ```js
   * root.walkAtRules(rule => {
   *   if (isOld(rule.name)) rule.remove()
   * })
   *
   * let first = false
   * root.walkAtRules('charset', rule => {
   *   if (!first) {
   *     first = true
   *   } else {
   *     rule.remove()
   *   }
   * })
   * ```
   *
   * @param name     String or regular expression to filter at-rules by name.
   * @param callback Iterator receives each node and index.
   * @return Returns `false` if iteration was broke.
   */
  walkAtRules(
    nameFilter: RegExp | string,
    callback: (atRule: AtRule, index: number) => false | void
  ): false | undefined

  walkAtRules(
    callback: (atRule: AtRule, index: number) => false | void
  ): false | undefined
  walkComments(
    callback: (comment: Comment, indexed: number) => false | void
  ): false | undefined

  walkComments(
    callback: (comment: Comment, indexed: number) => false | void
  ): false | undefined

  /**
   * Traverses the container’s descendant nodes, calling callback
   * for each declaration node.
   *
   * If you pass a filter, iteration will only happen over declarations
   * with matching properties.
   *
   * ```js
   * root.walkDecls(decl => {
   *   checkPropertySupport(decl.prop)
   * })
   *
   * root.walkDecls('border-radius', decl => {
   *   decl.remove()
   * })
   *
   * root.walkDecls(/^background/, decl => {
   *   decl.value = takeFirstColorFromGradient(decl.value)
   * })
   * ```
   *
   * Like `Container#each`, this method is safe
   * to use if you are mutating arrays during iteration.
   *
   * @param prop     String or regular expression to filter declarations
   *                 by property name.
   * @param callback Iterator receives each node and index.
   * @return Returns `false` if iteration was broke.
   */
  walkDecls(
    propFilter: RegExp | string,
    callback: (decl: Declaration, index: number) => false | void
  ): false | undefined

  walkDecls(
    callback: (decl: Declaration, index: number) => false | void
  ): false | undefined

  /**
   * Traverses the container’s descendant nodes, calling callback
   * for each rule node.
   *
   * If you pass a filter, iteration will only happen over rules
   * with matching selectors.
   *
   * Like `Container#each`, this method is safe
   * to use if you are mutating arrays during iteration.
   *
   * ```js
   * const selectors = []
   * root.walkRules(rule => {
   *   selectors.push(rule.selector)
   * })
   * console.log(`Your CSS uses ${ selectors.length } selectors`)
   * ```
   *
   * @param selector String or regular expression to filter rules by selector.
   * @param callback Iterator receives each node and index.
   * @return Returns `false` if iteration was broke.
   */
  walkRules(
    selectorFilter: RegExp | string,
    callback: (rule: Rule, index: number) => false | void
  ): false | undefined
  walkRules(
    callback: (rule: Rule, index: number) => false | void
  ): false | undefined
  /**
   * The container’s first child.
   *
   * ```js
   * rule.first === rules.nodes[0]
   * ```
   */
  get first(): Child | undefined
  /**
   * The container’s last child.
   *
   * ```js
   * rule.last === rule.nodes[rule.nodes.length - 1]
   * ```
   */
  get last(): Child | undefined
}

declare class Container<
  Child extends Node = ChildNode
> extends Container_<Child> {}

export = Container
