import {
  SDKState,
  getStepById,
} from './types'
import { ExtendedSDKAction, initialState } from './context-types'

// =============================================================================
// REDUCER
// =============================================================================

export function sdkReducer(state: SDKState, action: ExtendedSDKAction): SDKState {
  const updateState = (updates: Partial<SDKState>): SDKState => ({
    ...state,
    ...updates,
    lastModified: new Date(),
  })

  switch (action.type) {
    case 'SET_STATE':
      return updateState(action.payload)

    case 'LOAD_DEMO_DATA':
      // Load demo data while preserving user preferences
      return {
        ...initialState,
        ...action.payload,
        tenantId: state.tenantId,
        userId: state.userId,
        preferences: state.preferences,
        lastModified: new Date(),
      }

    case 'SET_CURRENT_STEP': {
      const step = getStepById(action.payload)
      return updateState({
        currentStep: action.payload,
        currentPhase: step?.phase || state.currentPhase,
      })
    }

    case 'COMPLETE_STEP':
      if (state.completedSteps.includes(action.payload)) {
        return state
      }
      return updateState({
        completedSteps: [...state.completedSteps, action.payload],
      })

    case 'SET_CHECKPOINT_STATUS':
      return updateState({
        checkpoints: {
          ...state.checkpoints,
          [action.payload.id]: action.payload.status,
        },
      })

    case 'SET_CUSTOMER_TYPE':
      return updateState({ customerType: action.payload })

    case 'SET_COMPANY_PROFILE':
      return updateState({ companyProfile: action.payload })

    case 'UPDATE_COMPANY_PROFILE':
      return updateState({
        companyProfile: state.companyProfile
          ? { ...state.companyProfile, ...action.payload }
          : null,
      })

    case 'SET_COMPLIANCE_SCOPE':
      return updateState({ complianceScope: action.payload })

    case 'UPDATE_COMPLIANCE_SCOPE':
      return updateState({
        complianceScope: state.complianceScope
          ? { ...state.complianceScope, ...action.payload }
          : null,
      })

    case 'ADD_IMPORTED_DOCUMENT':
      return updateState({
        importedDocuments: [...state.importedDocuments, action.payload],
      })

    case 'UPDATE_IMPORTED_DOCUMENT':
      return updateState({
        importedDocuments: state.importedDocuments.map(doc =>
          doc.id === action.payload.id ? { ...doc, ...action.payload.data } : doc
        ),
      })

    case 'DELETE_IMPORTED_DOCUMENT':
      return updateState({
        importedDocuments: state.importedDocuments.filter(doc => doc.id !== action.payload),
      })

    case 'SET_GAP_ANALYSIS':
      return updateState({ gapAnalysis: action.payload })

    case 'ADD_USE_CASE':
      return updateState({
        useCases: [...state.useCases, action.payload],
      })

    case 'UPDATE_USE_CASE':
      return updateState({
        useCases: state.useCases.map(uc =>
          uc.id === action.payload.id ? { ...uc, ...action.payload.data } : uc
        ),
      })

    case 'DELETE_USE_CASE':
      return updateState({
        useCases: state.useCases.filter(uc => uc.id !== action.payload),
        activeUseCase: state.activeUseCase === action.payload ? null : state.activeUseCase,
      })

    case 'SET_ACTIVE_USE_CASE':
      return updateState({ activeUseCase: action.payload })

    case 'SET_SCREENING':
      return updateState({ screening: action.payload })

    case 'ADD_MODULE':
      return updateState({
        modules: [...state.modules, action.payload],
      })

    case 'UPDATE_MODULE':
      return updateState({
        modules: state.modules.map(m =>
          m.id === action.payload.id ? { ...m, ...action.payload.data } : m
        ),
      })

    case 'ADD_REQUIREMENT':
      return updateState({
        requirements: [...state.requirements, action.payload],
      })

    case 'UPDATE_REQUIREMENT':
      return updateState({
        requirements: state.requirements.map(r =>
          r.id === action.payload.id ? { ...r, ...action.payload.data } : r
        ),
      })

    case 'ADD_CONTROL':
      return updateState({
        controls: [...state.controls, action.payload],
      })

    case 'UPDATE_CONTROL':
      return updateState({
        controls: state.controls.map(c =>
          c.id === action.payload.id ? { ...c, ...action.payload.data } : c
        ),
      })

    case 'ADD_EVIDENCE':
      return updateState({
        evidence: [...state.evidence, action.payload],
      })

    case 'UPDATE_EVIDENCE':
      return updateState({
        evidence: state.evidence.map(e =>
          e.id === action.payload.id ? { ...e, ...action.payload.data } : e
        ),
      })

    case 'DELETE_EVIDENCE':
      return updateState({
        evidence: state.evidence.filter(e => e.id !== action.payload),
      })

    case 'ADD_RISK':
      return updateState({
        risks: [...state.risks, action.payload],
      })

    case 'UPDATE_RISK':
      return updateState({
        risks: state.risks.map(r =>
          r.id === action.payload.id ? { ...r, ...action.payload.data } : r
        ),
      })

    case 'DELETE_RISK':
      return updateState({
        risks: state.risks.filter(r => r.id !== action.payload),
      })

    case 'SET_AI_ACT_RESULT':
      return updateState({ aiActClassification: action.payload })

    case 'ADD_OBLIGATION':
      return updateState({
        obligations: [...state.obligations, action.payload],
      })

    case 'UPDATE_OBLIGATION':
      return updateState({
        obligations: state.obligations.map(o =>
          o.id === action.payload.id ? { ...o, ...action.payload.data } : o
        ),
      })

    case 'SET_DSFA':
      return updateState({ dsfa: action.payload })

    case 'ADD_TOM':
      return updateState({
        toms: [...state.toms, action.payload],
      })

    case 'UPDATE_TOM':
      return updateState({
        toms: state.toms.map(t =>
          t.id === action.payload.id ? { ...t, ...action.payload.data } : t
        ),
      })

    case 'ADD_RETENTION_POLICY':
      return updateState({
        retentionPolicies: [...state.retentionPolicies, action.payload],
      })

    case 'UPDATE_RETENTION_POLICY':
      return updateState({
        retentionPolicies: state.retentionPolicies.map(p =>
          p.id === action.payload.id ? { ...p, ...action.payload.data } : p
        ),
      })

    case 'ADD_PROCESSING_ACTIVITY':
      return updateState({
        vvt: [...state.vvt, action.payload],
      })

    case 'UPDATE_PROCESSING_ACTIVITY':
      return updateState({
        vvt: state.vvt.map(p =>
          p.id === action.payload.id ? { ...p, ...action.payload.data } : p
        ),
      })

    case 'ADD_DOCUMENT':
      return updateState({
        documents: [...state.documents, action.payload],
      })

    case 'UPDATE_DOCUMENT':
      return updateState({
        documents: state.documents.map(d =>
          d.id === action.payload.id ? { ...d, ...action.payload.data } : d
        ),
      })

    case 'SET_COOKIE_BANNER':
      return updateState({ cookieBanner: action.payload })

    case 'SET_DSR_CONFIG':
      return updateState({ dsrConfig: action.payload })

    case 'ADD_ESCALATION_WORKFLOW':
      return updateState({
        escalationWorkflows: [...state.escalationWorkflows, action.payload],
      })

    case 'UPDATE_ESCALATION_WORKFLOW':
      return updateState({
        escalationWorkflows: state.escalationWorkflows.map(w =>
          w.id === action.payload.id ? { ...w, ...action.payload.data } : w
        ),
      })

    case 'ADD_SECURITY_ISSUE':
      return updateState({
        securityIssues: [...state.securityIssues, action.payload],
      })

    case 'UPDATE_SECURITY_ISSUE':
      return updateState({
        securityIssues: state.securityIssues.map(i =>
          i.id === action.payload.id ? { ...i, ...action.payload.data } : i
        ),
      })

    case 'ADD_BACKLOG_ITEM':
      return updateState({
        securityBacklog: [...state.securityBacklog, action.payload],
      })

    case 'UPDATE_BACKLOG_ITEM':
      return updateState({
        securityBacklog: state.securityBacklog.map(i =>
          i.id === action.payload.id ? { ...i, ...action.payload.data } : i
        ),
      })

    case 'ADD_COMMAND_HISTORY':
      return updateState({
        commandBarHistory: [action.payload, ...state.commandBarHistory].slice(0, 50),
      })

    case 'SET_PREFERENCES':
      return updateState({
        preferences: { ...state.preferences, ...action.payload },
      })

    case 'ADD_CUSTOM_CATALOG_ENTRY': {
      const entry = action.payload
      const existing = state.customCatalogs[entry.catalogId] || []
      return updateState({
        customCatalogs: {
          ...state.customCatalogs,
          [entry.catalogId]: [...existing, entry],
        },
      })
    }

    case 'UPDATE_CUSTOM_CATALOG_ENTRY': {
      const { catalogId, entryId, data } = action.payload
      const entries = state.customCatalogs[catalogId] || []
      return updateState({
        customCatalogs: {
          ...state.customCatalogs,
          [catalogId]: entries.map(e =>
            e.id === entryId ? { ...e, data: { ...e.data, ...data }, updatedAt: new Date().toISOString() } : e
          ),
        },
      })
    }

    case 'DELETE_CUSTOM_CATALOG_ENTRY': {
      const { catalogId, entryId } = action.payload
      const items = state.customCatalogs[catalogId] || []
      return updateState({
        customCatalogs: {
          ...state.customCatalogs,
          [catalogId]: items.filter(e => e.id !== entryId),
        },
      })
    }

    case 'RESET_STATE':
      return { ...initialState, lastModified: new Date() }

    default:
      return state
  }
}
