// import {
//   FixedAdjust,
//   DenseFixedAdjust,
//   ProminentFixedAdjust,
//   ShortFixedAdjust,
// } from "@smui/top-app-bar";

import Toastify from 'toastify-js'
import store from '~/store'
import useState from '~/hooks/useState'
import { AppDefsAction } from '~/store/types'
import { MessageType } from '~/typs'
import 'toastify-js/src/toastify.css'
const { connection } = useState()

// import { postData, sendData } from './api.js'

// https://www.carlrippon.com/fetch-with-async-await-and-typescript/

/*
const headers: HeadersInit = {
  'Content-Type': 'application/json',
  'X-Request-Id': uuidv4(),
  'Authorization': `Bearer <API_TOKEN>`
}
*/
// https://github.com/Maronato/vue-toastification#installation

export const show_message = (typ: MessageType, msg: string, timeout?: number): void => {
  // switch (typ) {
  //   case MessageType.Show:
  //     toast.show(msg)
  //     break
  //   case MessageType.Success:
  //     toast.success(msg)
  //     break
  //   case MessageType.Error:
  //     toast.error(msg)
  //     break
  //   case MessageType.Warning:
  //     toast.warning(msg)
  //     break
  //   case MessageType.Info:
  //     toast.info(msg)
  //     break
  // }
  // if (timeout && timeout > 0)
  //   setTimeout(toast.clear, timeout)
  // https://github.com/apvarun/toastify-js
  Toastify({
    text: msg,
    duration: timeout || 3000,
    destination: 'https://github.com/apvarun/toastify-js',
    newWindow: true,
    className: '',
    offset: {
      x: 10, // horizontal axis - can be a number or a string indicating unity. eg: '2em'
      y: 50, // vertical axis - can be a number or a string indicating unity. eg: '2em
    },
    close: true,
    gravity: 'top', // `top` or `bottom`
    position: 'left', // `left`, `center` or `right`
    backgroundColor: 'linear-gradient(to right, #00b09b, #96c93d)',
    stopOnFocus: true, // Prevents dismissing of toast on hover
    onClick() {}, // Callback after click
  }).showToast()
}

export const translate = (store: any, map: string, ky: string, ctx: string, dflt?: string): string => {
  const val = dflt || ky
  const lang = store.state.app_lang.lang.get(map)
  // switch (ctx) {
  //   case 'main':
  //     val = lang.value.main && lang.value.main[ky] ? lang.value.main[ky] : val
  //     break
  //   case 'data':
  //     val = lang.value.main && lang.value.main[ky] ? lang.value.main[ky] : val
  //     val = lang.value.data[ky] || val
  //     break
  //   case 'forms':
  //     val = lang.value.forms && lang.value.forms[ky] ? lang.value.forms[ky] : val
  //     break
  // }
  if (lang && lang.value)
    return lang.value[ctx] && lang.value[ctx][ky] ? lang.value[ctx][ky] : val
  else if (lang && lang[ctx])
    return lang[ctx][ky] ? lang[ctx][ky] : val
  else
    return val
}

export const senddata = async<T>(url: RequestInfo, data: BlobPart, file_name?: string, cllbck?: any): Promise<any> => {
  const formData = new FormData()
  // formData.append('blob', new Blob([JSON.stringify(rowData)]), 'test')
  // let response: Ref < T | undefined > = ref()

  formData.append('blob', new Blob([data]), file_name)
  try {
    const response = await fetch(url, {
      mode: 'no-cors', // 'cors' by default
      method: 'POST',
      body: formData,
    })
    return response
  }
  catch (err) {
    if (cllbck)
      cllbck(err)
    else
      console.log(err)
  }
}
export const postdata = (url: string, data: any, file_name: string, cllbck?: any): void => {
  if (data && file_name) {
    senddata(url, data, file_name, cllbck).then((result: any) => {
      if (result.status !== 0) {
        console.log(
        // throw Error(
          `Data sent to ${url} (${file_name}) - Network response NOT OK`,
        )
      }
      else {
        console.log(
          `Save data to ${url} (${file_name}) status: ${result.status}`,
        )
      }
      if (cllbck)
        cllbck(result)
    })
  }
}
export const fetch_text = async(path: RequestInfo): Promise<any> => {
  try {
    const response = await fetch(path)
    return !response.ok ? response.text() : new Error('No items found')
  }
  catch (err) {
    return err
  }
}

export const fetch_json = async(path: RequestInfo, timeout = 2000): Promise<any> => {
  // eslint-disable-next-line no-async-promise-executor
  return new Promise(async(resolve, reject) => {
    try {
      const response = await self.fetch(path)
      setTimeout(async() => {
        resolve(await response.json())
      }, timeout)
    }
    catch (err) {
      reject(err)
    }
  })
}

export const load_data = async(data_path: RequestInfo, ato: number, timeout = 2000, cllbck?: any) => {
  // eslint-disable-next-line no-async-promise-executor
  // return await new Promise(async(resolve, reject) => {
  useState().connection.value.state = ''
  const token = localStorage.getItem('auth') || ''
  // if (token === '')
  //  return `error no auth for ${data_path}`

  try {
		const headers = token !== "" ? { Authorization: `Bearer ${token}`} : {}   
    // 'content-type': 'application/json',
    const res = await self.fetch(data_path, {
      headers
    })
    // setTimeout(async() => {
    let dataloaded = {}
    try {
      let strData = await res.text()
      for (let i = 0; i < ato; i++)
        strData = atob(strData)
      dataloaded = JSON.parse(strData)
    }
    catch (e) {
      return `error ${e} with ${data_path}`
    }
    if (Object.keys(dataloaded).length) {
      if (cllbck)
        cllbck(dataloaded)
      return ''
    }
    else {
      return new Error('No definitions found')
    }
    // }, timeout)
  }
  catch (err) {
    show_message(MessageType.Error, `'Data Load' -> ${err}`)
    useState().connection.value.state = 'connection.error'
    return err
  }
  // })
}
export const post_data = async(url: string, formData: any, with_auth = true) => {
  connection.value.state = ''
  let headers = {}
  if (with_auth) {
    const token = localStorage.getItem('auth') || ''
    if (token === '')
      return `error no auth for ${url}`
    headers = {
      'content-type': 'application/json',
      'Authorization': `Bearer ${token}`,
      // 'Access-Control-Allow-Origin': '*',
      // 'Accept': 'application/json',
    }
  }
  else {
    headers = { 'content-type': 'application/json' }
  }
  let formDataJsonString = ''
  try {
    formDataJsonString = JSON.stringify(formData)
  }
  catch (e) {
    console.log(e)
    return
  }
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers,
      body: formDataJsonString,
    })
    if (!response.ok && response.status !== 200) {
      const errorMessage = await response.text()
      console.log(errorMessage)
      // throw new Error(errorMessage)
    }
    if (response.ok && response.status === 200)
      return response.json()
  }
  catch (e) {
    connection.value.state = 'connection.error'
    console.log(e)
  }
}

export const check_credentials = async(url: string, data: any): Promise<any> => {
  let dataJsonString = ''
  try {
    dataJsonString = JSON.stringify(data)
  }
  catch (e) {
    console.log(e)
    return
  }
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'content-type': 'application/json',
      },
      body: dataJsonString,
    })
    if (!response.ok) {
      const errorMessage = await response.text()
      // throw new Error(errorMessage)
      console.log(errorMessage)
      return
    }
    if (response.ok && response.status === 200)
      return response.json()
  }
  catch (e) {
    useState().connection.value.state = 'connection.error'
    console.log(e)
  }
}

export const run_task = (val: number, task: Function) => {
  const now = new Date().getTime()
  const timePassed = now % val
  const run_at = val - timePassed
  setTimeout(task, run_at)
}

export const verify_auth = async(mapkey: string, check_url: string, login_url: string) => {
  const auth = localStorage.getItem('auth') || ''
  const res = await check_credentials(check_url, { data: auth, mapkey })
  if (res && res.token === auth) {
    if (res.defs)
      store.dispatch(AppDefsAction.addDefs, { key: mapkey, defs: res.defs })
    if (res.defs.checkin && res.defs.checkin > 0) {
      run_task(res.defs.checkin, async() => {
        // console.log('run_task')
        const res_task = await verify_auth(mapkey, check_url, login_url)
        if (res_task)
          return
        if (useState().connection.value.state === '')
          location.href = login_url
      })
    }
    return res
  }
  return res
}

export const auth_data = () => {
	const auth = localStorage.getItem('auth') || ''
	let uidefs = {}
	if (store && store.state && store.state.app_defs && store.state.app_defs.main) {
		uidefs = store.state.app_defs.main.get('ui')
	}
  return {auth, uidefs}
}

export const parse_str_json_data = (src: string, dflt: object|any) => {
	let data = dflt
	try {
		data = JSON.parse(src)
	}
	catch (e) {
		data = dflt
	}
	return data
}

export default {
  fetch_text,
  fetch_json,
  postdata,
  senddata,
  load_data,
  post_data,
  //  store_data,
  show_message,
  translate,
  check_credentials,
  run_task,
  verify_auth,
	auth_data,
	parse_str_json_data,
}
