'use client'

import React, {
  useReducer,
  useMemo,
  useEffect,
  useState,
  useContext,
} from 'react'

import {
  VendorComplianceContextValue,
  VendorStatistics,
  ComplianceStatistics,
  RiskOverview,
  VendorStatus,
  VendorRole,
  RiskLevel,
  FindingType,
  FindingSeverity,
  getRiskLevelFromScore,
} from './types'

import { initialState, vendorComplianceReducer } from './reducer'
import { VendorComplianceContext } from './hooks'
import { useVendorComplianceActions } from './use-actions'
import { useContextApiActions } from './context-actions'

// Re-export hooks and selectors for barrel
export {
  useVendorCompliance,
  useVendor,
  useProcessingActivity,
  useVendorContracts,
  useVendorFindings,
  useContractFindings,
  useControlInstancesForEntity,
} from './hooks'

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

interface VendorComplianceProviderProps {
  children: React.ReactNode
  tenantId?: string
}

export function VendorComplianceProvider({
  children,
  tenantId,
}: VendorComplianceProviderProps) {
  const [state, dispatch] = useReducer(vendorComplianceReducer, initialState)
  const [isInitialized, setIsInitialized] = useState(false)

  const actions = useVendorComplianceActions(state, dispatch)

  // ==========================================
  // COMPUTED VALUES
  // ==========================================

  const vendorStats = useMemo<VendorStatistics>(() => {
    const vendors = state.vendors

    const byStatus = vendors.reduce(
      (acc, v) => {
        acc[v.status] = (acc[v.status] || 0) + 1
        return acc
      },
      {} as Record<VendorStatus, number>
    )

    const byRole = vendors.reduce(
      (acc, v) => {
        acc[v.role] = (acc[v.role] || 0) + 1
        return acc
      },
      {} as Record<VendorRole, number>
    )

    const byRiskLevel = vendors.reduce(
      (acc, v) => {
        const level = getRiskLevelFromScore(v.residualRiskScore / 4)
        acc[level] = (acc[level] || 0) + 1
        return acc
      },
      {} as Record<RiskLevel, number>
    )

    const now = new Date()
    const pendingReviews = vendors.filter(
      (v) => v.nextReviewDate && new Date(v.nextReviewDate) <= now
    ).length

    const withExpiredContracts = vendors.filter((v) =>
      state.contracts.some(
        (c) =>
          c.vendorId === v.id &&
          c.expirationDate &&
          new Date(c.expirationDate) <= now &&
          c.status === 'ACTIVE'
      )
    ).length

    return {
      total: vendors.length,
      byStatus,
      byRole,
      byRiskLevel,
      pendingReviews,
      withExpiredContracts,
    }
  }, [state.vendors, state.contracts])

  const complianceStats = useMemo<ComplianceStatistics>(() => {
    const findings = state.findings
    const contracts = state.contracts
    const controlInstances = state.controlInstances

    const averageComplianceScore =
      contracts.length > 0
        ? contracts.reduce((sum, c) => sum + (c.complianceScore || 0), 0) /
          contracts.filter((c) => c.complianceScore !== undefined).length || 0
        : 0

    const findingsByType = findings.reduce(
      (acc, f) => {
        acc[f.type] = (acc[f.type] || 0) + 1
        return acc
      },
      {} as Record<FindingType, number>
    )

    const findingsBySeverity = findings.reduce(
      (acc, f) => {
        acc[f.severity] = (acc[f.severity] || 0) + 1
        return acc
      },
      {} as Record<FindingSeverity, number>
    )

    const openFindings = findings.filter(
      (f) => f.status === 'OPEN' || f.status === 'IN_PROGRESS'
    ).length

    const resolvedFindings = findings.filter(
      (f) => f.status === 'RESOLVED' || f.status === 'FALSE_POSITIVE'
    ).length

    const passedControls = controlInstances.filter(
      (ci) => ci.status === 'PASS'
    ).length
    const applicableControls = controlInstances.filter(
      (ci) => ci.status !== 'NOT_APPLICABLE'
    ).length
    const controlPassRate =
      applicableControls > 0 ? (passedControls / applicableControls) * 100 : 0

    return {
      averageComplianceScore,
      findingsByType,
      findingsBySeverity,
      openFindings,
      resolvedFindings,
      controlPassRate,
    }
  }, [state.findings, state.contracts, state.controlInstances])

  const riskOverview = useMemo<RiskOverview>(() => {
    const vendors = state.vendors
    const findings = state.findings

    const averageInherentRisk =
      vendors.length > 0
        ? vendors.reduce((sum, v) => sum + v.inherentRiskScore, 0) / vendors.length
        : 0

    const averageResidualRisk =
      vendors.length > 0
        ? vendors.reduce((sum, v) => sum + v.residualRiskScore, 0) / vendors.length
        : 0

    const highRiskVendors = vendors.filter(
      (v) => v.residualRiskScore >= 60
    ).length

    const criticalFindings = findings.filter(
      (f) => f.severity === 'CRITICAL' && f.status === 'OPEN'
    ).length

    const transfersToThirdCountries = vendors.filter((v) =>
      v.processingLocations.some((pl) => !pl.isEU && !pl.isAdequate)
    ).length

    return {
      averageInherentRisk,
      averageResidualRisk,
      highRiskVendors,
      criticalFindings,
      transfersToThirdCountries,
    }
  }, [state.vendors, state.findings])

  // ==========================================
  // API CALLS (extracted to context-actions.tsx)
  // ==========================================

  const {
    loadData,
    refresh,
    createProcessingActivity,
    deleteProcessingActivity,
    duplicateProcessingActivity,
    deleteVendor,
    deleteContract,
    startContractReview,
  } = useContextApiActions(state, dispatch)

  // ==========================================
  // INITIALIZATION
  // ==========================================

  useEffect(() => {
    if (!isInitialized) {
      actions.loadData()
      setIsInitialized(true)
    }
  }, [isInitialized, actions])

  // ==========================================
  // CONTEXT VALUE
  // ==========================================

  const contextValue = useMemo<VendorComplianceContextValue>(
    () => ({
      ...state,
      dispatch,
      vendorStats,
      complianceStats,
      riskOverview,
      deleteProcessingActivity,
      duplicateProcessingActivity,
      deleteVendor,
      deleteContract,
      startContractReview,
      loadData,
      refresh,
    } as VendorComplianceContextValue),
    [
      state,
      vendorStats,
      complianceStats,
      riskOverview,
      deleteProcessingActivity,
      duplicateProcessingActivity,
      deleteVendor,
      deleteContract,
      startContractReview,
      loadData,
      refresh,
    ]
  )

  return (
    <VendorComplianceContext.Provider value={contextValue}>
      {children}
    </VendorComplianceContext.Provider>
  )
}


