import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { api } from 'boot/axios'
import type { CompanyParams } from 'types/Company'
import { useProjectsStore } from 'stores/projects'

interface Customer {
  id: string
  email?: string
  username: string
  first_name?: string
  last_name?: string
  avatar?: string
  company?: CompanyParams
}

interface WSMessage {
  id: number
  action: string
  entity: string
  entity_id?: number
  needUpdateStores: string[]
}

const ENDPOINT_MAP = {
  register: '/auth/email/register',
  forgot: '/auth/forgot',
  changePwd: '/auth/email/change-password',
  changeMethod: '/auth/email/upgrade'
} as const

export type AuthFlowType = keyof typeof ENDPOINT_MAP

export const useAuthStore = defineStore('auth', () => {
  const customer = ref<Customer | null>(null)
  const wsEvent = ref<WSMessage | null>(null)
  const projectsStore = useProjectsStore()

  const isAuth = computed(() => !!customer.value)

  const initialize = async () => {
    try {
      const { data } = await api.get('/customer/profile')
      customer.value = data.data
      const socket = new WebSocket("wss://946gp81j-9000.euw.devtunnels.ms/api/admin")
      console.log(socket)
      socket.onopen = () => console.log("Connection ws create.")

      socket.onclose = (event) => {
        if (event.wasClean) console.log('Connection ws close.')
        else console.log('Connection ws failure!')
        console.log('Code: ' + event.code + ', reason : ' + event.reason)
      }

      socket.onmessage = (event) => {
        if (wsEvent.value) {
          wsEvent.value.needUpdateStores = []
          wsEvent.value = JSON.parse(event.data)
          if (wsEvent.value?.entity === 'chat') wsEvent.value.needUpdateStores = ['users']
        }

      socket.onerror = (event) => console.error("Ошибка ", event)
      }

    } catch (error) {
      if (isAuth.value) console.error(error)
    } 
  }

  const loginWithCredentials = async (email: string, password: string) => {
    await api.post('/auth/email', { email, password }, { withCredentials: true })
    await initialize()
  }

  const loginWithTelegram = async (initData: string) => {
    await api.post('/auth/telegram?'+ initData, {}, { withCredentials: true })
    await initialize()
  }

  const logout = async () => {
    await api.get('/auth/logout', {})
    customer.value = null
    projectsStore.reset()
  }
  
  const initRegistration = async (flowType: AuthFlowType, email: string) => {
    if (flowType !== 'changePwd')
      await api.post(ENDPOINT_MAP[flowType], { email })
    else
      await api.post(ENDPOINT_MAP[flowType])
  }
  
  const confirmCode = async (flowType: AuthFlowType, email: string, code: string) => {
    await api.post(ENDPOINT_MAP[flowType], { email, code })
  }

  const setPassword = async (
    flowType: AuthFlowType,
    email: string,
    code: string,
    password: string
  ) => {
    await api.post(ENDPOINT_MAP[flowType], { email, code, password })
  }
  
  //change email of account
  const getCodeCurrentEmail = async () =>
    await api.post('/auth/email/change-email')


  const confirmCurrentEmailCode = async (code: string) =>
    await api.post('/auth/email/change-email', { code })
  
  const getCodeNewEmail = async (code: string, email: string) =>
    await api.post('/auth/email/change-email', { code, email })

  const confirmNewEmailCode = async (code: string, code2: string, email: string) =>
    await api.post('/auth/email/change-email', { code, code2, email })

  const setNewEmailPassword = async (code: string, code2: string, email: string, password: string) =>
    await api.post('/auth/email/change-email', { code, code2, email, password })

  // user data company
  const updateMyCompany = async (companyData: CompanyParams) => {
    const response = await api.put('/customer/profile', { company: companyData })
    if (response.status === 200 && customer.value) customer.value.company = companyData 
  }

  return {
    customer,
    isAuth,
    wsEvent,
    initialize,
    loginWithCredentials,
    loginWithTelegram,
    logout,
    initRegistration,
    confirmCode,
    setPassword,
    updateMyCompany,
    getCodeCurrentEmail,
    confirmCurrentEmailCode,
    getCodeNewEmail,
    confirmNewEmailCode,
    setNewEmailPassword
  }
})