import gql from 'graphql-tag'
import client from './fetch-client'

import { setRoute } from './actions-route'

import ThingsSnackbar from '../../components/things-snackbar'

export const fetchBoardList = (by, id, route) => async dispatch => {
  try {
    var query
    switch (by) {
      case 'group':
        query = gql`{
          ${by}(id:"${id}") {
            boards {
              id name description width height thumbnail createdAt updatedAt
            }
          }
        }`
        break
      case 'playGroup':
        query = gql`{
          ${by}(id:"${id}") {
            boards {
              id name description width height thumbnail createdAt updatedAt
            }
          }
        }`
        break
      default:
        // 'recent'
        query = gql`
          {
            boards {
              id
              name
              description
              width
              height
              thumbnail
              createdAt
              updatedAt
            }
          }
        `
    }

    const response = await client.query({ query })

    if (route) {
      dispatch(setRoute(route, id))
    } else {
      switch (by) {
        case 'group':
          dispatch(setRoute('list-by-group', id))
          break
        case 'playGroup':
          dispatch(setRoute('list-by-playgroup', id))
          break
        default:
          dispatch(setRoute('list-recent'))
      }
    }

    dispatch({
      type: 'BOARD-LIST',
      group: id,
      list: id !== undefined ? response.data[by].boards : response.data.boards,
      groupType: by
    })
  } catch (error) {
    dispatch({
      type: 'CLEAR-BOARD-LIST'
    })
  }
}

export const fetchBoard = id => async dispatch => {
  try {
    if (!id) {
      // 생성하는 경우.
      dispatch({
        type: 'NEW-BOARD'
      })
    } else {
      const response = await client.query({
        query: gql`
          query FetchBoardById($id: String!) {
            board(id: $id) {
              id
              name
              description
              model
              width
              height
              createdAt
              updatedAt
            }
          }
        `,
        variables: { id }
      })

      const fetchedBoard = response.data.board

      dispatch({
        type: 'SET-CURRENT-BOARD',
        board: {
          ...fetchedBoard,
          model: JSON.parse(fetchedBoard.model)
        }
      })
    }
  } catch (error) {
    /* TODO error */
  }
}

export const createBoard = board => async dispatch => {
  try {
    /*
    input NewBoard {
      name        : String!
      description : String
      model       : String!
      width       : Int
      height      : Int
      published   : Boolean
    }
    */

    var { name, description, model, width, height, published, group } = board
    model = JSON.stringify(model)

    const response = await client.mutate({
      mutation: gql`
        mutation CreateBoard($board: NewBoard!, $group: String!) {
          createBoard(board: $board, groupId: $group) {
            id
            name
            description
            model
            width
            height
            createdAt
            updatedAt
          }
        }
      `,
      variables: {
        board: { name, description, model, width, height, published },
        group
      }
    })

    const createdBoard = response.data.createBoard

    dispatch({
      type: 'SET-CURRENT-BOARD',
      board: {
        ...createdBoard,
        model: JSON.parse(createdBoard.model)
      }
    })

    return dispatch
  } catch (error) {
    console.error(error)
    /* TODO error */
    return dispatch
  }
}

export const updateBoard = board => async dispatch => {
  try {
    /*
    input BoardPatch {
      name        : String
      description : String
      model       : String
      width       : Int
      height      : Int
      published   : Boolean
    }
    */
    var { id, name, description, model, width, height, published } = board
    model = JSON.stringify(model)

    const response = await client.mutate({
      mutation: gql`
        mutation UpdateBoard($id: String!, $patch: BoardPatch!) {
          updateBoard(id: $id, patch: $patch) {
            id
            name
            description
            model
            width
            height
            createdAt
            updatedAt
          }
        }
      `,
      variables: {
        id,
        patch: { name, description, model, width, height, published }
      }
    })

    const updatedBoard = response.data.updateBoard

    updatedBoard.model = dispatch({
      type: 'SET-CURRENT-BOARD',
      board: {
        ...updatedBoard,
        model: JSON.parse(updatedBoard.model)
      }
    })

    ThingsSnackbar.toast('Saved.')

    return dispatch
  } catch (error) {
    console.error(error)
    /* TODO error */
  }
}

export const deleteBoard = (board, group) => async dispatch => {
  try {
    var { id } = board

    const response = await client.mutate({
      mutation: gql`
        mutation($id: String!) {
          deleteBoard(id: $id) {
            id
          }
        }
      `,
      variables: {
        id
      }
    })

    return dispatch
  } catch (error) {
    console.error(error)
    /* TODO error */
  }
}
