import { useState, useEffect, useCallback } from 'react'
import { nostrAuthService } from '@/lib/nostrAuth'
import { getLastSyncDate, setLastSyncDate as setLastSyncDateStorage, getCurrentTimestamp, calculateDaysBetween } from '@/lib/syncStorage'
import { MIN_EVENT_DATE } from '@/lib/platformConfig'
import { objectCache } from '@/lib/objectCache'
import { t } from '@/lib/i18n'
import { useSyncProgress } from '@/lib/hooks/useSyncProgress'

export function SyncProgressBar(): React.ReactElement | null {
  const [lastSyncDate, setLastSyncDate] = useState<number | null>(null)
  const [totalDays, setTotalDays] = useState<number>(0)
  const [isInitialized, setIsInitialized] = useState(false)
  const [connectionState, setConnectionState] = useState<{ connected: boolean; pubkey: string | null }>({ connected: false, pubkey: null })
  const [error, setError] = useState<string | null>(null)

  const loadSyncStatus = useCallback(async (): Promise<void> => {
    try {
      const state = nostrAuthService.getState()
      if (!state.connected || !state.pubkey) {
        return
      }

      const storedLastSyncDate = await getLastSyncDate()
      const currentTimestamp = getCurrentTimestamp()
      const days = calculateDaysBetween(storedLastSyncDate, currentTimestamp)

      setLastSyncDate(storedLastSyncDate)
      setTotalDays(days)
    } catch (loadError) {
      console.error('Error loading sync status:', loadError)
    }
  }, [])

  const { syncProgress, isSyncing, startMonitoring, stopMonitoring } = useSyncProgress({
    onComplete: loadSyncStatus,
  })

  useEffect(() => {
    // Check connection state
    const checkConnection = (): void => {
      const state = nostrAuthService.getState()
      console.warn('[SyncProgressBar] Initial connection check:', { connected: state.connected, pubkey: state.pubkey })
      setConnectionState({ connected: state.connected ?? false, pubkey: state.pubkey ?? null })
      setIsInitialized(true)
    }

    // Initial check
    checkConnection()

    // Listen to connection changes
    const unsubscribe = nostrAuthService.subscribe((state) => {
      console.warn('[SyncProgressBar] Connection state changed:', { connected: state.connected, pubkey: state.pubkey })
      setConnectionState({ connected: state.connected ?? false, pubkey: state.pubkey ?? null })
    })

    return () => {
      unsubscribe()
    }
  }, [])

  useEffect(() => {
    console.warn('[SyncProgressBar] Effect triggered:', { isInitialized, connected: connectionState.connected, pubkey: connectionState.pubkey, isSyncing })

    if (!isInitialized) {
      console.warn('[SyncProgressBar] Not initialized yet')
      return
    }

    if (!connectionState.connected) {
      console.warn('[SyncProgressBar] Not connected')
      return
    }

    if (!connectionState.pubkey) {
      console.warn('[SyncProgressBar] No pubkey')
      return
    }

    void runAutoSyncCheck({
      connection: { connected: connectionState.connected, pubkey: connectionState.pubkey },
      isSyncing,
      loadSyncStatus,
      startMonitoring,
      stopMonitoring,
      setError,
    })
  }, [isInitialized, connectionState.connected, connectionState.pubkey, isSyncing, loadSyncStatus, startMonitoring, stopMonitoring])

  async function resynchronize(): Promise<void> {
    try {
      const state = nostrAuthService.getState()
      if (!state.connected || !state.pubkey) {
        return
      }

      // Clear cache for user content (but keep other data)
      await Promise.all([
        objectCache.clear('author'),
        objectCache.clear('series'),
        objectCache.clear('publication'),
        objectCache.clear('review'),
        objectCache.clear('purchase'),
        objectCache.clear('sponsoring'),
        objectCache.clear('review_tip'),
      ])

      // Reset last sync date to force full resync
      await setLastSyncDateStorage(MIN_EVENT_DATE)

      // Reload sync status
      await loadSyncStatus()

      // Start full resynchronization via Service Worker
      if (state.pubkey !== null) {
        const { swClient } = await import('@/lib/swClient')
        const isReady = await swClient.isReady()
        if (isReady) {
          await swClient.startUserSync(state.pubkey)
          startMonitoring()
        } else {
          stopMonitoring()
        }
      }
    } catch (resyncError) {
      console.error('Error resynchronizing:', resyncError)
      stopMonitoring()
    }
  }

  // Don't show if not initialized or not connected
  if (!isInitialized || !connectionState.connected || !connectionState.pubkey) {
    return null
  }

  // Check if sync is recently completed (within last hour)
  const isRecentlySynced = lastSyncDate !== null && lastSyncDate >= getCurrentTimestamp() - 3600

  const progressPercentage = computeProgressPercentage(syncProgress)

  const formatDate = (timestamp: number): string => {
    const date = new Date(timestamp * 1000)
    const locale = typeof window !== 'undefined' ? navigator.language : 'fr-FR'
    return date.toLocaleDateString(locale, { day: '2-digit', month: '2-digit', year: 'numeric' })
  }

  const getStartDate = (): number => {
    if (lastSyncDate !== null) {
      return lastSyncDate
    }
    return MIN_EVENT_DATE
  }

  const startDate = getStartDate()
  const endDate = getCurrentTimestamp()

  return (
    <div className="bg-cyber-darker border border-neon-cyan/30 rounded-lg p-4 mt-6">
      <SyncErrorBanner
        error={error}
        onDismiss={() => {
          setError(null)
        }}
      />
      <div className="flex items-center justify-between mb-2">
        <h3 className="text-lg font-semibold text-neon-cyan">
          {t('settings.sync.title')}
        </h3>
        <SyncResyncButton
          isSyncing={isSyncing}
          onClick={() => {
            void resynchronize()
          }}
        />
      </div>

      <SyncDateRange
        totalDays={totalDays}
        startDate={formatDate(startDate)}
        endDate={formatDate(endDate)}
      />

      <SyncProgressSection
        isSyncing={isSyncing}
        syncProgress={syncProgress}
        progressPercentage={progressPercentage}
      />

      <SyncStatusMessage
        isSyncing={isSyncing}
        totalDays={totalDays}
        isRecentlySynced={isRecentlySynced}
      />
    </div>
  )
}

function computeProgressPercentage(syncProgress: ReturnType<typeof useSyncProgress>['syncProgress']): number {
  if (!syncProgress || syncProgress.totalSteps <= 0) {
    return 0
  }
  return Math.min(100, (syncProgress.currentStep / syncProgress.totalSteps) * 100)
}

function SyncErrorBanner(params: { error: string | null; onDismiss: () => void }): React.ReactElement | null {
  if (!params.error) {
    return null
  }
  return (
    <div className="mb-4 bg-red-900/30 border border-red-500/50 rounded p-3 text-red-300 text-sm">
      {params.error}
      <button onClick={params.onDismiss} className="ml-2 text-red-400 hover:text-red-200">
        ×
      </button>
    </div>
  )
}

function SyncResyncButton(params: { isSyncing: boolean; onClick: () => void }): React.ReactElement | null {
  if (params.isSyncing) {
    return null
  }
  return (
    <button
      onClick={params.onClick}
      className="px-3 py-1 text-xs bg-neon-cyan/20 hover:bg-neon-cyan/30 text-neon-cyan rounded border border-neon-cyan/50 hover:border-neon-cyan transition-colors"
    >
      {t('settings.sync.resync')}
    </button>
  )
}

function SyncDateRange(params: { totalDays: number; startDate: string; endDate: string }): React.ReactElement | null {
  if (params.totalDays <= 0) {
    return null
  }
  return (
    <div className="mb-2">
      <p className="text-sm text-cyber-accent">
        {t('settings.sync.daysRange', {
          startDate: params.startDate,
          endDate: params.endDate,
          days: params.totalDays,
        })}
      </p>
    </div>
  )
}

function SyncProgressSection(params: {
  isSyncing: boolean
  syncProgress: ReturnType<typeof useSyncProgress>['syncProgress']
  progressPercentage: number
}): React.ReactElement | null {
  if (!params.isSyncing || !params.syncProgress) {
    return null
  }
  return (
    <div className="space-y-2">
      <div className="flex items-center justify-between text-sm">
        <span className="text-cyber-accent">
          {t('settings.sync.progress', {
            current: params.syncProgress.currentStep,
            total: params.syncProgress.totalSteps,
          })}
        </span>
        <span className="text-neon-cyan font-semibold">{Math.round(params.progressPercentage)}%</span>
      </div>
      <div className="w-full bg-cyber-dark rounded-full h-2 overflow-hidden">
        <div className="bg-neon-cyan h-full transition-all duration-300" style={{ width: `${params.progressPercentage}%` }} />
      </div>
    </div>
  )
}

function SyncStatusMessage(params: { isSyncing: boolean; totalDays: number; isRecentlySynced: boolean }): React.ReactElement | null {
  if (params.isSyncing || params.totalDays !== 0) {
    return null
  }
  if (params.isRecentlySynced) {
    return <p className="text-sm text-green-400">{t('settings.sync.completed')}</p>
  }
  return <p className="text-sm text-cyber-accent">{t('settings.sync.ready')}</p>
}

async function runAutoSyncCheck(params: {
  connection: { connected: boolean; pubkey: string | null }
  isSyncing: boolean
  loadSyncStatus: () => Promise<void>
  startMonitoring: () => void
  stopMonitoring: () => void
  setError: (value: string | null) => void
}): Promise<void> {
  console.warn('[SyncProgressBar] Starting sync check...')
  await params.loadSyncStatus()

  const shouldStart = await shouldAutoStartSync({
    isSyncing: params.isSyncing,
    pubkey: params.connection.pubkey,
  })

  if (!shouldStart || !params.connection.pubkey) {
    console.warn('[SyncProgressBar] Skipping auto-sync:', { shouldStart, isSyncing: params.isSyncing, hasPubkey: Boolean(params.connection.pubkey) })
    return
  }

  console.warn('[SyncProgressBar] Starting auto-sync...')
  await startAutoSync({
    pubkey: params.connection.pubkey,
    startMonitoring: params.startMonitoring,
    stopMonitoring: params.stopMonitoring,
    setError: params.setError,
  })
}

async function shouldAutoStartSync(params: { isSyncing: boolean; pubkey: string | null }): Promise<boolean> {
  if (params.isSyncing || !params.pubkey) {
    return false
  }
  const storedLastSyncDate = await getLastSyncDate()
  const currentTimestamp = getCurrentTimestamp()
  const isRecentlySynced = storedLastSyncDate >= currentTimestamp - 3600
  console.warn('[SyncProgressBar] Sync status:', { storedLastSyncDate, currentTimestamp, isRecentlySynced })
  return !isRecentlySynced
}

async function startAutoSync(params: {
  pubkey: string
  startMonitoring: () => void
  stopMonitoring: () => void
  setError: (value: string | null) => void
}): Promise<void> {
  try {
    const { swClient } = await import('@/lib/swClient')
    const isReady = await swClient.isReady()
    if (!isReady) {
      params.stopMonitoring()
      return
    }
    await swClient.startUserSync(params.pubkey)
    params.startMonitoring()
  } catch (autoSyncError) {
    console.error('[SyncProgressBar] Error during auto-sync:', autoSyncError)
    params.stopMonitoring()
    params.setError(autoSyncError instanceof Error ? autoSyncError.message : 'Erreur de synchronisation')
  }
}
