import { randomUUID } from "node:crypto";

export const SUPPORTED_LOCALES = Object.freeze([
  "zh-CN",
  "en",
  "ms",
  "id",
  "th",
  "vi"
]);

export const EVENT_TYPES = Object.freeze({
  GAME_SESSION_STARTED: "game_session_started",
  GAME_SESSION_ENDED: "game_session_ended",
  RULE_SNAPSHOT_CREATED: "rule_snapshot_created",
  GAME_ACTION_TRIGGERED: "game_action_triggered",
  VISUAL_COMMAND_CREATED: "visual_command_created",
  VISUAL_PLAYED: "visual_played",
  VISUAL_FOLDED: "visual_folded",
  VISUAL_INTERRUPTED: "visual_interrupted",
  VISUAL_SKIPPED: "visual_skipped",
  AUDIO_PLAYED: "audio_played",
  AUDIO_MERGED: "audio_merged",
  PERFORMANCE_FALLBACK: "performance_fallback",
  SAFE_DISPLAY_ENTERED: "safe_display_entered",
  OPERATOR_ACTION_RECORDED: "operator_action_recorded",
  MAIN_GAMEPLAY_SWITCHED: "main_gameplay_switched",
  ONBOARDING_EVENT_RECORDED: "onboarding_event_recorded",
  ROOM_BINDING_CHANGED: "room_binding_changed",
  DEVICE_BINDING_CHANGED: "device_binding_changed",
  ENTITLEMENT_SNAPSHOT_CREATED: "entitlement_snapshot_created",
  USAGE_RESERVED: "usage_reserved",
  USAGE_COMMITTED: "usage_committed",
  USAGE_RELEASED: "usage_released",
  GIFT_RECEIVED: "gift_received",
  GIFT_EVENT_LIVE_CONFIRMED: "gift_event_live_confirmed",
  GIFT_EVENT_DUPLICATE_IGNORED: "gift_event_duplicate_ignored",
  GIFT_EVENT_NEEDS_REVIEW: "gift_event_needs_review",
  GIFT_EVENT_OFFICIAL_RECONCILED: "gift_event_official_reconciled",
  GIFT_EVENT_OFFICIAL_ADJUSTED: "gift_event_official_adjusted",
  GIFT_SOURCE_ROUTE_CHANGED: "gift_source_route_changed",
  GIFT_SOURCE_MISMATCH_REPORTED: "gift_source_mismatch_reported",
  PK_SCORE_CHANGED: "pk_score_changed",
  DATA_SOURCE_HEALTH_REPORTED: "data_source_health_reported",
  PUBLIC_CHAT_RECEIVED: "public_chat_received",
  VIEWER_MEMBER_JOINED: "viewer_member_joined",
  VIEWER_FOLLOWED: "viewer_followed",
  VIEWER_SHARED: "viewer_shared",
  LIKE_BURST_RECORDED: "like_burst_recorded",
  ROOM_METRIC_SAMPLED: "room_metric_sampled",
  VIEWER_VISIBLE_LABELS_OBSERVED: "viewer_visible_labels_observed",
  FAN_CLUB_EVENT_RECORDED: "fan_club_event_recorded",
  ROOM_PIN_UPDATED: "room_pin_updated",
  PROMOTION_OR_PRODUCT_PINNED: "promotion_or_product_pinned",
  LIVE_BATTLE_STATE_CHANGED: "live_battle_state_changed",
  SYSTEM_NOTICE_RECEIVED: "system_notice_received",
  MODERATION_ACTION_RECORDED: "moderation_action_recorded",
  HOST_OR_ROLE_SNAPSHOT: "host_or_role_snapshot",
  LIVE_SOURCE_HEALTH_REPORTED: "live_source_health_reported",
  STREAM_LIFECYCLE_RECORDED: "stream_lifecycle_recorded",
  MEDIA_RECORDING_STARTED: "media_recording_started",
  MEDIA_SEGMENT_WRITTEN: "media_segment_written",
  MEDIA_RECORDING_ENDED: "media_recording_ended",
  P1_CAPTURE_DEGRADED: "p1_capture_degraded",
  P1_CAPTURE_RECOVERED: "p1_capture_recovered",
  P1_REPLAY_COMPLETED: "p1_replay_completed",
  ANALYTICS_EVIDENCE_HEALTH_REPORTED: "analytics_evidence_health_reported",
  ANALYTICS_CANDIDATE_WINDOW_CREATED: "analytics_candidate_window_created",
  SESSION_SUMMARY_EXPORTED: "session_summary_exported",
  LIVE_TRANSLATION_SESSION_STARTED: "live_translation_session_started",
  LIVE_TRANSLATION_SESSION_DEGRADED: "live_translation_session_degraded",
  LIVE_TRANSLATION_SEGMENT_READY: "live_translation_segment_ready",
  LIVE_TRANSLATION_SEGMENT_SKIPPED: "live_translation_segment_skipped",
  LIVE_TRANSLATION_SESSION_ENDED: "live_translation_session_ended"
});

export const GAME_TYPES = Object.freeze({
  DYNAMIC_DUO_PK: "dynamic_duo_pk",
  OVERTIME_CHALLENGE: "overtime_challenge",
  VOTE: "vote",
  CARD_REVEAL: "card_reveal",
  STAGE_CONTROL: "stage_control",
  PRANK_SHOOTING: "prank_shooting",
  THANKS_BOARD: "thanks_board"
});

export const EVENT_SOURCES = Object.freeze({
  MOCK: "mock",
  REALTIME_PRIMARY: "realtime_primary",
  REALTIME_BACKUP: "realtime_backup",
  LIVE_TOOL_GUARDIAN: "live_tool_guardian",
  OPERATOR: "operator",
  SYSTEM: "system",
  OFFICIAL_BACKEND: "official_backend"
});

export const CUSTOMER_ROLES = Object.freeze({
  ADMIN: "admin",
  OPERATOR: "operator"
});

export const INTERNAL_ROLES = Object.freeze({
  SUPER_ADMIN: "super_admin",
  ADMIN: "admin",
  SALES: "sales"
});

export const PERMISSIONS = Object.freeze({
  MANAGE_ACCOUNT: "manage_account",
  MANAGE_OPERATORS: "manage_operators",
  MANAGE_TEMPLATES: "manage_templates",
  RUN_GAMEPLAY: "run_gameplay",
  EXPORT_DATA: "export_data",
  FULL_EXPORT_DATA: "full_export_data",
  BIND_LIVE_ROOM: "bind_live_room",
  UNBIND_LIVE_ROOM: "unbind_live_room",
  TRANSFER_DEVICE: "transfer_device",
  DELETE_DATA: "delete_data",
  VIEW_AUDIT_LOG: "view_audit_log",
  VIEW_RENEWAL: "view_renewal",
  MANAGE_RENEWAL: "manage_renewal",
  VIEW_SYSTEM_HEALTH: "view_system_health",
  MANAGE_RELEASES: "manage_releases"
});

export const SENSITIVE_PERMISSIONS = Object.freeze([
  PERMISSIONS.TRANSFER_DEVICE,
  PERMISSIONS.FULL_EXPORT_DATA,
  PERMISSIONS.BIND_LIVE_ROOM,
  PERMISSIONS.UNBIND_LIVE_ROOM,
  PERMISSIONS.DELETE_DATA
]);

export const FEATURES = Object.freeze({
  GAMEPLAY: "gameplay",
  ADVANCED_GAMEPLAY: "advanced_gameplay",
  TRANSLATION: "translation",
  ANALYTICS: "analytics",
  PLUGIN_FACTORY: "plugin_factory",
  DATA_EXPORT: "data_export",
  FULL_DATA_EXPORT: "full_data_export",
  INTERNAL_OPS: "internal_ops"
});

export const PLAN_CODES = Object.freeze({
  CLOSED_BETA: "closed_beta",
  STANDARD: "standard",
  DELUXE: "deluxe"
});

export const DEVICE_STATES = Object.freeze({
  ACTIVE: "active",
  PENDING_CONFIRMATION: "pending_confirmation",
  TRANSFER_PENDING: "transfer_pending",
  LIMITED: "limited",
  DISABLED: "disabled"
});

export const SESSION_MODES = Object.freeze({
  REHEARSAL: "rehearsal",
  FORMAL: "formal"
});

export const RELEASE_CHANNELS = Object.freeze({
  INTERNAL: "internal",
  ALPHA: "alpha",
  BETA: "beta",
  STABLE: "stable"
});

export const RELEASE_STAGES = Object.freeze({
  INTERNAL_ONLY: 1,
  FOUNDATION_READY: 2,
  LOCAL_REHEARSAL: 3,
  INTEGRATION_READY: 4,
  FULL_ACCEPTANCE: 5,
  EXTERNAL_TESTING_READY: 6,
  STABLE_ROLLOUT: 7
});

export const USAGE_UNITS = Object.freeze({
  TRANSLATION_MINUTE: "translation_minute",
  ANALYTICS_MINUTE: "analytics_minute",
  AI_CREDIT: "ai_credit"
});

export const SYNC_STATUS = Object.freeze({
  LOCAL_ONLY: "local_only",
  QUEUED: "queued",
  SYNCED: "synced",
  NEEDS_REVIEW: "needs_review"
});

export const GIFT_CONFIRMATION_STATUS = Object.freeze({
  RECEIVED: "received",
  PENDING: "pending",
  LIVE_CONFIRMED: "live_confirmed",
  NEEDS_REVIEW: "needs_review",
  DUPLICATE_IGNORED: "duplicate_ignored",
  OFFICIAL_CONFIRMED: "official_confirmed",
  OFFICIAL_ADJUSTED: "official_adjusted"
});

export const TEAM_IDS = Object.freeze({
  LEFT: "left",
  RIGHT: "right"
});

export function createId(prefix) {
  return `${prefix}_${randomUUID()}`;
}

export function nowIso() {
  return new Date().toISOString();
}

export function toEpochMs(value = Date.now()) {
  if (typeof value === "number") {
    return value;
  }
  const parsed = Date.parse(value);
  if (Number.isNaN(parsed)) {
    throw new Error(`Invalid time value: ${value}`);
  }
  return parsed;
}

export function assertRequiredFields(object, requiredFields, label = "object") {
  const missing = requiredFields.filter((field) => object[field] === undefined || object[field] === null);
  if (missing.length > 0) {
    throw new Error(`${label} missing required fields: ${missing.join(", ")}`);
  }
}
