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

interface ValueOptions {
  /**
   * An array of property names.
   */
  props?: string[]

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

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

/**
 * 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.
 */
export default 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[]

  /**
   * 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

  /**
   * 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

  /**
   * 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 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: string | RegExp,
    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: string | RegExp,
    callback: (rule: Rule, index: number) => false | void
  ): false | undefined
  walkRules(
    callback: (rule: Rule, 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: string | RegExp,
    callback: (atRule: AtRule, index: number) => false | void
  ): false | undefined
  walkAtRules(
    callback: (atRule: AtRule, index: number) => false | void
  ): false | undefined

  /**
   * 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.
   */

  walkComments(
    callback: (comment: Comment, indexed: number) => false | void
  ): false | undefined
  walkComments(
    callback: (comment: Comment, indexed: number) => false | void
  ): false | 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: (Node | Node[] | ChildProps | ChildProps[] | string | string[])[]
  ): this

  /**
   * 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: (Node | Node[] | ChildProps | ChildProps[] | string | string[])[]
  ): 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

  /**
   * 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 | ChildProps | string | Child[] | ChildProps[] | string[]
  ): this

  /**
   * 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 | ChildProps | string | Child[] | ChildProps[] | string[]
  ): 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

  /**
   * 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

  /**
   * 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: string | RegExp,
    options: ValueOptions,
    replaced: string | { (substring: string, ...args: any[]): string }
  ): this
  replaceValues(
    pattern: string | RegExp,
    replaced: string | { (substring: string, ...args: any[]): string }
  ): this

  /**
   * 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 `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

  /**
   * 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
}
