/**
 * Terminal tests — tab bar, tab CRUD, PTY I/O, collapse/expand, resize.
 */

import { browser, expect } from '@wdio/globals';
import * as S from '../helpers/selectors.ts';
import { addTerminalTab } from '../helpers/actions.ts';
import { exec } from '../helpers/execute.ts';

describe('Terminal section', () => {
  it('should show the terminal tab bar', async () => {
    const exists = await exec((sel: string) => {
      return document.querySelector(sel) !== null;
    }, S.TERMINAL_TABS);
    if (exists) {
      const el = await browser.$(S.TERMINAL_TABS);
      await expect(el).toBeDisplayed();
    }
  });

  it('should have an add-tab button', async () => {
    const addBtn = await browser.$(S.TAB_ADD_BTN);
    if (await addBtn.isExisting()) {
      expect(await addBtn.isClickable()).toBe(true);
    }
  });

  it('should create a new terminal tab on add click', async function () {
    // Terminal may be collapsed by default — expand first
    const hasAddBtn = await exec(() => {
      const btn = document.querySelector('.tab-add-btn');
      if (!btn) return false;
      return getComputedStyle(btn).display !== 'none';
    });
    if (!hasAddBtn) { this.skip(); return; }

    const countBefore = await exec((sel: string) => {
      return document.querySelectorAll(sel).length;
    }, S.TERMINAL_TAB);

    await addTerminalTab();

    const countAfter = await exec((sel: string) => {
      return document.querySelectorAll(sel).length;
    }, S.TERMINAL_TAB);
    expect(countAfter).toBeGreaterThanOrEqual(countBefore + 1);
  });

  it('should show an xterm container', async () => {
    const xterm = await browser.$(S.XTERM);
    if (await xterm.isExisting()) {
      await expect(xterm).toBeDisplayed();
    }
  });

  it('should accept keyboard input in terminal', async () => {
    const textarea = await browser.$(S.XTERM_TEXTAREA);
    if (await textarea.isExisting()) {
      await textarea.click();
      await browser.keys('echo hello');
      // Verify no crash — actual output requires PTY daemon
    }
  });

  it('should highlight active tab', async () => {
    const count = await exec((sel: string) => {
      return document.querySelectorAll(sel).length;
    }, S.TERMINAL_TAB_ACTIVE);
    if (count > 0) {
      expect(count).toBe(1);
    }
  });

  it('should switch tabs on click', async () => {
    const tabCount = await exec((sel: string) => {
      return document.querySelectorAll(sel).length;
    }, S.TERMINAL_TAB);

    if (tabCount >= 2) {
      await exec((sel: string) => {
        const tabs = document.querySelectorAll(sel);
        if (tabs[1]) (tabs[1] as HTMLElement).click();
      }, S.TERMINAL_TAB);
      await browser.pause(300);

      const isActive = await exec((sel: string) => {
        const tabs = document.querySelectorAll(sel);
        return tabs[1]?.classList.contains('active') ?? false;
      }, S.TERMINAL_TAB);
      expect(isActive).toBe(true);
    }
  });

  it('should show close button on tab hover', async () => {
    const tabs = await browser.$$(S.TERMINAL_TAB);
    if (tabs.length === 0) return;

    await tabs[0].moveTo();
    await browser.pause(200);

    const closeBtn = await tabs[0].$(S.TAB_CLOSE);
    if (await closeBtn.isExisting()) {
      await expect(closeBtn).toBeDisplayed();
    }
  });

  it('should close a tab on close button click', async () => {
    const countBefore = await exec((sel: string) => {
      return document.querySelectorAll(sel).length;
    }, S.TERMINAL_TAB);
    if (countBefore < 2) return;

    const tabs = await browser.$$(S.TERMINAL_TAB);
    const lastTab = tabs[tabs.length - 1];
    await lastTab.moveTo();
    await browser.pause(200);

    const closeBtn = await lastTab.$(S.TAB_CLOSE);
    if (await closeBtn.isExisting()) {
      await closeBtn.click();
      await browser.pause(300);

      const countAfter = await exec((sel: string) => {
        return document.querySelectorAll(sel).length;
      }, S.TERMINAL_TAB);
      expect(countAfter).toBeLessThan(countBefore);
    }
  });

  it('should support collapse/expand toggle', async () => {
    const collapseBtn = await browser.$(S.TERMINAL_COLLAPSE_BTN);
    if (!(await collapseBtn.isExisting())) return;

    await collapseBtn.click();
    await browser.pause(300);

    const h1 = await exec((sel: string) => {
      const el = document.querySelector(sel);
      return el ? getComputedStyle(el).height : '';
    }, S.TERMINAL_SECTION);

    await collapseBtn.click();
    await browser.pause(300);

    const h2 = await exec((sel: string) => {
      const el = document.querySelector(sel);
      return el ? getComputedStyle(el).height : '';
    }, S.TERMINAL_SECTION);

    expect(h1).not.toBe(h2);
  });

  it('should handle multiple terminal tabs', async function () {
    // Terminal may be collapsed by default — skip if add button not visible
    const hasAddBtn = await exec(() => {
      const btn = document.querySelector('.tab-add-btn');
      if (!btn) return false;
      return getComputedStyle(btn).display !== 'none';
    });
    if (!hasAddBtn) { this.skip(); return; }

    // Add two tabs
    await addTerminalTab();
    await addTerminalTab();

    const count = await exec((sel: string) => {
      return document.querySelectorAll(sel).length;
    }, S.TERMINAL_TAB);
    expect(count).toBeGreaterThanOrEqual(2);
  });

  it('should handle PTY output display', async () => {
    // Verify xterm rows container exists (for PTY output rendering)
    const hasRows = await exec(() => {
      return document.querySelector('.xterm-rows') !== null;
    });
    if (hasRows) {
      expect(hasRows).toBe(true);
    }
  });

  it('should have terminal container with correct dimensions', async () => {
    const dims = await exec((sel: string) => {
      const el = document.querySelector(sel);
      if (!el) return null;
      const rect = el.getBoundingClientRect();
      return { width: rect.width, height: rect.height };
    }, S.TERMINAL_SECTION);
    if (dims) {
      expect(dims.width).toBeGreaterThan(0);
      expect(dims.height).toBeGreaterThan(0);
    }
  });

  it('should have resize handle', async () => {
    const hasHandle = await exec(() => {
      return document.querySelector('.resize-handle')
        ?? document.querySelector('.terminal-resize') !== null;
    });
    expect(typeof hasHandle).toBe('boolean');
  });
});
