'use client'

import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react'
import type {
  AlertSource,
  B2BHit,
  B2BTopic,
  B2BTemplate,
  B2BTenant,
  B2BSettings,
  AlertsB2BContextType,
} from './alerts-b2b/types'
import { hectronicTemplate, mockHectronicHits, defaultB2BSettings, defaultTenant } from './alerts-b2b/template-data'
import { processEmailToHit } from './alerts-b2b/actions'

// Re-export all types and helpers for backward compatibility
export type {
  ImportanceLabel,
  DecisionLabel,
  SourceType,
  NoiseMode,
  Package,
  AlertSource,
  B2BHit,
  DecisionTrace,
  B2BTopic,
  TopicIntent,
  TopicFilters,
  DecisionPolicy,
  ImportanceModel,
  B2BTemplate,
  GuidedConfig,
  NotificationPreset,
  B2BTenant,
  B2BSettings,
} from './alerts-b2b/types'
export { hectronicTemplate } from './alerts-b2b/template-data'
export {
  getImportanceLabelColor,
  getDecisionLabelColor,
  formatDeadline,
  getPackageIcon,
  getPackageLabel,
} from './alerts-b2b/helpers'

// ============================================
// CONTEXT
// ============================================

const AlertsB2BContext = createContext<AlertsB2BContextType | null>(null)

// LocalStorage Keys
const B2B_TENANT_KEY = 'bp_b2b_tenant'
const B2B_SETTINGS_KEY = 'bp_b2b_settings'
const B2B_SOURCES_KEY = 'bp_b2b_sources'
const B2B_TOPICS_KEY = 'bp_b2b_topics'
const B2B_HITS_KEY = 'bp_b2b_hits'

export function AlertsB2BProvider({ children }: { children: ReactNode }) {
  const [tenant, setTenant] = useState<B2BTenant>(defaultTenant)
  const [settings, setSettings] = useState<B2BSettings>(defaultB2BSettings)
  const [sources, setSources] = useState<AlertSource[]>([])
  const [topics, setTopics] = useState<B2BTopic[]>([])
  const [hits, setHits] = useState<B2BHit[]>([])
  const [selectedTemplate, setSelectedTemplate] = useState<B2BTemplate | null>(null)
  const [isLoading] = useState(false)
  const [error] = useState<string | null>(null)
  const [mounted, setMounted] = useState(false)

  // Available templates
  const availableTemplates: B2BTemplate[] = [hectronicTemplate]

  // Load from localStorage
  useEffect(() => {
    const storedTenant = localStorage.getItem(B2B_TENANT_KEY)
    const storedSettings = localStorage.getItem(B2B_SETTINGS_KEY)
    const storedSources = localStorage.getItem(B2B_SOURCES_KEY)
    const storedTopics = localStorage.getItem(B2B_TOPICS_KEY)
    const storedHits = localStorage.getItem(B2B_HITS_KEY)

    if (storedTenant) {
      try {
        const parsed = JSON.parse(storedTenant)
        setTenant({ ...defaultTenant, ...parsed, createdAt: new Date(parsed.createdAt) })
      } catch (e) {
        console.error('Error parsing tenant:', e)
      }
    }

    if (storedSettings) {
      try {
        setSettings({ ...defaultB2BSettings, ...JSON.parse(storedSettings) })
      } catch (e) {
        console.error('Error parsing settings:', e)
      }
    }

    if (storedSources) {
      try {
        const parsed = JSON.parse(storedSources)
        setSources(parsed.map((s: any) => ({ ...s, createdAt: new Date(s.createdAt) })))
      } catch (e) {
        console.error('Error parsing sources:', e)
      }
    }

    if (storedTopics) {
      try {
        const parsed = JSON.parse(storedTopics)
        setTopics(parsed.map((t: any) => ({ ...t, createdAt: new Date(t.createdAt) })))
      } catch (e) {
        console.error('Error parsing topics:', e)
      }
    }

    if (storedHits) {
      try {
        const parsed = JSON.parse(storedHits)
        setHits(parsed.map((h: any) => ({
          ...h,
          foundAt: new Date(h.foundAt),
          createdAt: new Date(h.createdAt)
        })))
      } catch (e) {
        console.error('Error parsing hits:', e)
        setHits(mockHectronicHits)
      }
    } else {
      setHits(mockHectronicHits)
    }

    setMounted(true)
  }, [])

  // Save to localStorage
  useEffect(() => {
    if (mounted) localStorage.setItem(B2B_TENANT_KEY, JSON.stringify(tenant))
  }, [tenant, mounted])

  useEffect(() => {
    if (mounted) localStorage.setItem(B2B_SETTINGS_KEY, JSON.stringify(settings))
  }, [settings, mounted])

  useEffect(() => {
    if (mounted) localStorage.setItem(B2B_SOURCES_KEY, JSON.stringify(sources))
  }, [sources, mounted])

  useEffect(() => {
    if (mounted) localStorage.setItem(B2B_TOPICS_KEY, JSON.stringify(topics))
  }, [topics, mounted])

  useEffect(() => {
    if (mounted && hits.length > 0) localStorage.setItem(B2B_HITS_KEY, JSON.stringify(hits))
  }, [hits, mounted])

  // Tenant operations
  const updateTenant = useCallback((updates: Partial<B2BTenant>) => {
    setTenant(prev => ({ ...prev, ...updates }))
  }, [])

  const updateSettings = useCallback((updates: Partial<B2BSettings>) => {
    setSettings(prev => ({ ...prev, ...updates }))
  }, [])

  // Template operations
  const selectTemplate = useCallback((templateId: string) => {
    const template = availableTemplates.find(t => t.templateId === templateId)
    if (template) {
      setSelectedTemplate(template)
      updateSettings({
        selectedTemplateId: templateId,
        selectedRegions: template.guidedConfig.regionSelector.default,
        selectedLanguages: template.guidedConfig.languageSelector.default,
        selectedPackages: template.guidedConfig.packageSelector.default,
        noiseMode: template.guidedConfig.noiseMode.default,
        notificationCadence: template.notificationPreset.cadence,
        notificationTime: template.notificationPreset.timeLocal,
        maxDigestItems: template.notificationPreset.maxItems
      })
      const newTopics: B2BTopic[] = template.topics.map((t, idx) => ({
        ...t,
        id: `topic-${Date.now()}-${idx}`,
        tenantId: tenant.id,
        createdAt: new Date()
      }))
      setTopics(newTopics)
    }
  }, [availableTemplates, tenant.id, updateSettings])

  // Source operations
  const generateInboundEmail = useCallback(() => {
    const token = Math.random().toString(36).substring(2, 10)
    return `alerts+${tenant.id}-${token}@${tenant.inboundEmailDomain}`
  }, [tenant.id, tenant.inboundEmailDomain])

  const addSource = useCallback((source: Omit<AlertSource, 'id' | 'createdAt'>) => {
    const newSource: AlertSource = {
      ...source,
      id: `source-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      createdAt: new Date()
    }
    setSources(prev => [...prev, newSource])
  }, [])

  const removeSource = useCallback((id: string) => {
    setSources(prev => prev.filter(s => s.id !== id))
  }, [])

  // Topic operations
  const addTopic = useCallback((topic: Omit<B2BTopic, 'id' | 'createdAt'>) => {
    const newTopic: B2BTopic = {
      ...topic,
      id: `topic-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      createdAt: new Date()
    }
    setTopics(prev => [...prev, newTopic])
  }, [])

  const updateTopic = useCallback((id: string, updates: Partial<B2BTopic>) => {
    setTopics(prev => prev.map(t => t.id === id ? { ...t, ...updates } : t))
  }, [])

  const removeTopic = useCallback((id: string) => {
    setTopics(prev => prev.filter(t => t.id !== id))
  }, [])

  // Hit operations
  const markAsRead = useCallback((id: string) => {
    setHits(prev => prev.map(h => h.id === id ? { ...h, isRead: true } : h))
  }, [])

  const markAllAsRead = useCallback(() => {
    setHits(prev => prev.map(h => ({ ...h, isRead: true })))
  }, [])

  const submitFeedback = useCallback((id: string, feedback: 'relevant' | 'irrelevant') => {
    setHits(prev => prev.map(h => h.id === id ? { ...h, userFeedback: feedback } : h))
  }, [])

  const processEmailContent = useCallback((emailContent: string, emailSubject?: string): B2BHit => {
    const newHit = processEmailToHit(
      emailContent,
      tenant.id,
      topics[0]?.id || 'default',
      emailSubject
    )
    setHits(prev => [newHit, ...prev])
    return newHit
  }, [tenant.id, topics])

  // Digest
  const getDigest = useCallback((maxItems: number = settings.maxDigestItems) => {
    return hits
      .filter(h => h.decisionLabel === 'relevant' || h.decisionLabel === 'needs_review')
      .sort((a, b) => b.importanceScore - a.importanceScore)
      .slice(0, maxItems)
  }, [hits, settings.maxDigestItems])

  // Computed values
  const unreadCount = hits.filter(h => !h.isRead && h.decisionLabel !== 'irrelevant').length
  const relevantCount = hits.filter(h => h.decisionLabel === 'relevant').length
  const needsReviewCount = hits.filter(h => h.decisionLabel === 'needs_review').length

  // SSR safety
  if (!mounted) {
    return (
      <AlertsB2BContext.Provider
        value={{
          tenant: defaultTenant,
          updateTenant: () => {},
          settings: defaultB2BSettings,
          updateSettings: () => {},
          availableTemplates: [],
          selectedTemplate: null,
          selectTemplate: () => {},
          sources: [],
          addSource: () => {},
          removeSource: () => {},
          generateInboundEmail: () => '',
          topics: [],
          addTopic: () => {},
          updateTopic: () => {},
          removeTopic: () => {},
          hits: [],
          unreadCount: 0,
          relevantCount: 0,
          needsReviewCount: 0,
          markAsRead: () => {},
          markAllAsRead: () => {},
          submitFeedback: () => {},
          processEmailContent: () => ({} as B2BHit),
          getDigest: () => [],
          isLoading: false,
          error: null
        }}
      >
        {children}
      </AlertsB2BContext.Provider>
    )
  }

  return (
    <AlertsB2BContext.Provider
      value={{
        tenant,
        updateTenant,
        settings,
        updateSettings,
        availableTemplates,
        selectedTemplate,
        selectTemplate,
        sources,
        addSource,
        removeSource,
        generateInboundEmail,
        topics,
        addTopic,
        updateTopic,
        removeTopic,
        hits,
        unreadCount,
        relevantCount,
        needsReviewCount,
        markAsRead,
        markAllAsRead,
        submitFeedback,
        processEmailContent,
        getDigest,
        isLoading,
        error
      }}
    >
      {children}
    </AlertsB2BContext.Provider>
  )
}

export function useAlertsB2B() {
  const context = useContext(AlertsB2BContext)
  if (!context) {
    throw new Error('useAlertsB2B must be used within an AlertsB2BProvider')
  }
  return context
}
