/**
 * ConvexMachineProvider - Provider Convex para autenticacao via token de maquina
 *
 * Este provider inicializa o ConvexReactClient usando o token da maquina
 * armazenado no Tauri Store, permitindo subscriptions reativas em tempo real.
 *
 * Arquitetura:
 * - Carrega o token do Tauri Store na montagem
 * - Inicializa o ConvexReactClient com a URL do Convex
 * - Disponibiliza o cliente para componentes filhos via Context
 * - Reconecta automaticamente quando o token muda
 */

import { createContext, useContext, useEffect, useState, type ReactNode } from "react"
import { ConvexReactClient } from "convex/react"
import { getMachineStoreConfig } from "./machineStore"

// URL do Convex - em producao, usa o dominio personalizado
const CONVEX_URL = import.meta.env.MODE === "production"
  ? "https://convex.esdrasrenan.com.br"
  : (import.meta.env.VITE_CONVEX_URL ?? "https://convex.esdrasrenan.com.br")

type MachineAuthState = {
  token: string | null
  apiBaseUrl: string | null
  isLoading: boolean
  error: string | null
}

type ConvexMachineContextValue = {
  client: ConvexReactClient | null
  machineToken: string | null
  apiBaseUrl: string | null
  isReady: boolean
  error: string | null
  reload: () => Promise<void>
}

const ConvexMachineContext = createContext<ConvexMachineContextValue | null>(null)

export function useConvexMachine() {
  const ctx = useContext(ConvexMachineContext)
  if (!ctx) {
    throw new Error("useConvexMachine must be used within ConvexMachineProvider")
  }
  return ctx
}

export function useMachineToken() {
  const { machineToken } = useConvexMachine()
  return machineToken
}

interface ConvexMachineProviderProps {
  children: ReactNode
}

export function ConvexMachineProvider({ children }: ConvexMachineProviderProps) {
  const [authState, setAuthState] = useState<MachineAuthState>({
    token: null,
    apiBaseUrl: null,
    isLoading: true,
    error: null,
  })

  const [client, setClient] = useState<ConvexReactClient | null>(null)

  // Funcao para carregar configuracao do Tauri Store
  const loadConfig = async () => {
    setAuthState(prev => ({ ...prev, isLoading: true, error: null }))

    try {
      const config = await getMachineStoreConfig()

      if (!config.token) {
        setAuthState({
          token: null,
          apiBaseUrl: config.apiBaseUrl,
          isLoading: false,
          error: "Token da maquina nao encontrado",
        })
        return
      }

      setAuthState({
        token: config.token,
        apiBaseUrl: config.apiBaseUrl,
        isLoading: false,
        error: null,
      })
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err)
      setAuthState({
        token: null,
        apiBaseUrl: null,
        isLoading: false,
        error: message || "Erro ao carregar configuracao",
      })
    }
  }

  // Carregar configuracao na montagem
  useEffect(() => {
    loadConfig()
  }, [])

  // Inicializar/reinicializar cliente Convex quando token muda
  useEffect(() => {
    if (!authState.token) {
      // Limpar cliente se nao tem token
      if (client) {
        client.close()
        setClient(null)
      }
      return
    }

    // Criar novo cliente Convex
    const newClient = new ConvexReactClient(CONVEX_URL, {
      // Desabilitar retry agressivo para evitar loops infinitos
      unsavedChangesWarning: false,
    })

    setClient(newClient)

    // Cleanup ao desmontar ou trocar token
    return () => {
      newClient.close()
    }
  }, [authState.token]) // eslint-disable-line react-hooks/exhaustive-deps

  const contextValue: ConvexMachineContextValue = {
    client,
    machineToken: authState.token,
    apiBaseUrl: authState.apiBaseUrl,
    isReady: !authState.isLoading && !!client && !!authState.token,
    error: authState.error,
    reload: loadConfig,
  }

  return (
    <ConvexMachineContext.Provider value={contextValue}>
      {children}
    </ConvexMachineContext.Provider>
  )
}
