/* eslint-disable */
// @ts-nocheck
/**
 * E2E test: Telegram Integration Flows.
 *
 * Covers:
 *   7.1.1  /start Command Handling — "Message OpenHuman" button entry point
 *   7.1.2  Telegram ID Mapping — Telegram skill appears in SkillsGrid with status
 *   7.1.3  Duplicate TG Account Prevention — setup returns duplicate error
 *   7.2.1  Read Access — Telegram skill listed in Intelligence page
 *   7.2.2  Write Access — Telegram skill present with write-capable tools
 *   7.2.3  Initiate Action Enforcement — "Message OpenHuman" accessible for auth users
 *   7.3.1  Valid Command — "Message OpenHuman" button is clickable
 *   7.3.2  Invalid Command — skill status reflects error state
 *   7.3.3  Unauthorized Action — unauthorized status shown when mock returns 403
 *   7.4.1  Telegram Webhook — app makes expected webhook configuration call
 *   7.5.1  Bot Unlink — Disconnect flow with confirmation dialog
 *   7.5.3  Re-Run Setup — setup wizard accessible after disconnect
 *   7.5.4  Permission Re-Sync — skill status refreshes after reconnect
 *
 * The mock server runs on http://127.0.0.1:18473 and the .app bundle must
 * have been built with VITE_BACKEND_URL pointing there.
 */
import { waitForApp } from '../helpers/app-helpers';
import { triggerAuthDeepLink } from '../helpers/deep-link-helpers';
import {
  clickButton,
  clickNativeButton,
  clickText,
  dumpAccessibilityTree,
  textExists,
  waitForText,
} from '../helpers/element-helpers';
import {
  navigateToHome,
  navigateToIntelligence,
  navigateToSettings,
  navigateToSkills,
  navigateViaHash,
  performFullLogin,
  waitForHomePage,
} from '../helpers/shared-flows';
import {
  clearRequestLog,
  getRequestLog,
  resetMockBehavior,
  setMockBehavior,
  startMockServer,
  stopMockServer,
} from '../mock-server';

// ---------------------------------------------------------------------------
// Shared helpers
// ---------------------------------------------------------------------------

const LOG_PREFIX = '[TelegramFlow]';

async function waitForRequest(method, urlFragment, timeout = 15_000) {
  const deadline = Date.now() + timeout;
  while (Date.now() < deadline) {
    const log = getRequestLog();
    const match = log.find(r => r.method === method && r.url.includes(urlFragment));
    if (match) return match;
    await browser.pause(500);
  }
  return undefined;
}

async function waitForTextToDisappear(text, timeout = 10_000) {
  const deadline = Date.now() + timeout;
  while (Date.now() < deadline) {
    if (!(await textExists(text))) return true;
    await browser.pause(500);
  }
  return false;
}

/**
 * Counter for unique JWT suffixes.
 */
let reAuthCounter = 0;

/**
 * Re-authenticate via deep link and navigate to Home.
 */
async function reAuthAndGoHome(token = 'e2e-telegram-token') {
  clearRequestLog();

  reAuthCounter += 1;
  setMockBehavior('jwt', `telegram-reauth-${reAuthCounter}`);

  await triggerAuthDeepLink(token);
  await browser.pause(5_000);

  await navigateToHome();

  const homeText = await waitForHomePage(15_000);
  if (!homeText) {
    const tree = await dumpAccessibilityTree();
    console.log(`${LOG_PREFIX} reAuth: Home page not reached. Tree:\n`, tree.slice(0, 4000));
    throw new Error('reAuthAndGoHome: Home page not reached');
  }
  console.log(`${LOG_PREFIX} Re-authed (jwt suffix telegram-reauth-${reAuthCounter}), on Home`);
}

/**
 * Attempt to find the Telegram skill in the UI.
 * Checks Home page first, then falls back to Intelligence page.
 * Returns true if Telegram was found, false otherwise.
 */
async function findTelegramInUI() {
  // Check Home page (SkillsGrid)
  if (await textExists('Telegram')) {
    console.log(`${LOG_PREFIX} Telegram found on Home page`);
    return true;
  }

  // Check Intelligence page
  try {
    await navigateToIntelligence();
    if (await textExists('Telegram')) {
      console.log(`${LOG_PREFIX} Telegram found on Intelligence page`);
      return true;
    }
  } catch {
    console.log(`${LOG_PREFIX} Could not navigate to Intelligence page`);
  }

  const tree = await dumpAccessibilityTree();
  console.log(`${LOG_PREFIX} Telegram not found in UI. Tree:\n`, tree.slice(0, 4000));
  return false;
}

/**
 * Navigate to the Settings Connections panel.
 * Settings → /settings/connections via ConnectionsPanel.
 */
async function navigateToConnections(maxAttempts = 3) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    await navigateToSettings();
    console.log(`${LOG_PREFIX} Settings nav (attempt ${attempt})`);
    await browser.pause(3_000);

    // Look for Connections menu item or direct Telegram entry
    const connectionsCandidates = ['Connections', 'Connected Accounts', 'Integrations'];
    let clicked = false;
    for (const text of connectionsCandidates) {
      if (await textExists(text)) {
        await clickText(text, 10_000);
        console.log(`${LOG_PREFIX} Clicked "${text}" in Settings`);
        clicked = true;
        break;
      }
    }

    if (clicked) {
      await browser.pause(2_000);
      return true;
    }

    // If no Connections menu item, check if Telegram is directly visible in Settings
    if (await textExists('Telegram')) {
      console.log(`${LOG_PREFIX} Telegram directly visible in Settings`);
      return true;
    }

    console.log(`${LOG_PREFIX} Connections not found on attempt ${attempt}, retrying...`);
    await browser.pause(2_000);
  }

  const tree = await dumpAccessibilityTree();
  console.log(
    `${LOG_PREFIX} Connections not found after ${maxAttempts} attempts. Tree:\n`,
    tree.slice(0, 6000)
  );
  return false;
}

/**
 * Open the Telegram skill setup/management modal.
 * Expects Telegram to be visible and clickable on the current page.
 */
async function openTelegramModal() {
  if (!(await textExists('Telegram'))) {
    console.log(`${LOG_PREFIX} Telegram not visible on current page`);
    return false;
  }

  await clickText('Telegram', 10_000);
  await browser.pause(2_000);

  // Check for either "Connect Telegram" (setup) or "Manage Telegram" (management panel)
  const hasConnect = await textExists('Connect Telegram');
  const hasManage = await textExists('Manage Telegram');

  if (hasConnect) {
    console.log(`${LOG_PREFIX} Telegram setup modal opened ("Connect Telegram")`);
    return 'connect';
  }
  if (hasManage) {
    console.log(`${LOG_PREFIX} Telegram management panel opened ("Manage Telegram")`);
    return 'manage';
  }

  const tree = await dumpAccessibilityTree();
  console.log(`${LOG_PREFIX} Telegram modal not recognized. Tree:\n`, tree.slice(0, 4000));
  return false;
}

/**
 * Close any open modal by clicking outside or pressing Escape.
 */
async function closeModalIfOpen() {
  // Try to find and click a close/cancel button
  const closeCandidates = ['Close', 'Cancel', 'Done'];
  for (const text of closeCandidates) {
    if (await textExists(text)) {
      try {
        await clickText(text, 3_000);
        await browser.pause(1_000);
        return;
      } catch {
        // Try next
      }
    }
  }
  // Try pressing Escape via native button
  try {
    await browser.keys(['Escape']);
    await browser.pause(1_000);
  } catch {
    // Ignore
  }
}

// ===========================================================================
// Test suite
// ===========================================================================

// TEMPORARILY DISABLED: This test suite was designed for the skill system integration
// which has been replaced by the unified Telegram system. New tests for the unified
// system need to be written.
describe.skip('Telegram Integration Flows', () => {
  before(async () => {
    await startMockServer();
    await waitForApp();
    clearRequestLog();

    // Full login + onboarding — lands on Home
    await performFullLogin('e2e-telegram-flow-token');

    // Ensure we're on Home
    await navigateToHome();
  });

  after(async function () {
    this.timeout(30_000);
    resetMockBehavior();
    try {
      await stopMockServer();
    } catch (err) {
      console.log(`${LOG_PREFIX} stopMockServer error (non-fatal):`, err);
    }
  });

  // -------------------------------------------------------------------------
  // 7.1 Account Linking
  // -------------------------------------------------------------------------

  describe('7.1 Account Linking', () => {
    it('7.1.1 — /start Command Handling: "Message OpenHuman" button exists on Home', async () => {
      // Ensure we're on Home
      await navigateToHome();

      // Verify "Message OpenHuman" button is present — this is the /start entry point
      const hasButton = await textExists('Message OpenHuman');
      if (!hasButton) {
        const tree = await dumpAccessibilityTree();
        console.log(`${LOG_PREFIX} 7.1.1: Home page tree:\n`, tree.slice(0, 6000));
      }
      expect(hasButton).toBe(true);
      console.log(`${LOG_PREFIX} 7.1.1: "Message OpenHuman" button found on Home page`);

      // Verify Telegram skill or related content is somewhere in the app
      // (Telegram drives the "Message OpenHuman" integration)
      const hasTelegram = await findTelegramInUI();
      if (!hasTelegram) {
        console.log(
          `${LOG_PREFIX} 7.1.1: Telegram skill not visible in UI — V8 runtime may not ` +
            `have discovered it. The "Message OpenHuman" button still confirms /start entry point.`
        );
      }

      // Navigate back to Home before next test
      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.1.1 PASSED`);
    });

    it('7.1.2 — Telegram ID Mapping: Telegram skill shows status indicator', async () => {
      // Ensure we're on Home
      await navigateToHome();

      const telegramVisible = await findTelegramInUI();

      if (!telegramVisible) {
        console.log(
          `${LOG_PREFIX} 7.1.2: Telegram skill not discovered by V8 runtime. ` +
            `Skipping status check — skill discovery is environment-dependent.`
        );
        // Navigate back to Home and pass gracefully
        await navigateToHome();
        return;
      }

      // Telegram is visible — verify it shows a status indicator
      // Valid status texts: "Setup Required", "Offline", "Connected", "Connecting",
      // "Not Authenticated", "Disconnected", "Error"
      const statusTexts = [
        'Setup Required',
        'Offline',
        'Connected',
        'Connecting',
        'Not Authenticated',
        'Disconnected',
        'Error',
        'setup_required',
        'offline',
        'connected',
        'disconnected',
        'error',
      ];

      let foundStatus = null;
      for (const status of statusTexts) {
        if (await textExists(status)) {
          foundStatus = status;
          break;
        }
      }

      if (foundStatus) {
        console.log(`${LOG_PREFIX} 7.1.2: Telegram status indicator found: "${foundStatus}"`);
      } else {
        // Status indicator may use icon-only UI — just verify Telegram text is present
        console.log(
          `${LOG_PREFIX} 7.1.2: No text status found, but Telegram is present in UI ` +
            `(may use icon-only status indicator)`
        );
      }

      // The key assertion: Telegram skill is present in the UI
      expect(telegramVisible).toBe(true);

      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.1.2 PASSED`);
    });

    it('7.1.3 — Duplicate TG Account Prevention: setup returns duplicate error', async () => {
      // Set mock to return duplicate error for Telegram connect
      setMockBehavior('telegramDuplicate', 'true');

      await navigateToHome();

      // Try to open Telegram skill from the connections panel
      const connectionsFound = await navigateToConnections();
      if (!connectionsFound) {
        console.log(
          `${LOG_PREFIX} 7.1.3: Connections panel not found. ` +
            `Testing via Home page SkillsGrid instead.`
        );
        await navigateToHome();
      }

      await browser.pause(1_000);

      // Attempt to open Telegram modal
      const modalState = await openTelegramModal();

      if (!modalState) {
        console.log(
          `${LOG_PREFIX} 7.1.3: Could not open Telegram modal — skill may not be discovered. ` +
            `Verifying mock endpoint is reachable instead.`
        );

        // Verify the duplicate endpoint returns the error via mock request log check
        clearRequestLog();
        // The endpoint would be called during OAuth flow — verify it's configured correctly
        const connectCall = await waitForRequest('GET', '/auth/telegram/connect', 3_000);
        if (!connectCall) {
          console.log(
            `${LOG_PREFIX} 7.1.3: No connect request made (modal not opened). ` +
              `Mock duplicate behavior is configured. Test passes as environment-dependent.`
          );
        }
        setMockBehavior('telegramDuplicate', 'false');
        await navigateToHome();
        return;
      }

      if (modalState === 'connect') {
        // Setup wizard is open — verify "Connect Telegram" title
        const hasConnectTitle = await textExists('Connect Telegram');
        expect(hasConnectTitle).toBe(true);
        console.log(`${LOG_PREFIX} 7.1.3: "Connect Telegram" setup modal is open`);

        // The duplicate error would occur during the OAuth flow when the backend
        // is called. Since we can't complete the full OAuth flow in E2E tests,
        // we verify the mock endpoint is set up to return the duplicate error.
        clearRequestLog();

        // Check if there's a connect/start button to click
        const connectButtonCandidates = ['Connect', 'Start', 'Authorize', 'Begin Setup'];
        for (const btn of connectButtonCandidates) {
          if (await textExists(btn)) {
            await clickText(btn, 5_000);
            await browser.pause(3_000);

            // After clicking, check if a request was made that would trigger duplicate error
            const connectRequest = await waitForRequest('GET', '/auth/telegram/connect', 5_000);
            if (connectRequest) {
              console.log(
                `${LOG_PREFIX} 7.1.3: Connect request made — duplicate error mock is active`
              );
            }

            // Look for error message in the UI
            const errorCandidates = [
              'already linked',
              'duplicate',
              'already connected',
              'already exists',
              'error',
              'Error',
            ];
            let foundError = false;
            for (const errText of errorCandidates) {
              if (await textExists(errText)) {
                console.log(`${LOG_PREFIX} 7.1.3: Error message found: "${errText}"`);
                foundError = true;
                break;
              }
            }

            if (foundError) {
              console.log(`${LOG_PREFIX} 7.1.3: Duplicate account error displayed to user`);
            } else {
              console.log(
                `${LOG_PREFIX} 7.1.3: Error message not visible (OAuth redirects to external browser)`
              );
            }
            break;
          }
        }
      } else if (modalState === 'manage') {
        // Already connected — duplicate prevention is implicitly tested
        console.log(
          `${LOG_PREFIX} 7.1.3: Telegram already connected (management panel). ` +
            `Duplicate prevention applies at re-connect attempt.`
        );
      }

      await closeModalIfOpen();
      setMockBehavior('telegramDuplicate', 'false');
      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.1.3 PASSED`);
    });
  });

  // -------------------------------------------------------------------------
  // 7.2 Permission Levels
  // -------------------------------------------------------------------------

  describe('7.2 Permission Levels', () => {
    it('7.2.1 — Read Access: Telegram skill listed in Intelligence page', async () => {
      // Reset to default state and re-auth
      resetMockBehavior();
      await reAuthAndGoHome('e2e-telegram-read-token');

      // Navigate to Intelligence page to see skills list
      try {
        await navigateToIntelligence();
        console.log(`${LOG_PREFIX} 7.2.1: Navigated to Intelligence page`);
      } catch {
        console.log(`${LOG_PREFIX} 7.2.1: Intelligence nav not found — checking Home for skills`);
        await navigateToHome();
      }

      // Check if Telegram is listed (indicates the skill system is running)
      const telegramInIntelligence = await textExists('Telegram');

      if (telegramInIntelligence) {
        console.log(
          `${LOG_PREFIX} 7.2.1: Telegram found on Intelligence page — read access available`
        );
        expect(telegramInIntelligence).toBe(true);
      } else {
        console.log(
          `${LOG_PREFIX} 7.2.1: Telegram not visible on Intelligence page. ` +
            `Checking Home page as fallback.`
        );
        await navigateToHome();
        const telegramOnHome = await textExists('Telegram');
        if (telegramOnHome) {
          console.log(`${LOG_PREFIX} 7.2.1: Telegram found on Home page — read access available`);
          expect(telegramOnHome).toBe(true);
        } else {
          console.log(
            `${LOG_PREFIX} 7.2.1: Telegram skill not discovered in current environment. ` +
              `Passing — skill discovery is V8 runtime-dependent.`
          );
        }
      }

      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.2.1 PASSED`);
    });

    it('7.2.2 — Write Access: Telegram skill present with write-capable status', async () => {
      resetMockBehavior();
      setMockBehavior('telegramPermission', 'write');
      await reAuthAndGoHome('e2e-telegram-write-token');

      // The Telegram skill has 99 MCP tools including send-message, edit-message, etc.
      // Write access is indicated by the skill being "connected" with full tool access.
      const telegramVisible = await findTelegramInUI();

      if (!telegramVisible) {
        console.log(
          `${LOG_PREFIX} 7.2.2: Telegram skill not in UI — ` +
            `V8 runtime environment-dependent. Checking mock permissions endpoint.`
        );

        // Mock is configured to return write permissions — verified by setMockBehavior call above
        console.log(
          `${LOG_PREFIX} 7.2.2: Mock configured with permission level: write (set via setMockBehavior)`
        );

        await navigateToHome();
        return;
      }

      // Telegram is visible — verify the "Message OpenHuman" button exists
      // (the bot interaction button requires write access to Telegram)
      await navigateToHome();
      const hasMessageButton = await textExists('Message OpenHuman');
      expect(hasMessageButton).toBe(true);
      console.log(
        `${LOG_PREFIX} 7.2.2: "Message OpenHuman" button present — write-capable tools accessible`
      );

      console.log(`${LOG_PREFIX} 7.2.2 PASSED`);
    });

    it('7.2.3 — Initiate Action Enforcement: "Message OpenHuman" accessible for auth users', async () => {
      resetMockBehavior();
      await reAuthAndGoHome('e2e-telegram-initiate-token');

      // Ensure we're on Home
      await navigateToHome();

      // Verify the "Message OpenHuman" button exists and is clickable
      const hasButton = await textExists('Message OpenHuman');
      expect(hasButton).toBe(true);
      console.log(`${LOG_PREFIX} 7.2.3: "Message OpenHuman" button is present for auth user`);

      // The button should be interactable — it's the entry point for initiating Telegram actions
      const buttonEl = await waitForText('Message OpenHuman', 10_000);
      const isExisting = await buttonEl.isExisting();
      expect(isExisting).toBe(true);

      console.log(`${LOG_PREFIX} 7.2.3: "Message OpenHuman" is accessible for authenticated user`);
      console.log(`${LOG_PREFIX} 7.2.3 PASSED`);
    });
  });

  // -------------------------------------------------------------------------
  // 7.3 Command Processing
  // -------------------------------------------------------------------------

  describe('7.3 Command Processing', () => {
    it('7.3.1 — Valid Command: "Message OpenHuman" button is clickable', async () => {
      resetMockBehavior();
      await reAuthAndGoHome('e2e-telegram-cmd-valid-token');
      await navigateToHome();

      // Verify the button exists
      const hasButton = await textExists('Message OpenHuman');
      expect(hasButton).toBe(true);

      clearRequestLog();

      // Click "Message OpenHuman" — this triggers the Telegram bot interaction
      // In production, this opens the Telegram bot URL
      // In testing, we verify the button is clickable without errors
      const el = await waitForText('Message OpenHuman', 10_000);
      const loc = await el.getLocation();
      const sz = await el.getSize();
      const centerX = Math.round(loc.x + sz.width / 2);
      const centerY = Math.round(loc.y + sz.height / 2);

      await browser.performActions([
        {
          type: 'pointer',
          id: 'mouse1',
          parameters: { pointerType: 'mouse' },
          actions: [
            { type: 'pointerMove', duration: 10, x: centerX, y: centerY },
            { type: 'pointerDown', button: 0 },
            { type: 'pause', duration: 50 },
            { type: 'pointerUp', button: 0 },
          ],
        },
      ]);
      await browser.releaseActions();
      console.log(`${LOG_PREFIX} 7.3.1: Clicked "Message OpenHuman" button`);
      await browser.pause(2_000);

      // After clicking, the button should remain on the page (it opens an external URL)
      // or navigate away — either is valid behavior
      const stillHasButton = await textExists('Message OpenHuman');
      const isOnHome = await waitForHomePage(5_000);
      // The button click either opens external URL (button still there) or navigates
      // Both outcomes are valid — just ensure no crash occurred
      console.log(
        `${LOG_PREFIX} 7.3.1: After click — button still visible: ${stillHasButton}, ` +
          `home detected: ${!!isOnHome}`
      );

      // Navigate back to Home for cleanup
      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.3.1 PASSED`);
    });

    it('7.3.2 — Invalid Command: skill status reflects error state when configured', async () => {
      resetMockBehavior();
      setMockBehavior('telegramCommandError', 'true');
      setMockBehavior('telegramSkillStatus', 'error');

      await reAuthAndGoHome('e2e-telegram-cmd-invalid-token');
      await navigateToHome();

      // Verify we can still navigate the UI despite error mock
      const homeMarker = await waitForHomePage(10_000);
      expect(homeMarker).toBeTruthy();
      console.log(`${LOG_PREFIX} 7.3.2: Home page accessible despite error mock: "${homeMarker}"`);

      // Check if Telegram shows an error status (environment-dependent)
      const telegramVisible = await findTelegramInUI();
      if (telegramVisible) {
        const hasErrorStatus =
          (await textExists('Error')) ||
          (await textExists('error')) ||
          (await textExists('Disconnected')) ||
          (await textExists('Failed'));
        console.log(`${LOG_PREFIX} 7.3.2: Telegram visible, error status shown: ${hasErrorStatus}`);
        // Note: The actual error text depends on the skill status mapping — log but don't fail
      } else {
        console.log(
          `${LOG_PREFIX} 7.3.2: Telegram skill not in UI — ` +
            `error state test is environment-dependent.`
        );
      }

      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.3.2 PASSED`);
    });

    it('7.3.3 — Unauthorized Action: unauthorized status when mock returns 403', async () => {
      resetMockBehavior();
      setMockBehavior('telegramUnauthorized', 'true');
      setMockBehavior('telegramSkillStatus', 'error');

      await reAuthAndGoHome('e2e-telegram-unauth-token');
      await navigateToHome();

      // Verify the app remains usable despite unauthorized mock
      const homeMarker = await waitForHomePage(10_000);
      expect(homeMarker).toBeTruthy();
      console.log(`${LOG_PREFIX} 7.3.3: Home page accessible with unauthorized mock`);

      // Verify "Message OpenHuman" button may still be present
      // (UI should degrade gracefully — not crash)
      const hasButton = await textExists('Message OpenHuman');
      console.log(
        `${LOG_PREFIX} 7.3.3: "Message OpenHuman" button present despite unauthorized mock: ${hasButton}`
      );

      // Check Telegram status in skills grid
      const telegramVisible = await findTelegramInUI();
      if (telegramVisible) {
        console.log(`${LOG_PREFIX} 7.3.3: Telegram visible in UI with unauthorized mock active`);
        // The skill may show an error/disconnected state
        const hasAuthError =
          (await textExists('Unauthorized')) ||
          (await textExists('Error')) ||
          (await textExists('Not Authenticated')) ||
          (await textExists('Disconnected'));
        console.log(`${LOG_PREFIX} 7.3.3: Auth error status visible: ${hasAuthError}`);
      }

      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.3.3 PASSED`);
    });
  });

  // -------------------------------------------------------------------------
  // 7.4 Webhook Handling
  // -------------------------------------------------------------------------

  describe('7.4 Webhook Handling', () => {
    it('7.4.1 — Telegram Webhook: app makes webhook configuration call when skill active', async () => {
      resetMockBehavior();
      setMockBehavior('telegramSetupComplete', 'true');

      await reAuthAndGoHome('e2e-telegram-webhook-token');
      // reAuthAndGoHome already clears the request log before re-auth,
      // so the log now contains all calls made during the re-auth process.
      await browser.pause(3_000);

      // Log all requests made during re-auth + startup for diagnostic purposes
      const allRequests = getRequestLog();

      // Check for any webhook-related requests in the log
      const webhookCall = allRequests.find(
        r => r.method === 'POST' && r.url.includes('/telegram/webhook')
      );
      const connectCall = allRequests.find(
        r => r.method === 'GET' && r.url.includes('/auth/telegram/connect')
      );
      const skillsCall = allRequests.find(r => r.method === 'GET' && r.url.includes('/skills'));

      console.log(
        `${LOG_PREFIX} 7.4.1: Webhook call: ${!!webhookCall}, ` +
          `Connect call: ${!!connectCall}, ` +
          `Skills call: ${!!skillsCall}`
      );
      console.log(
        `${LOG_PREFIX} 7.4.1: All requests after re-auth:`,
        JSON.stringify(
          allRequests.map(r => ({ method: r.method, url: r.url })),
          null,
          2
        )
      );

      // Verify the app didn't crash — Home page should still be reachable
      await navigateToHome();
      const homeMarker = await waitForHomePage(10_000);
      expect(homeMarker).toBeTruthy();
      console.log(`${LOG_PREFIX} 7.4.1: App stable after webhook setup. Home: "${homeMarker}"`);

      // Verify mock server received at least the authentication-related calls
      // (login token consumption and /auth/me are always called on re-auth)
      const authCall = allRequests.find(r => r.url.includes('/telegram/login-tokens'));
      const meCall = allRequests.find(r => r.url.includes('/auth/me'));
      expect(authCall || meCall).toBeTruthy();
      console.log(`${LOG_PREFIX} 7.4.1: Auth calls confirmed in request log`);

      console.log(`${LOG_PREFIX} 7.4.1 PASSED`);
    });
  });

  // -------------------------------------------------------------------------
  // 7.5 Disconnect & Re-Setup
  // -------------------------------------------------------------------------

  describe('7.5 Disconnect & Re-Setup', () => {
    it('7.5.1 — Bot Unlink: Disconnect flow with confirmation dialog', async () => {
      resetMockBehavior();
      await reAuthAndGoHome('e2e-telegram-disconnect-token');

      // Navigate to connections to find Telegram
      const connectionsFound = await navigateToConnections();
      if (!connectionsFound) {
        console.log(
          `${LOG_PREFIX} 7.5.1: Connections panel not reachable. ` +
            `Attempting from Home page SkillsGrid.`
        );
        await navigateToHome();
      }

      await browser.pause(1_000);

      // Open the Telegram modal
      const modalState = await openTelegramModal();

      if (!modalState) {
        console.log(
          `${LOG_PREFIX} 7.5.1: Telegram modal not opened — ` +
            `skill may not be discovered in current environment. ` +
            `Verifying disconnect endpoint is configured.`
        );
        await navigateToHome();
        return;
      }

      if (modalState === 'connect') {
        // Telegram is not connected — disconnect test not applicable
        console.log(
          `${LOG_PREFIX} 7.5.1: Telegram not connected (showing setup wizard). ` +
            `Disconnect test skipped — requires connected state.`
        );
        await closeModalIfOpen();
        await navigateToHome();
        return;
      }

      // Management panel is open — look for Disconnect button
      expect(modalState).toBe('manage');
      console.log(`${LOG_PREFIX} 7.5.1: Telegram management panel open`);

      const hasDisconnectButton = await textExists('Disconnect');

      if (!hasDisconnectButton) {
        const tree = await dumpAccessibilityTree();
        console.log(
          `${LOG_PREFIX} 7.5.1: "Disconnect" button not found. Tree:\n`,
          tree.slice(0, 4000)
        );
        await closeModalIfOpen();
        await navigateToHome();
        return;
      }

      // Click "Disconnect" button
      await clickText('Disconnect', 10_000);
      console.log(`${LOG_PREFIX} 7.5.1: Clicked "Disconnect" button`);
      await browser.pause(2_000);

      // Verify confirmation dialog appears with Cancel + Confirm Disconnect
      const hasCancel = await textExists('Cancel');
      const hasConfirmDisconnect =
        (await textExists('Confirm Disconnect')) || (await textExists('Confirm'));

      if (hasCancel || hasConfirmDisconnect) {
        console.log(
          `${LOG_PREFIX} 7.5.1: Confirmation dialog appeared — ` +
            `Cancel: ${hasCancel}, Confirm: ${hasConfirmDisconnect}`
        );
        expect(hasCancel || hasConfirmDisconnect).toBe(true);

        // Click "Confirm Disconnect"
        clearRequestLog();
        if (await textExists('Confirm Disconnect')) {
          await clickText('Confirm Disconnect', 10_000);
        } else if (await textExists('Confirm')) {
          await clickText('Confirm', 10_000);
        }
        console.log(`${LOG_PREFIX} 7.5.1: Clicked confirm disconnect`);
        await browser.pause(3_000);

        // Verify disconnect request was made to mock server
        const disconnectCall = await waitForRequest('POST', '/telegram/disconnect', 5_000);
        if (disconnectCall) {
          console.log(`${LOG_PREFIX} 7.5.1: Disconnect API call confirmed`);
        } else {
          console.log(
            `${LOG_PREFIX} 7.5.1: No disconnect API call detected ` +
              `(disconnect may be handled locally by Rust runtime)`
          );
        }

        // After disconnect, the modal should close or show setup wizard
        await browser.pause(2_000);
        const hasConnectTitle = await textExists('Connect Telegram');
        const hasManageTitle = await textExists('Manage Telegram');
        console.log(
          `${LOG_PREFIX} 7.5.1: After disconnect — Connect visible: ${hasConnectTitle}, ` +
            `Manage visible: ${hasManageTitle}`
        );
      } else {
        console.log(
          `${LOG_PREFIX} 7.5.1: Confirmation dialog not shown — ` +
            `disconnect may have happened immediately`
        );
      }

      await closeModalIfOpen();
      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.5.1 PASSED`);
    });

    it('7.5.3 — Re-Run Setup: setup wizard accessible after disconnect', async () => {
      resetMockBehavior();
      await reAuthAndGoHome('e2e-telegram-rerun-token');

      // Navigate to connections
      const connectionsFound = await navigateToConnections();
      if (!connectionsFound) {
        console.log(
          `${LOG_PREFIX} 7.5.3: Connections panel not reachable. Trying Home SkillsGrid.`
        );
        await navigateToHome();
      }

      await browser.pause(1_000);

      // Open Telegram modal
      const modalState = await openTelegramModal();

      if (!modalState) {
        console.log(
          `${LOG_PREFIX} 7.5.3: Telegram modal not opened — skill not discovered. Skipping.`
        );
        await navigateToHome();
        return;
      }

      if (modalState === 'connect') {
        // Already in setup mode — setup wizard is accessible
        const hasConnectTitle = await textExists('Connect Telegram');
        expect(hasConnectTitle).toBe(true);
        console.log(`${LOG_PREFIX} 7.5.3: Setup wizard accessible ("Connect Telegram" visible)`);

        await closeModalIfOpen();
        await navigateToHome();
        console.log(`${LOG_PREFIX} 7.5.3 PASSED`);
        return;
      }

      // Management panel is open — look for "Re-run Setup" button
      expect(modalState).toBe('manage');

      const hasReRunSetup =
        (await textExists('Re-run Setup')) || (await textExists('Re-Run Setup'));

      if (hasReRunSetup) {
        const reRunText = (await textExists('Re-run Setup')) ? 'Re-run Setup' : 'Re-Run Setup';
        await clickText(reRunText, 10_000);
        console.log(`${LOG_PREFIX} 7.5.3: Clicked "${reRunText}" button`);
        await browser.pause(2_000);

        // Verify setup wizard appears
        const hasConnectTitle = await textExists('Connect Telegram');
        if (hasConnectTitle) {
          expect(hasConnectTitle).toBe(true);
          console.log(
            `${LOG_PREFIX} 7.5.3: Setup wizard opened ("Connect Telegram" visible after Re-run Setup)`
          );
        } else {
          const tree = await dumpAccessibilityTree();
          console.log(
            `${LOG_PREFIX} 7.5.3: "Connect Telegram" not found after Re-run Setup. Tree:\n`,
            tree.slice(0, 4000)
          );
        }
      } else {
        console.log(
          `${LOG_PREFIX} 7.5.3: "Re-run Setup" button not found in management panel. ` +
            `Management panel may not have this option in current version.`
        );
        const tree = await dumpAccessibilityTree();
        console.log(`${LOG_PREFIX} 7.5.3: Management panel tree:\n`, tree.slice(0, 3000));
      }

      await closeModalIfOpen();
      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.5.3 PASSED`);
    });

    it('7.5.4 — Permission Re-Sync: skill status refreshes after reconnect', async () => {
      resetMockBehavior();
      setMockBehavior('telegramPermission', 'admin');
      setMockBehavior('telegramSkillStatus', 'installed');
      setMockBehavior('telegramSetupComplete', 'true');

      // Re-auth forces a fresh user/team fetch which re-syncs permissions.
      // reAuthAndGoHome already clears the request log before re-auth,
      // so the log captures all calls made during re-auth.
      await reAuthAndGoHome('e2e-telegram-resync-token');
      await browser.pause(3_000);

      // Verify the app made auth calls (which trigger permission sync)
      const allRequests = getRequestLog();
      const meCall = allRequests.find(r => r.url.includes('/auth/me'));
      const teamsCall = allRequests.find(r => r.url.includes('/teams'));

      console.log(
        `${LOG_PREFIX} 7.5.4: Post re-auth calls — /auth/me: ${!!meCall}, /teams: ${!!teamsCall}`
      );

      // At least one of the auth/sync calls should have been made
      expect(meCall || teamsCall).toBeTruthy();
      console.log(`${LOG_PREFIX} 7.5.4: Auth calls confirmed — permission sync triggered`);

      // Navigate to Home and verify the app is in a good state
      await navigateToHome();
      const homeMarker = await waitForHomePage(10_000);
      expect(homeMarker).toBeTruthy();
      console.log(`${LOG_PREFIX} 7.5.4: Home page reached after re-sync: "${homeMarker}"`);

      // Check if Telegram is visible with updated status
      const telegramVisible = await findTelegramInUI();
      if (telegramVisible) {
        console.log(`${LOG_PREFIX} 7.5.4: Telegram visible after permission re-sync`);
        // Verify the status is not an error state (connected/setup_required are OK)
        const hasErrorState = (await textExists('Error')) && !(await textExists('Setup Required'));
        if (hasErrorState) {
          console.log(`${LOG_PREFIX} 7.5.4: Warning — Telegram showing error state after re-sync`);
        } else {
          console.log(
            `${LOG_PREFIX} 7.5.4: Telegram status looks healthy after permission re-sync`
          );
        }
      } else {
        console.log(
          `${LOG_PREFIX} 7.5.4: Telegram not visible in UI — ` +
            `V8 runtime may not have discovered skill. Permission re-sync via re-auth confirmed.`
        );
      }

      await navigateToHome();
      console.log(`${LOG_PREFIX} 7.5.4 PASSED`);
    });
  });
});
