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

interface  Customer {
  id: string
  email?: string
  username: string
  first_name?: string
  last_name?: string
  avatar?: string
  company?: CompanyParams
  plan?: CurrentTariff
  storage_id: number
  external_id: string
}

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

const ENDPOINT_MAP = {
  register: '/auth/email/register',
  forgot: '/auth/email/recovery',
  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 ENV = ref<Env | 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', { suppressNotify: true })
      customer.value = data.data
      const response = await api.get('/env', { suppressNotify: true })
      ENV.value = response.data.data as Env
    } catch (error) {
      if (isAuth.value) console.error(error)
    }
  }

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

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

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

  const logout = async () => {
    await api.get('/auth/logout', {})
    customer.value = null
    projectsStore.setCurrentProjectId(null)
    projectsStore.reset()
  }
  
  const initRegistration = async (flowType: AuthFlowType, email: string, locale?: string) => {
    if (flowType !== 'changePwd')
      await api.post(ENDPOINT_MAP[flowType], { email, locale })
    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 })

  // for payment  
  async function updateProfile () {
    const { data } = await api.get('/customer/profile')
    customer.value = data.data
  }

  // 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 
  }

  // agreement
  async function termsAccepted () {
    await api.post('/terms/accept')
  }

  async function termsRevoked () {
    await api.post('/terms/revoke')
  }

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