const tinyWave = 'data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEAESsAACJWAAACABAAZGF0YQAAAAA=';
const originalMessage = 'Plugin API original message';
const editedMessage = 'Plugin API edited message';
const deletedMessage = 'Plugin API deleted message';
const embedMessage = 'toju:embed:e2e.coverage:{"title":"Plugin API custom embed","body":"Rendered by plugin API"}';
const soundboardPlayedMessage = 'E2E soundboard played Airhorn to voice channel';

export async function activate(context) {
  const api = context.api;
  const currentUser = api.profile.getCurrent();
  const shouldMutateChat = !currentUser?.displayName?.includes('Bob');
  const pluginUserId = api.server.registerPluginUser({
    displayName: 'E2E Plugin Bot',
    id: 'e2e-plugin-bot'
  });

  context.subscriptions.push(api.ui.registerSettingsPage('coverage', {
    label: 'E2E Coverage',
    render: () => 'E2E settings contribution'
  }));
  context.subscriptions.push(api.ui.registerAppPage('coverage', {
    label: 'E2E Page',
    path: '/plugins/e2e/coverage',
    render: () => 'E2E page contribution'
  }));
  context.subscriptions.push(api.ui.registerSidePanel('coverage', {
    label: 'E2E Soundboard',
    render: () => 'E2E soundboard ready'
  }));
  context.subscriptions.push(api.ui.registerChannelSection('coverage', {
    label: 'E2E Soundboard',
    type: 'custom'
  }));
  context.subscriptions.push(api.ui.registerComposerAction('coverage', {
    icon: 'SFX',
    label: 'E2E Soundboard',
    run: () => openSoundboardModal(api, pluginUserId)
  }));
  context.subscriptions.push(api.ui.registerProfileAction('coverage', {
    label: 'E2E Profile',
    run: () => api.logger.info('profile action ran')
  }));
  context.subscriptions.push(api.ui.registerToolbarAction('coverage', {
    label: 'E2E Toolbar',
    run: () => api.logger.info('toolbar action ran')
  }));
  context.subscriptions.push(api.ui.registerEmbedRenderer('coverage', {
    embedType: 'e2e.coverage',
    render: (payload) => `E2E custom embed: ${payload?.title ?? 'missing title'}`
  }));

  const injectedBadge = document.createElement('div');

  injectedBadge.dataset.testid = 'e2e-plugin-owned-dom';
  injectedBadge.textContent = 'E2E plugin-owned DOM injected into chat';
  injectedBadge.style.position = 'absolute';
  injectedBadge.style.left = '1rem';
  injectedBadge.style.bottom = '5.5rem';
  injectedBadge.style.zIndex = '20';
  injectedBadge.style.border = '1px solid hsl(var(--border))';
  injectedBadge.style.borderRadius = '0.5rem';
  injectedBadge.style.padding = '0.35rem 0.5rem';
  injectedBadge.style.background = 'hsl(var(--card))';
  injectedBadge.style.color = 'hsl(var(--foreground))';
  injectedBadge.style.fontSize = '0.75rem';
  context.subscriptions.push(api.ui.mountElement('chat-owned-badge', {
    element: injectedBadge,
    target: 'app-chat-messages'
  }));

  context.subscriptions.push(api.events.subscribeServer({ eventName: 'e2e:server', handler: () => {} }));
  context.subscriptions.push(api.events.subscribeP2p({ eventName: 'e2e:p2p', handler: () => {} }));

  api.storage.set('coverage', { ok: true });
  api.storage.get('coverage');
  await api.clientData.write('coverage', { ok: true });
  await api.clientData.read('coverage');
  await api.serverData.write('coverage', { ok: true });
  await api.serverData.read('coverage');

  api.profile.update({
    description: 'Updated by E2E plugin',
    displayName: `${currentUser?.displayName || 'E2E Plugin User'} Plugin Renamed`
  });
  api.profile.updateAvatar({
    avatarHash: 'e2e-plugin-avatar',
    avatarMime: 'image/svg+xml',
    avatarUrl: '/plugins/e2e-all-api/icon.svg'
  });

  api.users.getCurrent();
  api.users.list();
  api.users.readMembers();
  api.users.setRole(pluginUserId, 'member');
  api.users.kick(pluginUserId);
  api.users.ban(pluginUserId, 'E2E coverage');

  api.roles.list();
  api.roles.setAssignments([]);

  api.channels.list();
  api.channels.addAudioChannel({ id: 'e2e-audio', name: 'E2E Audio', position: 90 });
  api.channels.addVideoChannel({ id: 'e2e-video', name: 'E2E Video', position: 91 });
  api.channels.select('general');
  api.channels.rename('e2e-audio', 'E2E Audio Renamed');

  api.server.getCurrent();
  api.server.updatePermissions({ allowVoice: true });
  api.server.updateSettings({
    name: api.server.getCurrent()?.name,
    topic: 'Updated by E2E plugin'
  });

  api.messages.readCurrent();
  if (shouldMutateChat) {
    const sentMessage = api.messages.send(originalMessage);

    api.messages.edit(sentMessage.id, editedMessage);

    const removableMessage = api.messages.send(deletedMessage);

    api.messages.delete(removableMessage.id);
    api.messages.send(embedMessage);
  }

  api.messages.sendAsPluginUser({
    content: 'Plugin bot message from all-api fixture',
    pluginUserId
  });
  api.messages.moderateDelete('missing-message-id');
  api.messages.sync(api.messages.readCurrent());
  context.subscriptions.push(api.messageBus.subscribe({
    handler: () => {},
    latestMessageLimit: 5,
    replayLatest: true,
    topic: 'e2e:latest'
  }));
  api.messageBus.publish({
    includeLatestMessages: true,
    includeSelf: true,
    latestMessageLimit: 5,
    payload: { ok: true },
    topic: 'e2e:latest'
  });
  api.messageBus.sendLatestMessages({
    limit: 5,
    topic: 'e2e:latest'
  });

  api.p2p.connectedPeers();
  api.p2p.broadcastData('e2e:p2p', { ok: true });
  api.p2p.sendData('missing-peer', 'e2e:p2p', { ok: true });
  api.events.publishServer('e2e:server', { ok: true });
  api.events.publishP2p('e2e:p2p', { ok: true });

  api.media.setOutputVolume(0.8);
  api.media.setInputVolume(0.8);
  await api.media.playAudioClip({ url: tinyWave, volume: 0 }).catch((error) => api.logger.warn('audio clip rejected', String(error)));
  await api.media.addCustomVideoStream({ label: 'e2e-video', stream: new MediaStream() });

  const audioContext = new AudioContext();
  const destination = audioContext.createMediaStreamDestination();

  await api.media.addCustomAudioStream({ label: 'e2e-audio', stream: destination.stream }).catch((error) => api.logger.warn('audio stream rejected', String(error)));
  await audioContext.close();

  api.storage.remove('coverage');
  await api.clientData.remove('coverage');
  await api.serverData.remove('coverage');
  api.logger.info('all-api plugin completed');
}

export function ready(context) {
  context.api.logger.info('all-api plugin ready');
}

export function deactivate(context) {
  context.api.logger.info('all-api plugin deactivated');
}

function openSoundboardModal(api, pluginUserId) {
  document.querySelector('[data-testid="e2e-soundboard-modal"]')?.remove();

  const overlay = document.createElement('div');

  overlay.dataset.testid = 'e2e-soundboard-modal';
  overlay.setAttribute('role', 'dialog');
  overlay.setAttribute('aria-modal', 'true');
  overlay.setAttribute('aria-label', 'E2E Soundboard');
  overlay.style.position = 'fixed';
  overlay.style.inset = '0';
  overlay.style.zIndex = '9999';
  overlay.style.display = 'grid';
  overlay.style.placeItems = 'center';
  overlay.style.background = 'rgb(0 0 0 / 0.45)';

  const panel = document.createElement('section');

  panel.style.width = 'min(24rem, calc(100vw - 2rem))';
  panel.style.border = '1px solid hsl(var(--border))';
  panel.style.borderRadius = '0.5rem';
  panel.style.padding = '1rem';
  panel.style.color = 'hsl(var(--foreground))';
  panel.style.background = 'hsl(var(--card))';
  panel.style.boxShadow = '0 1.25rem 3rem rgb(0 0 0 / 0.25)';

  const title = document.createElement('h2');

  title.textContent = 'E2E Soundboard';
  title.style.margin = '0 0 0.75rem';
  title.style.fontSize = '1rem';

  const status = document.createElement('p');

  status.dataset.testid = 'e2e-soundboard-status';
  status.textContent = 'Ready to play to voice channel';
  status.style.margin = '0 0 1rem';
  status.style.color = 'hsl(var(--muted-foreground))';
  status.style.fontSize = '0.875rem';

  const actions = document.createElement('div');

  actions.style.display = 'flex';
  actions.style.gap = '0.5rem';
  actions.style.justifyContent = 'flex-end';

  const closeButton = document.createElement('button');

  closeButton.type = 'button';
  closeButton.textContent = 'Close';
  closeButton.style.border = '1px solid hsl(var(--border))';
  closeButton.style.borderRadius = '0.375rem';
  closeButton.style.padding = '0.5rem 0.75rem';
  closeButton.style.background = 'transparent';
  closeButton.style.color = 'hsl(var(--foreground))';
  closeButton.addEventListener('click', () => overlay.remove());

  const playButton = document.createElement('button');

  playButton.type = 'button';
  playButton.textContent = 'Play airhorn to voice';
  playButton.style.border = '0';
  playButton.style.borderRadius = '0.375rem';
  playButton.style.padding = '0.5rem 0.75rem';
  playButton.style.background = 'hsl(var(--primary))';
  playButton.style.color = 'hsl(var(--primary-foreground))';
  playButton.addEventListener('click', async () => {
    playButton.disabled = true;
    status.textContent = 'Playing Airhorn to voice channel';

    try {
      await playSoundboardClipToVoice(api);
      api.p2p.broadcastData('e2e:p2p', { sound: 'airhorn', source: 'soundboard' });
      api.events.publishP2p('e2e:p2p', { sound: 'airhorn', source: 'soundboard' });
      api.messages.sendAsPluginUser({ content: soundboardPlayedMessage, pluginUserId });
      api.logger.info('soundboard played to voice channel');
      status.textContent = soundboardPlayedMessage;
    } catch (error) {
      status.textContent = error instanceof Error ? error.message : 'Soundboard playback failed';
      api.logger.warn('soundboard playback failed', String(error));
    } finally {
      playButton.disabled = false;
    }
  });

  actions.append(closeButton, playButton);
  panel.append(title, status, actions);
  overlay.append(panel);
  api.ui.mountElement('soundboard-modal', {
    element: overlay,
    target: 'body'
  });
}

async function playSoundboardClipToVoice(api) {
  const audioContext = new AudioContext();
  const oscillator = audioContext.createOscillator();
  const gain = audioContext.createGain();
  const destination = audioContext.createMediaStreamDestination();

  oscillator.type = 'square';
  oscillator.frequency.value = 330;
  gain.gain.value = 0.08;
  oscillator.connect(gain);
  gain.connect(destination);
  oscillator.start();

  await api.media.addCustomAudioStream({ label: 'e2e-soundboard-airhorn', stream: destination.stream });
  await api.media.playAudioClip({ url: tinyWave, volume: 0 }).catch((error) => api.logger.warn('soundboard preview rejected', String(error)));
  await new Promise((resolve) => setTimeout(resolve, 150));
  oscillator.stop();
  await audioContext.close();
}
