import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useFetchJson } from '@/composable/useFetchJson'

export interface User {
  id: string
  email: string
  name: string
}

interface AuthResponse {
  access_token: string
  token_type: string
  expires_in: number
  user: User
}

// Read the non-HTTPOnly is_authenticated cookie set by the backend.
// The backend sets it to "1" on login and removes it on logout.
function readIsAuthenticatedCookie(): boolean {
  if (typeof document === 'undefined') return false
  return document.cookie.split('; ').some((c) => c === 'is_authenticated=1')
}

export const useAuthStore = defineStore('auth', () => {
  // useRouter must be called at the top level of the setup function, not inside a method
  // We use window.location as a fallback-safe redirect mechanism instead, to avoid
  // the "Cannot read properties of undefined" error when the router is not yet available.
  const user = ref<User | null>(null)
  const loading = ref(false)
  const error = ref<string | null>(null)

  // Auth state is derived from the is_authenticated cookie (set/cleared by backend).
  // We use a ref so Vue reactivity works; it is initialised from the cookie on store creation.
  const _isAuthenticated = ref<boolean>(readIsAuthenticatedCookie())

  const isAuthenticated = computed(() => _isAuthenticated.value)

  /** Call after any successful login to sync the reactive flag. */
  function _syncAuthState() {
    _isAuthenticated.value = readIsAuthenticatedCookie()
  }

  async function login(email: string, password: string) {
    loading.value = true
    error.value = null

    try {
      const data = await useFetchJson<AuthResponse>('/api/v1/public/auth/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password }),
      })

      const response = (data as any).items || data

      if (!response.access_token) {
        throw new Error('No access token received')
      }

      user.value = response.user
      _syncAuthState()

      return true
    } catch (e: any) {
      error.value = e?.error ?? 'An error occurred'
      return false
    } finally {
      loading.value = false
    }
  }

  async function register(
    first_name: string,
    last_name: string,
    email: string,
    password: string,
    confirm_password: string,
    lang?: string,
    company_name?: string,
    company_email?: string,
    company_address?: {
      street: string
      zipCode: string
      city: string
      country: string
    },
    regon?: string,
    nip?: string,
    vat?: string,
    billing_address?: {
      street: string
      zipCode: string
      city: string
      country: string
    },
  ) {
    loading.value = true
    error.value = null
    try {
      const body: any = { first_name, last_name, email, password, confirm_password, lang: lang || 'en' }
      
      // Add company information if provided
      if (company_name) body.company_name = company_name
      if (company_email) body.company_email = company_email
      if (company_address) body.company_address = company_address
      if (regon) body.regon = regon
      if (nip) body.nip = nip
      if (vat) body.vat = vat
      if (billing_address) body.billing_address = billing_address

      await useFetchJson('/api/v1/public/auth/register', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      })

      return { success: true, requiresVerification: true }
    } catch (e: any) {
      error.value = e?.error ?? 'An error occurred'
      return { success: false, requiresVerification: false }
    } finally {
      loading.value = false
    }
  }

  async function requestPasswordReset(email: string) {
    loading.value = true
    error.value = null

    try {
      await useFetchJson('/api/v1/public/auth/forgot-password', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email }),
      })

      return true
    } catch (e: any) {
      error.value = e?.error ?? 'An error occurred'
      return false
    } finally {
      loading.value = false
    }
  }

  async function resetPassword(token: string, password: string) {
    loading.value = true
    error.value = null

    try {
      await useFetchJson('/api/v1/public/auth/reset-password', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ token, password }),
      })

      return true
    } catch (e: any) {
      error.value = e?.error ?? 'An error occurred'
      return false
    } finally {
      loading.value = false
    }
  }

  function loginWithGoogle() {
    window.location.href = '/api/v1/public/auth/google'
  }

  /**
   * Logout: calls the backend to revoke the refresh token and clear HTTPOnly cookies,
   * clears local reactive state, then redirects to the login page.
   */
  async function logout() {
    try {
      await useFetchJson('/api/v1/public/auth/logout', {
        method: 'POST',
      })
    } catch {
      // Continue with local cleanup even if the backend call fails
    } finally {
      user.value = null
      _isAuthenticated.value = false
      // Use dynamic import to get the router instance safely from outside the setup context
      const { default: router } = await import('@/router')
      router.push({ name: 'login' })
    }
  }

  /**
   * Refresh the access token by calling the backend.
   * The backend reads the HTTPOnly refresh_token cookie, rotates it, and sets new cookies.
   * Returns true on success.
   */
  async function refreshAccessToken(): Promise<boolean> {
    try {
      await useFetchJson('/api/v1/public/auth/refresh', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        // No body needed — the backend reads the refresh_token from the HTTPOnly cookie
      })

      _syncAuthState()
      return true
    } catch {
      // Refresh failed — clear local state
      user.value = null
      _isAuthenticated.value = false
      return false
    }
  }

  function clearError() {
    error.value = null
  }

  return {
    user,
    loading,
    error,
    isAuthenticated,
    login,
    loginWithGoogle,
    register,
    requestPasswordReset,
    resetPassword,
    logout,
    refreshAccessToken,
    clearError,
  }
})
