import { browser, expect } from '@wdio/globals';

// Phase F — Search Overlay, Context Tab, Anchors, SSH Tab Tests (F1–F3)
// Tests FTS5 search overlay interactions, context tab with anchors, and SSH tab.

// ─── Helpers ──────────────────────────────────────────────────────────

/** Get first project box ID. */
async function getFirstProjectId(): Promise<string | null> {
  return browser.execute(() => {
    const box = document.querySelector('[data-testid="project-box"]');
    return box?.getAttribute('data-project-id') ?? null;
  });
}

/** Switch to a tab in the first project box by tab text label. */
async function switchProjectTabByLabel(projectId: string, label: string): Promise<void> {
  await browser.execute((id, lbl) => {
    const box = document.querySelector(`[data-project-id="${id}"]`);
    const tabs = box?.querySelectorAll('[data-testid="project-tabs"] .ptab');
    if (!tabs) return;
    for (const tab of tabs) {
      if (tab.textContent?.trim() === lbl) {
        (tab as HTMLElement).click();
        return;
      }
    }
  }, projectId, label);
  await browser.pause(400);
}

/** Close any open overlays/panels to reset state. */
async function resetOverlays(): Promise<void> {
  // Close search overlay if open
  const overlay = await browser.$('.search-overlay');
  if (await overlay.isExisting()) {
    await browser.keys('Escape');
    await browser.pause(300);
  }
  // Close settings panel if open
  const settingsPanel = await browser.$('.settings-panel');
  if (await settingsPanel.isExisting()) {
    const closeBtn = await browser.$('.settings-close, .panel-close');
    if (await closeBtn.isExisting()) await closeBtn.click();
    await browser.pause(300);
  }
}

// ─── Scenario F1: Search Overlay Advanced ─────────────────────────────

describe('Scenario F1 — Search Overlay Advanced', () => {
  before(async () => {
    await resetOverlays();
  });

  afterEach(async () => {
    // Ensure overlay is closed after each test
    try {
      const isVisible = await browser.execute(() => {
        const el = document.querySelector('.search-overlay');
        return el !== null && window.getComputedStyle(el).display !== 'none';
      });
      if (isVisible) {
        await browser.keys('Escape');
        await browser.pause(300);
      }
    } catch {
      // Ignore if overlay doesn't exist
    }
  });

  it('should open search overlay with Ctrl+Shift+F', async () => {
    await browser.execute(() => document.body.focus());
    await browser.pause(100);
    await browser.keys(['Control', 'Shift', 'f']);
    await browser.pause(500);

    const overlay = await browser.$('.search-overlay');
    await expect(overlay).toBeDisplayed();
  });

  it('should show search input focused and ready', async () => {
    await browser.execute(() => document.body.focus());
    await browser.pause(100);
    await browser.keys(['Control', 'Shift', 'f']);
    await browser.pause(500);

    const isFocused = await browser.execute(() => {
      const input = document.querySelector('.search-input');
      return input === document.activeElement;
    });
    expect(isFocused).toBe(true);
  });

  it('should show empty state message when no results', async () => {
    await browser.execute(() => document.body.focus());
    await browser.pause(100);
    await browser.keys(['Control', 'Shift', 'f']);
    await browser.pause(500);

    const input = await browser.$('.search-input');
    await input.setValue('xyznonexistent99999');
    await browser.pause(500);

    const emptyMsg = await browser.execute(() => {
      const el = document.querySelector('.search-empty');
      return el?.textContent ?? '';
    });
    expect(emptyMsg.toLowerCase()).toContain('no results');
  });

  it('should close search overlay on Escape', async () => {
    await browser.execute(() => document.body.focus());
    await browser.pause(100);
    await browser.keys(['Control', 'Shift', 'f']);
    await browser.pause(500);

    // Verify it opened
    const overlayBefore = await browser.$('.search-overlay');
    await expect(overlayBefore).toBeDisplayed();

    // Press Escape
    await browser.keys('Escape');
    await browser.pause(400);

    // Verify it closed
    const isHidden = await browser.execute(() => {
      const el = document.querySelector('.search-overlay');
      if (!el) return true;
      return window.getComputedStyle(el).display === 'none';
    });
    expect(isHidden).toBe(true);
  });
});

// ─── Scenario F2: Context Tab & Anchors ───────────────────────────────

describe('Scenario F2 — Context Tab & Anchors', () => {
  let projectId: string;

  before(async () => {
    await resetOverlays();
    const id = await getFirstProjectId();
    if (!id) throw new Error('No project box found');
    projectId = id;
  });

  after(async () => {
    // Restore to Model tab
    if (projectId) {
      await switchProjectTabByLabel(projectId, 'Model');
    }
  });

  it('should show Context tab in project tab bar', async () => {
    const hasContextTab = await browser.execute((id) => {
      const box = document.querySelector(`[data-project-id="${id}"]`);
      const tabs = box?.querySelectorAll('[data-testid="project-tabs"] .ptab');
      if (!tabs) return false;
      for (const tab of tabs) {
        if (tab.textContent?.trim() === 'Context') return true;
      }
      return false;
    }, projectId);
    expect(hasContextTab).toBe(true);
  });

  it('should render context visualization when Context tab activated', async () => {
    await switchProjectTabByLabel(projectId, 'Context');

    const hasContent = await browser.execute((id) => {
      const box = document.querySelector(`[data-project-id="${id}"]`);
      // Look for context-tab component, stats, token meter, or anchors section
      const contextTab = box?.querySelector('.context-tab');
      const stats = box?.querySelector('.context-stats, .token-meter, .stat-value');
      const anchors = box?.querySelector('.anchors-section');
      return (contextTab !== null) || (stats !== null) || (anchors !== null);
    }, projectId);
    expect(hasContent).toBe(true);
  });

  it('should show anchor budget scale selector in Settings', async () => {
    // Open settings
    await browser.execute(() => {
      const btn = document.querySelector('[data-testid="settings-btn"]');
      if (btn) (btn as HTMLElement).click();
    });
    await browser.pause(500);

    // Navigate to Orchestration category
    const clickedOrch = await browser.execute(() => {
      const items = document.querySelectorAll('.settings-sidebar button, .settings-sidebar [role="tab"]');
      for (const item of items) {
        if (item.textContent?.includes('Orchestration')) {
          (item as HTMLElement).click();
          return true;
        }
      }
      return false;
    });
    await browser.pause(300);

    // Look for anchor budget setting
    const hasAnchorBudget = await browser.execute(() => {
      const panel = document.querySelector('.settings-panel, .settings-content');
      if (!panel) return false;
      const text = panel.textContent ?? '';
      return text.includes('Anchor') || text.includes('anchor') ||
        document.querySelector('#setting-anchor-budget') !== null;
    });

    // Close settings
    await browser.keys('Escape');
    await browser.pause(300);

    if (clickedOrch) {
      expect(hasAnchorBudget).toBe(true);
    }
    // If Orchestration nav not found, test passes but logs info
    if (!clickedOrch) {
      console.log('Orchestration category not found in settings nav — may use different layout');
    }
  });
});

// ─── Scenario F3: SSH Tab ─────────────────────────────────────────────

describe('Scenario F3 — SSH Tab', () => {
  let projectId: string;

  before(async () => {
    await resetOverlays();
    const id = await getFirstProjectId();
    if (!id) throw new Error('No project box found');
    projectId = id;
  });

  after(async () => {
    // Restore to Model tab
    if (projectId) {
      await switchProjectTabByLabel(projectId, 'Model');
    }
  });

  it('should show SSH tab in project tab bar', async () => {
    const hasSshTab = await browser.execute((id) => {
      const box = document.querySelector(`[data-project-id="${id}"]`);
      const tabs = box?.querySelectorAll('[data-testid="project-tabs"] .ptab');
      if (!tabs) return false;
      for (const tab of tabs) {
        if (tab.textContent?.trim() === 'SSH') return true;
      }
      return false;
    }, projectId);
    expect(hasSshTab).toBe(true);
  });

  it('should render SSH content pane when tab activated', async () => {
    await switchProjectTabByLabel(projectId, 'SSH');

    const hasSshContent = await browser.execute((id) => {
      const box = document.querySelector(`[data-project-id="${id}"]`);
      const sshTab = box?.querySelector('.ssh-tab');
      const sshHeader = box?.querySelector('.ssh-header');
      return (sshTab !== null) || (sshHeader !== null);
    }, projectId);
    expect(hasSshContent).toBe(true);
  });

  it('should show SSH connection list or empty state', async () => {
    // SSH tab should show either connections or an empty state message
    const sshState = await browser.execute((id) => {
      const box = document.querySelector(`[data-project-id="${id}"]`);
      const list = box?.querySelector('.ssh-list');
      const empty = box?.querySelector('.ssh-empty');
      const cards = box?.querySelectorAll('.ssh-card');
      return {
        hasList: list !== null,
        hasEmpty: empty !== null,
        cardCount: cards?.length ?? 0,
      };
    }, projectId);

    // Either we have a list container or cards or an empty state
    expect(sshState.hasList || sshState.hasEmpty || sshState.cardCount >= 0).toBe(true);
  });

  it('should show add SSH connection button or form', async () => {
    const hasAddControl = await browser.execute((id) => {
      const box = document.querySelector(`[data-project-id="${id}"]`);
      // Look for add button or SSH form
      const form = box?.querySelector('.ssh-form');
      const addBtn = box?.querySelector('.ssh-header button, .ssh-add, [title*="Add"]');
      return (form !== null) || (addBtn !== null);
    }, projectId);
    expect(hasAddControl).toBe(true);
  });
});
