'use client'

import React, {
  useReducer,
  useMemo,
  useRef,
  useState,
} from 'react'
import {
  ComplianceClient,
  sdkReducer,
  initialState,
  StateSyncManager,
  createDSGVOModule,
  createComplianceModule,
  createRAGModule,
  createSecurityModule,
} from '@breakpilot/compliance-sdk-core'
import type { SyncState } from '@breakpilot/compliance-sdk-types'
import {
  getStepById,
  getNextStep,
  getPreviousStep,
  getCompletionPercentage,
  getPhaseCompletionPercentage,
} from '@breakpilot/compliance-sdk-types'
import {
  ComplianceContext,
  type ComplianceContextValue,
  type ComplianceProviderProps,
} from './provider-context'
import {
  useSyncManagerEffect,
  useLoadInitialStateEffect,
  useAutoSaveEffect,
  useKeyboardShortcutsEffect,
} from './provider-effects'
import {
  useValidateCheckpoint,
  useOverrideCheckpoint,
  useGetCheckpointStatus,
  useUpdateUseCase,
  useAddRisk,
  useUpdateControl,
  useSaveState,
  useLoadState,
  useResetState,
  useForceSyncToServer,
  useExportState,
} from './provider-callbacks'
import { useCallback, useMemo as useMemoReact } from 'react'

export {
  ComplianceContext,
  type ComplianceContextValue,
  type ComplianceProviderProps,
} from './provider-context'

// Re-export useCompliance so legacy component imports (`from '../provider'`)
// keep resolving. Pre-existing cross-file import that was broken in baseline.
export { useCompliance } from './hooks'

// =============================================================================
// PROVIDER
// =============================================================================

export function ComplianceProvider({
  children,
  apiEndpoint,
  apiKey,
  tenantId,
  userId = 'default',
  enableBackendSync = true,
  onNavigate,
  onError,
}: ComplianceProviderProps) {
  const [state, dispatch] = useReducer(sdkReducer, {
    ...initialState,
    tenantId,
    userId,
  })
  const [isCommandBarOpen, setCommandBarOpenRaw] = useState(false)
  const [isInitialized, setIsInitialized] = useState(false)
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<Error | null>(null)
  const [syncState, setSyncState] = useState<SyncState>({
    status: 'idle',
    lastSyncedAt: null,
    localVersion: 0,
    serverVersion: 0,
    pendingChanges: 0,
    error: null,
  })
  const [isOnline, setIsOnline] = useState(true)

  // Refs
  const clientRef = useRef<ComplianceClient | null>(null)
  const syncManagerRef = useRef<StateSyncManager | null>(null)

  // Initialize client (once)
  if (!clientRef.current) {
    clientRef.current = new ComplianceClient({
      apiEndpoint,
      apiKey,
      tenantId,
      onError: err => {
        setError(err)
        onError?.(err)
      },
    })
  }

  const client = clientRef.current

  // Modules
  const dsgvo = useMemo(() => createDSGVOModule(client, () => state), [client, state])
  const compliance = useMemo(() => createComplianceModule(client, () => state), [client, state])
  const rag = useMemo(() => createRAGModule(client), [client])
  const security = useMemo(() => createSecurityModule(client, () => state), [client, state])

  // -------------------------------------------------------------------------
  // Effects (extracted to provider-effects.ts)
  // -------------------------------------------------------------------------

  const syncStateSetters = useMemo(
    () => ({ setSyncState, setIsOnline, setError, dispatch }),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    []
  )

  useSyncManagerEffect(enableBackendSync, tenantId, client, state, syncManagerRef, syncStateSetters)

  useLoadInitialStateEffect(tenantId, enableBackendSync, syncManagerRef, {
    setIsLoading,
    setIsInitialized,
    setError,
    dispatch,
    onError,
  })

  useAutoSaveEffect(state, tenantId, isInitialized, enableBackendSync, syncManagerRef)

  const setCommandBarOpen = useCallback(
    (fn: boolean | ((prev: boolean) => boolean)) => {
      setCommandBarOpenRaw(typeof fn === 'function' ? fn : () => fn)
    },
    []
  )

  useKeyboardShortcutsEffect(isCommandBarOpen, setCommandBarOpen as (fn: (prev: boolean) => boolean) => void)

  // -------------------------------------------------------------------------
  // Navigation
  // -------------------------------------------------------------------------

  const currentStep = useMemo(() => getStepById(state.currentStep), [state.currentStep])

  const goToStep = useCallback(
    (stepId: string) => {
      const step = getStepById(stepId)
      if (step) {
        dispatch({ type: 'SET_CURRENT_STEP', payload: stepId })
        onNavigate?.(step.url)
      }
    },
    [onNavigate]
  )

  const goToNextStep = useCallback(() => {
    const nextStep = getNextStep(state.currentStep)
    if (nextStep) goToStep(nextStep.id)
  }, [state.currentStep, goToStep])

  const goToPreviousStep = useCallback(() => {
    const prevStep = getPreviousStep(state.currentStep)
    if (prevStep) goToStep(prevStep.id)
  }, [state.currentStep, goToStep])

  const canGoNext = useMemo(() => getNextStep(state.currentStep) !== undefined, [state.currentStep])
  const canGoPrevious = useMemo(
    () => getPreviousStep(state.currentStep) !== undefined,
    [state.currentStep]
  )

  const completionPercentage = useMemo(() => getCompletionPercentage(state), [state])
  const phase1Completion = useMemo(() => getPhaseCompletionPercentage(state, 1), [state])
  const phase2Completion = useMemo(() => getPhaseCompletionPercentage(state, 2), [state])

  // -------------------------------------------------------------------------
  // Callbacks (extracted to provider-callbacks.ts)
  // -------------------------------------------------------------------------

  const validateCheckpoint = useValidateCheckpoint(state, enableBackendSync, client, dispatch)
  const overrideCheckpoint = useOverrideCheckpoint(state, dispatch)
  const getCheckpointStatus = useGetCheckpointStatus(state)
  const updateUseCase = useUpdateUseCase(dispatch)
  const addRisk = useAddRisk(dispatch)
  const updateControl = useUpdateControl(dispatch)
  const saveState = useSaveState(state, tenantId, enableBackendSync, syncManagerRef, e => setError(e))
  const loadState = useLoadState(tenantId, enableBackendSync, syncManagerRef, setIsLoading, dispatch, e => setError(e))
  const resetState = useResetState(tenantId, dispatch)
  const forceSyncToServer = useForceSyncToServer(state, enableBackendSync, syncManagerRef)
  const exportState = useExportState(state, client)

  // -------------------------------------------------------------------------
  // Context value
  // -------------------------------------------------------------------------

  const value: ComplianceContextValue = {
    state,
    dispatch,
    client,
    dsgvo,
    compliance,
    rag,
    security,
    currentStep,
    goToStep,
    goToNextStep,
    goToPreviousStep,
    canGoNext,
    canGoPrevious,
    completionPercentage,
    phase1Completion,
    phase2Completion,
    validateCheckpoint,
    overrideCheckpoint,
    getCheckpointStatus,
    updateUseCase,
    addRisk,
    updateControl,
    saveState,
    loadState,
    resetState,
    syncState,
    forceSyncToServer,
    isOnline,
    exportState,
    isCommandBarOpen,
    setCommandBarOpen: setCommandBarOpenRaw,
    isInitialized,
    isLoading,
    error,
  }

  return <ComplianceContext.Provider value={value}>{children}</ComplianceContext.Provider>
}
