import dayjs from 'dayjs'

const relativeTime = require('dayjs/plugin/relativeTime')
const utc = require('dayjs/plugin/utc')
dayjs.extend(utc)
dayjs.extend(relativeTime)

export function calculateDiff(date) {
  return dayjs.utc(date).fromNow()
}

export const isEmail = v => /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i.test(v)

// ref : https://stackoverflow.com/a/5717133
export const isValidURL = (str) => {
  const pattern = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00A1-\uFFFF0-9]-*)*[a-z\u00A1-\uFFFF0-9]+)(?:\.(?:[a-z\u00A1-\uFFFF0-9]-*)*[a-z\u00A1-\uFFFF0-9]+)*(?:\.(?:[a-z\u00A1-\uFFFF]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i
  return !!pattern.test(str)
}

export const parseIfInteger = v => /^\d+$/.test(v) ? +v : v

// ref : https://stackoverflow.com/a/11077016
export function insertAtCursor(myField, myValue, len = 0, b = 0) {
  // IE support
  if (document.selection) {
    myField.focus()
    const sel = document.selection.createRange()
    sel.text = myValue
  } // MOZILLA and others
  else if (myField.selectionStart || myField.selectionStart == '0') {
    const startPos = myField.selectionStart
    const endPos = myField.selectionEnd
    myField.value = myField.value.substring(0, startPos - len) +
      myValue +
      myField.value.substring(endPos, myField.value.length)

    const pos = +startPos - len + myValue.length - b
    // https://stackoverflow.com/a/4302688
    if (myField.setSelectionRange) {
      myField.focus()
      myField.setSelectionRange(pos, pos)
    } else if (myField.createTextRange) {
      const range = myField.createTextRange()
      range.collapse(true)
      range.moveEnd('character', pos)
      range.moveStart('character', pos)
      range.select()
    }
  } else {
    myField.value += myValue
  }
  return myField.value
}

function ReturnWord(text, caretPos) {
  const index = text.indexOf(caretPos)
  const preText = text.substring(0, caretPos)
  if (preText.indexOf(' ') > 0) {
    const words = preText.split(' ')
    return words[words.length - 1] // return last word
  } else {
    return preText
  }
}

export function getWordUntilCaret(ctrl) {
  const caretPos = GetCaretPosition(ctrl)
  const word = ReturnWord(ctrl.value, caretPos)
  return word || ''
}

function GetCaretPosition(ctrl) {
  let CaretPos = 0 // IE Support
  if (document.selection) {
    ctrl.focus()
    const Sel = document.selection.createRange()
    Sel.moveStart('character', -ctrl.value.length)
    CaretPos = Sel.text.length
  }
  // Firefox support
  else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
    CaretPos = ctrl.selectionStart
  }
  return (CaretPos)
}

export function validateTableName(v, isGQL) {
  if (!v) {
    return 'Table name required'
  }

  // GraphQL naming convention
  // http://spec.graphql.org/June2018/#Name

  if (isGQL) {
    if (/^[_A-Za-z][_0-9A-Za-z]*$/.test(v)) {
      return true
    }

    if (/^[^_A-Za-z]/.test(v)) {
      return 'Name should start with an alphabet or _'
    }
    const m = v.match(/[^_A-Za-z\d]/g)
    if (m) {
      return `Following characters are not allowed ${m
        .map(c => JSON.stringify(c))
        .join(', ')}`
    }
  } else {
    // exclude . / \
    // rest all characters allowed
    // https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name.
    const m = v.match(/[./\\]/g)
    if (m) {
      return `Following characters are not allowed ${m
        .map(c => JSON.stringify(c))
        .join(', ')}`
    }

    return true
  }
}

export function validateColumnName(v, isGQL) {
  if (!v) {
    return 'Column name required'
  }

  // GraphQL naming convention
  // http://spec.graphql.org/June2018/#Name
  if (isGQL) {
    if (/^[_A-Za-z][_0-9A-Za-z]*$/.test(v)) {
      return true
    }

    if (/^[^_A-Za-z]/.test(v)) {
      return 'Name should start with an alphabet or _'
    }
    const m = v.match(/[^_A-Za-z\d]/g)
    if (m) {
      return `Following characters are not allowed ${m
        .map(c => JSON.stringify(c))
        .join(', ')}`
    }
  } else {
    // exclude . / \
    // rest all characters allowed
    // https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name.
    const m = v.match(/[./\\]/g)
    if (m) {
      return `Following characters are not allowed ${m
        .map(c => JSON.stringify(c))
        .join(', ')}`
    }

    return true
  }
}

/**
 * @copyright Copyright (c) 2021, Xgene Cloud Ltd
 *
 * @author Naveen MR <oof1lab@gmail.com>
 * @author Pranav C Balan <pranavxc@gmail.com>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
