
import nanoid from 'nanoid'

import {Http, Delay} from './effects'

import {
  getFieldType,
  typeDefaults,
  getClearedCopy,
  getRef,
  setPath,
  deletePath,
  renamePath,
  setInArrays,
  deleteInArrays,
  renameInArrays,
  closeUI
} from './utils'


export const Navigate = (state, location) => ({
  ...state,
  location
})



export const OnOverlayMount = (state, ev) => {
  if (!state.dataFetched && !state.dataFetching) {
    return [
      {
        ...state,
        dataFetching: true
      },
      Http.fetch({
        url: '/databelt/api?raw=true',
        action: ReceiveData
      })
    ]
  }
  return state
}

export const ReceiveData = (state, response) => ({
  ...state,
  dataFetched: true,
  dataFetching: false,
  data: response
})


export const SetField = (state, path, value) => ({
  ...state,
  data: setPath(
    state.data,
    path,
    value
  )
})


export const RemoveField = (state, path) => ({
  ...state,
  data: deleteInArrays(state.data, path)
})





export const AddRepeaterRow = (state, path) => {

  let pointer = getRef(state.data, path)
  
  if (pointer[0]) {
    pointer.push(getClearedCopy(pointer[0]))
  } else {
    pointer.push(typeDefaults['repeater'][0])
  }

  return {...state}
}






export const OpenFieldForm = (state, path) => {
    
  const parts = path.split('.')
  const key = parts.pop()

  let pointer = getRef(state.data, parts.join('.'))

  const type = getFieldType(pointer[key])
  
  return {
    ...state,
    fieldFormIsOpen: true,
    fieldForm: {
      ...state.fieldForm,
      path,
      name: key,
      type,
      value: pointer[key] || ''
    }
  }
}

export const ToggleFieldForm = (state, ev) => {
  ev.stopPropagation()
  return {
    ...state,
    fieldFormIsOpen: !state.fieldFormIsOpen
  }
}

export const SetFieldForm = (state, key, value) => ({
  ...state,
  fieldForm: {
    ...state.fieldForm,
    [key]: value
  }
})

export const SetFieldFormType = (state, ev) => ({
  ...state,
  fieldForm: {
    ...state.fieldForm,
    type: ev.target.value,
    value: typeDefaults[ev.target.value]
  }
})


export const SetFieldFormValue = (state, value) => ({
  ...state,
  fieldForm: {
    ...state.fieldForm,
    value: value
  }
})

export const ToggleCodeSample = (state) => ({
  ...state,
  fieldForm: {
    ...state.fieldForm,
    codeSampleOpened: !state.fieldForm.codeSampleOpened
  }
})


export const CopyToClipBoard = (state, codeSample) => {
  navigator.clipboard.writeText(codeSample)
  return {
    ...state,
    toasts: state.toasts.concat({
      id: nanoid(),
      message: 'Copied to clipboard !',
      type: 'success'
    })
  }
}



export const HandleFieldForm = (state, ev) => {

  ev.preventDefault();

  const parts = state.fieldForm.path.split('.')
  const key = parts.pop()
  const newPath = parts.concat(state.fieldForm.name).join('.')
  let data = state.data

  data = renameInArrays(data, state.fieldForm.path, state.fieldForm.name)

  data = setInArrays(data, newPath, state.fieldForm.value)
  
  data = setPath(data, newPath, state.fieldForm.value)
  
  return {
    ...state,
    fieldFormIsOpen: false
  }
}


















export const SetLoginForm = (state, key, ev) => ({
  ...state,
  loginForm: {
    ...state.loginForm,
    [key]: ev.target.value
  }
})

export const OnLoginFormMount = (state, ev) => {
  if (state.authStatus === 'UNKNOWN') {
    return [
      state,
      Http.fetch({
        url: '/databelt/auth/check',
        action: ReceiveAuthStatus
      })
    ]
  }
  return state
}

export const ReceiveAuthStatus = (state, response) => ({
  ...state,
  authStatus: response
})

export const HandleLoginForm = (state, ev) => {
  ev.preventDefault()
  return [
    {
      ...state,
      loginForm: {
        password: '',
        submitted: true
      }
    },
    Http.post({
      url: '/databelt/auth/' + (state.authStatus == 'NO_PASSWORD_SET' ? 'init' : 'login'),
      action: HandleLoginResponse,
      method: 'POST',
      data: state.loginForm
    })
  ]
}


export const HandleLoginResponse = (state, response) => {
  console.log(response);
  return {
    ...state,
    authStatus: response ? 'LOGGED_IN' : 'WRONG_PASSWORD'
  }
}

export const LogOut = (state, ev) => [
  state,
  Http.fetch({
    url: '/databelt/auth/logout',
    action: HandleLogOutResponse
  })
]

export const HandleLogOutResponse = (state, response) => {
  closeUI()
  return {
    ...state,
    authStatus: response ? 'LOGGED_OUT' : 'LOGGED_IN'
  }
}























export const HandleSaveAll = (state, ev) => [
  state,
  Http.post({
    url: '/databelt/api',
    action: HandleSaveAllResponse,
    method: 'PUT',
    data: state.data
  })
]

export const HandleSaveAllResponse = (state, response) => ({
  ...state,
  data: response,
  reloadWhenClosed: true,
  toasts: state.toasts.concat({
    id: nanoid(),
    message: 'Saved successfully !',
    type: 'success'
  })
})



export const DeleteToastLater = (state, id) => [
  state,
  Delay({
    action: [DeleteToast, id],
    duration: 3000
  })
]



export const DeleteToast = (state, id) => ({
  ...state,
  toasts: state.toasts.filter(toast => id !== toast.id)
})
