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

// Phase D — Settings Panel Tests (D1–D3)
// Tests the redesigned VS Code-style settings panel with 6+1 category tabs,
// appearance controls, and theme editor.

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

async function openSettings(): Promise<void> {
  const panel = await browser.$('.settings-panel');
  if (!(await panel.isDisplayed().catch(() => false))) {
    await browser.execute(() => {
      const btn = document.querySelector('[data-testid="settings-btn"]');
      if (btn) (btn as HTMLElement).click();
    });
    await (await browser.$('.sidebar-panel')).waitForDisplayed({ timeout: 5000 });
  }
  await browser.waitUntil(
    async () => (await browser.execute(() => document.querySelectorAll('.settings-panel').length) as number) >= 1,
    { timeout: 5000, timeoutMsg: 'Settings panel did not render within 5s' },
  );
  await browser.pause(300);
}

async function closeSettings(): Promise<void> {
  const panel = await browser.$('.sidebar-panel');
  if (await panel.isDisplayed().catch(() => false)) {
    await browser.execute(() => {
      const btn = document.querySelector('.settings-close') || document.querySelector('.panel-close');
      if (btn) (btn as HTMLElement).click();
    });
    await browser.pause(500);
  }
}

async function clickCategory(label: string): Promise<void> {
  await browser.execute((lbl) => {
    const items = document.querySelectorAll('.sidebar-item');
    for (const el of items) {
      if (el.textContent?.includes(lbl)) { (el as HTMLElement).click(); return; }
    }
  }, label);
  await browser.pause(300);
}

async function scrollToTop(): Promise<void> {
  await browser.execute(() => { document.querySelector('.settings-content')?.scrollTo(0, 0); });
  await browser.pause(200);
}

// ─── Scenario D1: Settings Panel Categories ──────────────────────────

describe('Scenario D1 — Settings Panel Categories', () => {
  before(async () => { await openSettings(); });
  after(async () => { await closeSettings(); });

  it('should render settings sidebar with 6+ category buttons', async () => {
    const sidebar = await browser.$('.settings-sidebar');
    await expect(sidebar).toBeDisplayed();
    const items = await browser.$$('.sidebar-item');
    expect(items.length).toBeGreaterThanOrEqual(6);
  });

  it('should switch between all 6 categories', async () => {
    for (const cat of ['Appearance', 'Agents', 'Security', 'Projects', 'Orchestration', 'Advanced']) {
      await clickCategory(cat);
      const content = await browser.$('.settings-content');
      await expect(content).toBeDisplayed();
    }
    await clickCategory('Appearance');
  });

  it('should highlight active category with blue accent', async () => {
    await clickCategory('Agents');
    const activeItem = await browser.$('.sidebar-item.active');
    await expect(activeItem).toBeExisting();
    expect(await activeItem.getText()).toContain('Agents');
    await clickCategory('Appearance');
  });

  it('should show search bar and filter results', async () => {
    await expect(await browser.$('.settings-search')).toBeDisplayed();
    await browser.execute(() => {
      const input = document.querySelector('.settings-search') as HTMLInputElement;
      if (input) { input.value = 'font'; input.dispatchEvent(new Event('input', { bubbles: true })); }
    });
    await browser.pause(500);
    const results = await browser.$$('.search-result');
    expect(results.length).toBeGreaterThan(0);
    const hasFont = await browser.execute(() => {
      const labels = document.querySelectorAll('.search-result .sr-label');
      return Array.from(labels).some(l => l.textContent?.toLowerCase().includes('font'));
    });
    expect(hasFont).toBe(true);
    // Clear search
    await browser.execute(() => {
      const input = document.querySelector('.settings-search') as HTMLInputElement;
      if (input) { input.value = ''; input.dispatchEvent(new Event('input', { bubbles: true })); }
    });
    await browser.pause(300);
  });
});

// ─── Scenario D2: Appearance Settings ────────────────────────────────

describe('Scenario D2 — Appearance Settings', () => {
  before(async () => { await openSettings(); await clickCategory('Appearance'); await scrollToTop(); });
  after(async () => { await closeSettings(); });

  it('should show theme dropdown with 17+ built-in themes grouped by category', async () => {
    await browser.execute(() => {
      const btn = document.querySelector('.appearance .custom-dropdown .dropdown-btn');
      if (btn) (btn as HTMLElement).click();
    });
    await browser.pause(500);
    const groupLabels = await browser.$$('.theme-menu .group-label');
    expect(groupLabels.length).toBeGreaterThanOrEqual(3);
    const items = await browser.$$('.theme-menu .dropdown-item');
    expect(items.length).toBeGreaterThanOrEqual(17);
    // Close dropdown
    await browser.execute(() => {
      const btn = document.querySelector('.appearance .custom-dropdown .dropdown-btn');
      if (btn) (btn as HTMLElement).click();
    });
    await browser.pause(300);
  });

  it('should show font size steppers with -/+ buttons', async () => {
    const steppers = await browser.$$('.stepper');
    expect(steppers.length).toBeGreaterThanOrEqual(1);
    const before = await browser.execute(() => document.querySelector('.stepper span')?.textContent ?? '');
    const sizeBefore = parseInt(before as string, 10);
    await browser.execute(() => {
      const btns = document.querySelectorAll('.stepper button');
      if (btns.length >= 2) (btns[1] as HTMLElement).click(); // + button
    });
    await browser.pause(300);
    const after = await browser.execute(() => document.querySelector('.stepper span')?.textContent ?? '');
    expect(parseInt(after as string, 10)).toBe(sizeBefore + 1);
    // Revert
    await browser.execute(() => {
      const btns = document.querySelectorAll('.stepper button');
      if (btns.length >= 1) (btns[0] as HTMLElement).click();
    });
    await browser.pause(200);
  });

  it('should show terminal cursor style selector (Block/Line/Underline)', async () => {
    await browser.execute(() => {
      document.getElementById('setting-cursor-style')?.scrollIntoView({ behavior: 'instant', block: 'center' });
    });
    await browser.pause(300);
    const segmented = await browser.$('.segmented');
    await expect(segmented).toBeDisplayed();
    const buttons = await browser.$$('.segmented button');
    expect(buttons.length).toBe(3);
    const activeText = await browser.execute(() =>
      document.querySelector('.segmented button.active')?.textContent?.trim() ?? '',
    );
    expect(activeText).toBe('Block');
  });

  it('should show scrollback lines input', async () => {
    await browser.execute(() => {
      document.getElementById('setting-scrollback')?.scrollIntoView({ behavior: 'instant', block: 'center' });
    });
    await browser.pause(300);
    const input = await browser.$('#setting-scrollback input[type="number"]');
    await expect(input).toBeExisting();
    const num = parseInt(await input.getValue() as string, 10);
    expect(num).toBeGreaterThanOrEqual(100);
    expect(num).toBeLessThanOrEqual(100000);
  });
});

// ─── Scenario D3: Theme Editor ───────────────────────────────────────

describe('Scenario D3 — Theme Editor', () => {
  before(async () => { await openSettings(); await clickCategory('Appearance'); await scrollToTop(); });
  after(async () => {
    await browser.execute(() => {
      const btn = Array.from(document.querySelectorAll('.editor .btn'))
        .find(b => b.textContent?.trim() === 'Cancel');
      if (btn) (btn as HTMLElement).click();
    });
    await browser.pause(300);
    await closeSettings();
  });

  it('should show "+ New Custom Theme" button', async () => {
    const btn = await browser.$('.new-theme-btn');
    await expect(btn).toBeDisplayed();
    expect(await btn.getText()).toContain('New Custom Theme');
  });

  it('should open theme editor with color pickers when clicked', async () => {
    await browser.execute(() => {
      const btn = document.querySelector('.new-theme-btn');
      if (btn) (btn as HTMLElement).click();
    });
    await browser.pause(500);
    const editor = await browser.$('.editor');
    await expect(editor).toBeDisplayed();
    const colorInputs = await browser.$$('.editor input[type="color"]');
    expect(colorInputs.length).toBeGreaterThan(0);
    const nameInput = await browser.$('.editor .name-input');
    await expect(nameInput).toBeExisting();
  });

  it('should show 26 color pickers grouped in Accents and Neutrals', async () => {
    const groups = await browser.$$('.editor details.group');
    expect(groups.length).toBe(2);
    const colorRows = await browser.$$('.editor .color-row');
    expect(colorRows.length).toBe(26);
  });

  it('should have Cancel and Save buttons', async () => {
    const hasCancel = await browser.execute(() =>
      Array.from(document.querySelectorAll('.editor .footer .btn')).some(b => b.textContent?.trim() === 'Cancel'),
    );
    expect(hasCancel).toBe(true);
    const hasSave = await browser.execute(() =>
      Array.from(document.querySelectorAll('.editor .footer .btn')).some(b => b.textContent?.trim() === 'Save'),
    );
    expect(hasSave).toBe(true);
  });
});
