'use strict'

const stringWidth = require('string-width')
const stripAnsi = require('strip-ansi')
const wrap = require('wrap-ansi')

const align = {
  right: alignRight,
  center: alignCenter
}
const top = 0
const right = 1
const bottom = 2
const left = 3

class UI {
  constructor (opts) {
    this.width = opts.width
    this.wrap = opts.wrap
    this.rows = []
  }

  span (...args) {
    const cols = this.div(...args)
    cols.span = true
  }

  resetOutput () {
    this.rows = []
  }

  div (...args) {
    if (args.length === 0) {
      this.div('')
    }

    if (this.wrap && this._shouldApplyLayoutDSL(...args)) {
      return this._applyLayoutDSL(args[0])
    }

    const cols = args.map(arg => {
      if (typeof arg === 'string') {
        return this._colFromString(arg)
      }

      return arg
    })

    this.rows.push(cols)
    return cols
  }

  _shouldApplyLayoutDSL (...args) {
    return args.length === 1 && typeof args[0] === 'string' &&
      /[\t\n]/.test(args[0])
  }

  _applyLayoutDSL (str) {
    const rows = str.split('\n').map(row => row.split('\t'))
    let leftColumnWidth = 0

    // simple heuristic for layout, make sure the
    // second column lines up along the left-hand.
    // don't allow the first column to take up more
    // than 50% of the screen.
    rows.forEach(columns => {
      if (columns.length > 1 && stringWidth(columns[0]) > leftColumnWidth) {
        leftColumnWidth = Math.min(
          Math.floor(this.width * 0.5),
          stringWidth(columns[0])
        )
      }
    })

    // generate a table:
    //  replacing ' ' with padding calculations.
    //  using the algorithmically generated width.
    rows.forEach(columns => {
      this.div(...columns.map((r, i) => {
        return {
          text: r.trim(),
          padding: this._measurePadding(r),
          width: (i === 0 && columns.length > 1) ? leftColumnWidth : undefined
        }
      }))
    })

    return this.rows[this.rows.length - 1]
  }

  _colFromString (text) {
    return {
      text,
      padding: this._measurePadding(text)
    }
  }

  _measurePadding (str) {
    // measure padding without ansi escape codes
    const noAnsi = stripAnsi(str)
    return [0, noAnsi.match(/\s*$/)[0].length, 0, noAnsi.match(/^\s*/)[0].length]
  }

  toString () {
    const lines = []

    this.rows.forEach(row => {
      this.rowToString(row, lines)
    })

    // don't display any lines with the
    // hidden flag set.
    return lines
      .filter(line => !line.hidden)
      .map(line => line.text)
      .join('\n')
  }

  rowToString (row, lines) {
    this._rasterize(row).forEach((rrow, r) => {
      let str = ''
      rrow.forEach((col, c) => {
        const { width } = row[c] // the width with padding.
        const wrapWidth = this._negatePadding(row[c]) // the width without padding.

        let ts = col // temporary string used during alignment/padding.

        if (wrapWidth > stringWidth(col)) {
          ts += ' '.repeat(wrapWidth - stringWidth(col))
        }

        // align the string within its column.
        if (row[c].align && row[c].align !== 'left' && this.wrap) {
          ts = align[row[c].align](ts, wrapWidth)
          if (stringWidth(ts) < wrapWidth) {
            ts += ' '.repeat(width - stringWidth(ts) - 1)
          }
        }

        // apply border and padding to string.
        const padding = row[c].padding || [0, 0, 0, 0]
        if (padding[left]) {
          str += ' '.repeat(padding[left])
        }

        str += addBorder(row[c], ts, '| ')
        str += ts
        str += addBorder(row[c], ts, ' |')
        if (padding[right]) {
          str += ' '.repeat(padding[right])
        }

        // if prior row is span, try to render the
        // current row on the prior line.
        if (r === 0 && lines.length > 0) {
          str = this._renderInline(str, lines[lines.length - 1])
        }
      })

      // remove trailing whitespace.
      lines.push({
        text: str.replace(/ +$/, ''),
        span: row.span
      })
    })

    return lines
  }

  // if the full 'source' can render in
  // the target line, do so.
  _renderInline (source, previousLine) {
    const leadingWhitespace = source.match(/^ */)[0].length
    const target = previousLine.text
    const targetTextWidth = stringWidth(target.trimRight())

    if (!previousLine.span) {
      return source
    }

    // if we're not applying wrapping logic,
    // just always append to the span.
    if (!this.wrap) {
      previousLine.hidden = true
      return target + source
    }

    if (leadingWhitespace < targetTextWidth) {
      return source
    }

    previousLine.hidden = true

    return target.trimRight() + ' '.repeat(leadingWhitespace - targetTextWidth) + source.trimLeft()
  }

  _rasterize (row) {
    const rrows = []
    const widths = this._columnWidths(row)
    let wrapped

    // word wrap all columns, and create
    // a data-structure that is easy to rasterize.
    row.forEach((col, c) => {
      // leave room for left and right padding.
      col.width = widths[c]
      if (this.wrap) {
        wrapped = wrap(col.text, this._negatePadding(col), { hard: true }).split('\n')
      } else {
        wrapped = col.text.split('\n')
      }

      if (col.border) {
        wrapped.unshift('.' + '-'.repeat(this._negatePadding(col) + 2) + '.')
        wrapped.push("'" + '-'.repeat(this._negatePadding(col) + 2) + "'")
      }

      // add top and bottom padding.
      if (col.padding) {
        wrapped.unshift(...new Array(col.padding[top] || 0).fill(''))
        wrapped.push(...new Array(col.padding[bottom] || 0).fill(''))
      }

      wrapped.forEach((str, r) => {
        if (!rrows[r]) {
          rrows.push([])
        }

        const rrow = rrows[r]

        for (let i = 0; i < c; i++) {
          if (rrow[i] === undefined) {
            rrow.push('')
          }
        }

        rrow.push(str)
      })
    })

    return rrows
  }

  _negatePadding (col) {
    let wrapWidth = col.width
    if (col.padding) {
      wrapWidth -= (col.padding[left] || 0) + (col.padding[right] || 0)
    }

    if (col.border) {
      wrapWidth -= 4
    }

    return wrapWidth
  }

  _columnWidths (row) {
    if (!this.wrap) {
      return row.map(col => {
        return col.width || stringWidth(col.text)
      })
    }

    let unset = row.length
    let remainingWidth = this.width

    // column widths can be set in config.
    const widths = row.map(col => {
      if (col.width) {
        unset--
        remainingWidth -= col.width
        return col.width
      }

      return undefined
    })

    // any unset widths should be calculated.
    const unsetWidth = unset ? Math.floor(remainingWidth / unset) : 0

    return widths.map((w, i) => {
      if (w === undefined) {
        return Math.max(unsetWidth, _minWidth(row[i]))
      }

      return w
    })
  }
}

function addBorder (col, ts, style) {
  if (col.border) {
    if (/[.']-+[.']/.test(ts)) {
      return ''
    }

    if (ts.trim().length !== 0) {
      return style
    }

    return '  '
  }

  return ''
}

// calculates the minimum width of
// a column, based on padding preferences.
function _minWidth (col) {
  const padding = col.padding || []
  const minWidth = 1 + (padding[left] || 0) + (padding[right] || 0)
  if (col.border) {
    return minWidth + 4
  }

  return minWidth
}

function getWindowWidth () {
  /* istanbul ignore next: depends on terminal */
  if (typeof process === 'object' && process.stdout && process.stdout.columns) {
    return process.stdout.columns
  }
}

function alignRight (str, width) {
  str = str.trim()
  const strWidth = stringWidth(str)

  if (strWidth < width) {
    return ' '.repeat(width - strWidth) + str
  }

  return str
}

function alignCenter (str, width) {
  str = str.trim()
  const strWidth = stringWidth(str)

  /* istanbul ignore next */
  if (strWidth >= width) {
    return str
  }

  return ' '.repeat((width - strWidth) >> 1) + str
}

module.exports = function (opts = {}) {
  return new UI({
    width: opts.width || getWindowWidth() || /* istanbul ignore next */ 80,
    wrap: opts.wrap !== false
  })
}
