import { APP_CONFIG_KEYS } from '../../config/app-config-keys.js'
import type { JsonObject } from '../../types/json.js'
import { readAppConfigEntry, saveAppConfigEntry } from '../config/app-config-store.js'

export const WORKER_PLATFORM_NOTIFICATION_EVENT_KEYS = [
  'withdraw_requested',
  'recharge_requested',
  'acceptance_submitted',
  'acceptance_reminded',
  'material_required',
  'cancel_requested',
  'feedback_submitted',
] as const

export type WorkerPlatformNotificationEventKey =
  (typeof WORKER_PLATFORM_NOTIFICATION_EVENT_KEYS)[number]

export type WorkerPlatformNotificationEventConfig = {
  todoEnabled: boolean
  soundEnabled: boolean
  externalPushEnabled: boolean
}

export type WorkerPlatformNotificationConfig = {
  events: Record<WorkerPlatformNotificationEventKey, WorkerPlatformNotificationEventConfig>
}

export function getWorkerPlatformNotificationConfig(): WorkerPlatformNotificationConfig {
  return readAppConfigEntry({
    configKey: APP_CONFIG_KEYS.workerPlatformNotifications,
    fallback: createDefaultWorkerPlatformNotificationConfig,
    normalize: normalizeWorkerPlatformNotificationConfig,
  })
}

export async function saveWorkerPlatformNotificationConfig(rawValue: unknown) {
  return saveAppConfigEntry({
    configKey: APP_CONFIG_KEYS.workerPlatformNotifications,
    value: rawValue,
    normalize: normalizeWorkerPlatformNotificationConfig,
  })
}

export function createDefaultWorkerPlatformNotificationConfig(): WorkerPlatformNotificationConfig {
  return {
    events: {
      withdraw_requested: createEnabledEventConfig(),
      recharge_requested: createEnabledEventConfig(),
      acceptance_submitted: createEnabledEventConfig(),
      acceptance_reminded: createEnabledEventConfig(),
      material_required: {
        todoEnabled: false,
        soundEnabled: false,
        externalPushEnabled: false,
      },
      cancel_requested: createEnabledEventConfig(),
      feedback_submitted: createEnabledEventConfig(),
    },
  }
}

export function normalizeWorkerPlatformNotificationConfig(
  rawValue: unknown,
): WorkerPlatformNotificationConfig {
  const source = isPlainObject(rawValue) ? rawValue : {}
  const rawEvents = isPlainObject(source.events) ? source.events : {}
  const defaults = createDefaultWorkerPlatformNotificationConfig()

  return {
    events: Object.fromEntries(
      WORKER_PLATFORM_NOTIFICATION_EVENT_KEYS.map((key) => [
        key,
        normalizeEventConfig(rawEvents[key], defaults.events[key]),
      ]),
    ) as WorkerPlatformNotificationConfig['events'],
  }
}

function createEnabledEventConfig(): WorkerPlatformNotificationEventConfig {
  return { todoEnabled: true, soundEnabled: true, externalPushEnabled: true }
}

function normalizeEventConfig(
  value: unknown,
  fallback: WorkerPlatformNotificationEventConfig,
): WorkerPlatformNotificationEventConfig {
  const source = isPlainObject(value) ? value : {}
  const todoEnabled =
    typeof source.todoEnabled === 'boolean' ? source.todoEnabled : fallback.todoEnabled
  return {
    todoEnabled,
    soundEnabled:
      todoEnabled &&
      (typeof source.soundEnabled === 'boolean' ? source.soundEnabled : fallback.soundEnabled),
    externalPushEnabled:
      typeof source.externalPushEnabled === 'boolean'
        ? source.externalPushEnabled
        : fallback.externalPushEnabled,
  }
}

function isPlainObject(value: unknown): value is JsonObject {
  return Object.prototype.toString.call(value) === '[object Object]'
}
