{"version":3,"sources":["../src/hooks/useZendesk.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\n\nexport interface UseZendeskConfig {\n  /** Chave do canal Zendesk (snippet). */\n  zendeskKey: string;\n  /**\n   * Carrega o messenger apenas quando `true` (ex.: suporte é ZENDESK).\n   * Default: `true`.\n   */\n  enabled?: boolean;\n}\n\nexport interface UseZendeskReturn {\n  /** `true` quando o messenger (`window.zE`) está disponível para abrir. */\n  ready: boolean;\n  /** Abre o messenger do Zendesk. No-op enquanto não estiver pronto. */\n  openChat: () => void;\n}\n\nconst SCRIPT_ID = 'ze-snippet';\nconst INITIAL_RETRY_MS = 2000;\nconst MAX_RETRY_MS = 30_000;\nconst POLL_MS = 500;\n\ntype ZE = (...args: unknown[]) => void;\n\nconst getZE = (): ZE | undefined =>\n  (globalThis as unknown as Record<string, unknown>).zE as ZE | undefined;\n\n/**\n * Carrega o messenger do Zendesk de forma resiliente e isolada:\n * - injeta o snippet uma única vez (dedupe por id);\n * - se o script falhar (rede), re-injeta com backoff exponencial até carregar;\n * - sinaliza `ready` assim que `window.zE` fica disponível;\n * - `openChat` abre o messenger (no-op enquanto não estiver pronto).\n *\n * O loop de carregamento fica confinado a este hook — não bloqueia o restante\n * da página (form de login, Google, etc. funcionam independentemente).\n */\nexport const useZendesk = ({\n  zendeskKey,\n  enabled = true,\n}: UseZendeskConfig): UseZendeskReturn => {\n  const [ready, setReady] = useState(false);\n\n  useEffect(() => {\n    if (!enabled || !zendeskKey) return;\n\n    let cancelled = false;\n    let attempt = 0;\n    let retryTimer: ReturnType<typeof setTimeout> | undefined;\n    let pollTimer: ReturnType<typeof setInterval> | undefined;\n\n    function confirmReady(): boolean {\n      const zE = getZE();\n      if (!zE) return false;\n      zE('messenger:set', 'locale', 'pt-BR');\n      if (!cancelled) setReady(true);\n      return true;\n    }\n\n    function scheduleRetry() {\n      if (cancelled) return;\n      const delay = Math.min(INITIAL_RETRY_MS * 2 ** attempt, MAX_RETRY_MS);\n      attempt += 1;\n      retryTimer = setTimeout(inject, delay);\n    }\n\n    function handleScriptError() {\n      if (cancelled) return;\n      document.getElementById(SCRIPT_ID)?.remove();\n      scheduleRetry();\n    }\n\n    function inject() {\n      if (cancelled || confirmReady()) return;\n\n      // Se o snippet já existe (ex.: injetado por outro ponto, como o\n      // ZendeskWidget), não injeta de novo — mas adota o tratamento de erro\n      // para manter o retry e não deixar `ready` travado caso ele falhe.\n      const existing = document.getElementById(\n        SCRIPT_ID\n      ) as HTMLScriptElement | null;\n      if (existing) {\n        existing.addEventListener('error', handleScriptError, { once: true });\n        return;\n      }\n\n      const script = document.createElement('script');\n      script.id = SCRIPT_ID;\n      script.src = `https://static.zdassets.com/ekr/snippet.js?key=${zendeskKey}`;\n      script.async = true;\n      script.addEventListener('error', handleScriptError, { once: true });\n      document.body.appendChild(script);\n    }\n\n    inject();\n\n    // Poll leve (sem rede) só para detectar quando o `zE` fica disponível.\n    pollTimer = setInterval(() => {\n      if (cancelled) return;\n      if (confirmReady() && pollTimer) clearInterval(pollTimer);\n    }, POLL_MS);\n\n    return () => {\n      cancelled = true;\n      if (retryTimer) clearTimeout(retryTimer);\n      if (pollTimer) clearInterval(pollTimer);\n    };\n  }, [zendeskKey, enabled]);\n\n  const openChat = useCallback(() => {\n    getZE()?.('messenger', 'open');\n  }, []);\n\n  return { ready, openChat };\n};\n"],"mappings":";AAAA,SAAS,aAAa,WAAW,gBAAgB;AAmBjD,IAAM,YAAY;AAClB,IAAM,mBAAmB;AACzB,IAAM,eAAe;AACrB,IAAM,UAAU;AAIhB,IAAM,QAAQ,MACX,WAAkD;AAY9C,IAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA,UAAU;AACZ,MAA0C;AACxC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,KAAK;AAExC,YAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,WAAY;AAE7B,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,QAAI;AACJ,QAAI;AAEJ,aAAS,eAAwB;AAC/B,YAAM,KAAK,MAAM;AACjB,UAAI,CAAC,GAAI,QAAO;AAChB,SAAG,iBAAiB,UAAU,OAAO;AACrC,UAAI,CAAC,UAAW,UAAS,IAAI;AAC7B,aAAO;AAAA,IACT;AAEA,aAAS,gBAAgB;AACvB,UAAI,UAAW;AACf,YAAM,QAAQ,KAAK,IAAI,mBAAmB,KAAK,SAAS,YAAY;AACpE,iBAAW;AACX,mBAAa,WAAW,QAAQ,KAAK;AAAA,IACvC;AAEA,aAAS,oBAAoB;AAC3B,UAAI,UAAW;AACf,eAAS,eAAe,SAAS,GAAG,OAAO;AAC3C,oBAAc;AAAA,IAChB;AAEA,aAAS,SAAS;AAChB,UAAI,aAAa,aAAa,EAAG;AAKjC,YAAM,WAAW,SAAS;AAAA,QACxB;AAAA,MACF;AACA,UAAI,UAAU;AACZ,iBAAS,iBAAiB,SAAS,mBAAmB,EAAE,MAAM,KAAK,CAAC;AACpE;AAAA,MACF;AAEA,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,KAAK;AACZ,aAAO,MAAM,kDAAkD,UAAU;AACzE,aAAO,QAAQ;AACf,aAAO,iBAAiB,SAAS,mBAAmB,EAAE,MAAM,KAAK,CAAC;AAClE,eAAS,KAAK,YAAY,MAAM;AAAA,IAClC;AAEA,WAAO;AAGP,gBAAY,YAAY,MAAM;AAC5B,UAAI,UAAW;AACf,UAAI,aAAa,KAAK,UAAW,eAAc,SAAS;AAAA,IAC1D,GAAG,OAAO;AAEV,WAAO,MAAM;AACX,kBAAY;AACZ,UAAI,WAAY,cAAa,UAAU;AACvC,UAAI,UAAW,eAAc,SAAS;AAAA,IACxC;AAAA,EACF,GAAG,CAAC,YAAY,OAAO,CAAC;AAExB,QAAM,WAAW,YAAY,MAAM;AACjC,UAAM,IAAI,aAAa,MAAM;AAAA,EAC/B,GAAG,CAAC,CAAC;AAEL,SAAO,EAAE,OAAO,SAAS;AAC3B;","names":[]}