import React, {useCallback, useEffect, useState} from 'react'

import {ReportErrorParams} from '@shopify/shop-minis-platform/actions'

import {MinisQueryProvider} from '../internal/reactQuery'
import {useShopActions} from '../internal/useShopActions'
import {injectMocks} from '../mocks'
import {ImagePickerProvider} from '../providers/ImagePickerProvider'

import {ErrorBoundary} from './ErrorBoundary'

injectMocks()

export function MinisContainer({children}: {children: React.ReactNode}) {
  const [isSDKReady, setIsSDKReady] = useState(false)
  const actions = useShopActions()

  const handleError = useCallback(
    async (params: ReportErrorParams) => {
      try {
        if (actions && actions.reportError) {
          await actions.reportError(params)
        }
      } catch (error) {
        // If reporting fails, at least log to console
        console.error('Failed to report error to app:', error)
      }
    },
    [actions]
  )

  useEffect(() => {
    // Function to check if SDK is ready
    const checkSDKReady = () => {
      if (window.minisSDK) {
        setIsSDKReady(true)
        return true
      }
      return false
    }

    // Check immediately
    if (checkSDKReady()) {
      return
    }

    // If not ready, set up a listener for the MINIS_SDK_READY event
    const handleSDKReady = (event: any) => {
      const {type} = JSON.parse(event.data)

      if (type === 'MINIS_SDK_READY') {
        setIsSDKReady(true)
      }
    }

    // Listen for the MINIS_SDK_READY event
    window.addEventListener('message', handleSDKReady)
    document.addEventListener('message', handleSDKReady)

    // Also poll for SDK availability as a fallback
    const pollInterval = setInterval(() => {
      if (checkSDKReady()) {
        clearInterval(pollInterval)
      }
    }, 100)

    // Cleanup
    return () => {
      clearInterval(pollInterval)
      window.removeEventListener('message', handleSDKReady)
      document.removeEventListener('message', handleSDKReady)
    }
  }, [])

  // Don't render anything until SDK is ready
  if (!isSDKReady) {
    return (
      <div className="h-screen bg-gray-50 flex items-center justify-center">
        <div className="text-center">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mx-auto mb-4" />
          <p className="text-gray-600">Loading...</p>
        </div>
      </div>
    )
  }

  return (
    <MinisQueryProvider>
      <ErrorBoundary onError={handleError}>
        <ImagePickerProvider>{children}</ImagePickerProvider>
      </ErrorBoundary>
    </MinisQueryProvider>
  )
}
