export const PLUGIN_REQUIREMENT_STATUSES = [
  'required',
  'optional',
  'recommended',
  'blocked',
  'incompatible'
] as const;

export type PluginRequirementStatus = typeof PLUGIN_REQUIREMENT_STATUSES[number];

export const PLUGIN_EVENT_DIRECTIONS = [
  'clientToServer',
  'serverRelay',
  'p2pHint'
] as const;

export type PluginEventDirection = typeof PLUGIN_EVENT_DIRECTIONS[number];

export const PLUGIN_EVENT_SCOPES = [
  'server',
  'channel',
  'user',
  'plugin'
] as const;

export type PluginEventScope = typeof PLUGIN_EVENT_SCOPES[number];
export type TojuPluginInstallScope = 'client' | 'server';

export const PLUGIN_CAPABILITIES = [
  'profile.read',
  'profile.write',
  'users.read',
  'users.manage',
  'roles.read',
  'roles.manage',
  'messages.read',
  'messages.send',
  'messages.editOwn',
  'messages.deleteOwn',
  'messages.moderate',
  'messages.sync',
  'channels.read',
  'channels.manage',
  'server.read',
  'server.manage',
  'p2p.data',
  'p2p.media',
  'media.playAudio',
  'media.addAudioStream',
  'media.addVideoStream',
  'audio.volume',
  'audio.effects',
  'ui.settings',
  'ui.pages',
  'ui.sidePanel',
  'ui.channelsSection',
  'ui.embeds',
  'ui.dom',
  'storage.local',
  'storage.serverData.read',
  'storage.serverData.write',
  'events.server.publish',
  'events.server.subscribe',
  'events.p2p.publish',
  'events.p2p.subscribe'
] as const;

export type PluginCapabilityId = typeof PLUGIN_CAPABILITIES[number];

export interface PluginRequirementSummary {
  installUrl?: string;
  manifest?: TojuPluginManifest;
  pluginId: string;
  reason?: string;
  sourceUrl?: string;
  status: PluginRequirementStatus;
  updatedAt: number;
  versionRange?: string;
}

export interface PluginEventDefinitionSummary {
  direction: PluginEventDirection;
  eventName: string;
  maxPayloadBytes: number;
  pluginId: string;
  scope: PluginEventScope;
  schemaJson?: string;
  updatedAt: number;
}

export interface PluginRequirementsSnapshot {
  eventDefinitions: PluginEventDefinitionSummary[];
  requirements: PluginRequirementSummary[];
  serverId: string;
  updatedAt: number;
}

export interface PluginEventEnvelope<TPayload = unknown> {
  emittedAt?: number;
  eventId?: string;
  eventName: string;
  payload: TPayload;
  pluginId: string;
  serverId: string;
  sourcePluginUserId?: string;
  sourceUserId?: string;
  type: 'plugin_event';
}

export interface PluginRequirementsMessage {
  snapshot: PluginRequirementsSnapshot;
  serverId: string;
  type: 'plugin_requirements';
}

export interface PluginRequirementsChangedMessage {
  snapshot: PluginRequirementsSnapshot;
  serverId: string;
  type: 'plugin_requirements_changed';
}

export interface PluginDataChangedMessage {
  key: string;
  ownerId?: string;
  pluginId: string;
  scope: string;
  serverId: string;
  type: 'plugin_data_changed';
  updatedAt: number;
}

export interface PluginErrorMessage {
  code: string;
  eventId?: string;
  eventName?: string;
  message: string;
  pluginId?: string;
  serverId?: string;
  type: 'plugin_error';
}

export interface TojuPluginManifest {
  apiVersion: string;
  authors?: {
    email?: string;
    name: string;
    url?: string;
  }[];
  bugs?: string;
  bundle?: {
    entrypoint?: string;
    url: string;
  };
  capabilities?: PluginCapabilityId[];
  changelog?: string;
  compatibility: {
    maximumTojuVersion?: string;
    minimumTojuVersion: string;
    verifiedTojuVersion?: string;
  };
  data?: {
    key: string;
    schema?: string;
    scope: string;
    storage: 'local' | 'serverData';
  }[];
  description: string;
  entrypoint?: string;
  events?: {
    direction: PluginEventDirection;
    eventName: string;
    maxPayloadBytes?: number;
    schema?: string;
    scope: PluginEventScope;
  }[];
  homepage?: string;
  id: string;
  kind: 'client' | 'library';
  license?: string;
  load?: {
    priority?: 'bootstrap' | 'high' | 'default' | 'low';
  };
  pluginUser?: {
    avatar?: string;
    displayName: string;
    label?: string;
  };
  readme?: string;
  relationships?: {
    after?: string[];
    before?: string[];
    conflicts?: string[];
    optional?: { id: string; versionRange?: string }[];
    requires?: { id: string; versionRange?: string }[];
  };
  schemaVersion: 1;
  scope?: TojuPluginInstallScope;
  settings?: Record<string, unknown>;
  title: string;
  ui?: Record<string, unknown>;
  version: string;
}
