/**
 * SDK State Management
 *
 * Reducer-based state management with persistence support
 */

import type {
  SDKState,
  SDKAction,
  UserPreferences,
  SDKPhase,
  SubscriptionTier,
  getStepById,
} from '@breakpilot/compliance-sdk-types'

// =============================================================================
// INITIAL STATE
// =============================================================================

const initialPreferences: UserPreferences = {
  language: 'de',
  theme: 'light',
  compactMode: false,
  showHints: true,
  autoSave: true,
  autoValidate: true,
}

export const initialState: SDKState = {
  // Metadata
  version: '1.0.0',
  lastModified: new Date(),

  // Tenant & User
  tenantId: '',
  userId: '',
  subscription: 'PROFESSIONAL' as SubscriptionTier,

  // Progress
  currentPhase: 1 as SDKPhase,
  currentStep: 'use-case-workshop',
  completedSteps: [],
  checkpoints: {},

  // Phase 1 Data
  useCases: [],
  activeUseCase: null,
  screening: null,
  modules: [],
  requirements: [],
  controls: [],
  evidence: [],
  checklist: [],
  risks: [],

  // Phase 2 Data
  aiActClassification: null,
  obligations: [],
  dsfa: null,
  toms: [],
  retentionPolicies: [],
  vvt: [],
  documents: [],
  cookieBanner: null,
  consents: [],
  dsrConfig: null,
  dsrRequests: [],
  escalationWorkflows: [],

  // Security
  sbom: null,
  securityIssues: [],
  securityBacklog: [],

  // UI State
  commandBarHistory: [],
  recentSearches: [],
  preferences: initialPreferences,
}

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

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

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

    case 'SET_CURRENT_STEP': {
      // Import dynamically to avoid circular dependencies
      const { getStepById } = require('@breakpilot/compliance-sdk-types')
      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,
        },
      })

    // Use Cases
    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 })

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

    // Modules
    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
        ),
      })

    // Requirements
    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
        ),
      })

    // Controls
    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
        ),
      })

    // Evidence
    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),
      })

    // Risks
    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),
      })

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

    // Obligations
    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
        ),
      })

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

    // TOMs
    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
        ),
      })

    // Retention Policies
    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
        ),
      })

    // Processing Activities (VVT)
    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
        ),
      })

    // Documents
    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
        ),
      })

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

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

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

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

    // Escalation Workflows
    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
        ),
      })

    // Security
    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
        ),
      })

    // UI State
    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 'RESET_STATE':
      return { ...initialState, lastModified: new Date() }

    default:
      return state
  }
}

// =============================================================================
// STORE
// =============================================================================

export interface SDKStoreOptions {
  tenantId: string
  userId: string
  initialState?: Partial<SDKState>
  onChange?: (state: SDKState) => void
}

export interface SDKStore {
  getState: () => SDKState
  dispatch: (action: SDKAction) => void
  subscribe: (listener: (state: SDKState) => void) => () => void
}

export function createStore(options: SDKStoreOptions): SDKStore {
  let state: SDKState = {
    ...initialState,
    tenantId: options.tenantId,
    userId: options.userId,
    ...options.initialState,
  }

  const listeners = new Set<(state: SDKState) => void>()

  const getState = () => state

  const dispatch = (action: SDKAction) => {
    state = sdkReducer(state, action)
    listeners.forEach(listener => listener(state))
    options.onChange?.(state)
  }

  const subscribe = (listener: (state: SDKState) => void) => {
    listeners.add(listener)
    return () => listeners.delete(listener)
  }

  return { getState, dispatch, subscribe }
}
