import { browser, expect } from '@wdio/globals';
import { exec } from '../helpers/execute.ts';

//


/** Switch to a tab by text content in the first project box. */
async function clickTabByText(tabText: string): Promise<void> {
  await exec((text) => {
    const tabs = document.querySelectorAll('[data-testid="project-tabs"] .ptab');
    for (const tab of tabs) {
      if (tab.textContent?.trim() === text) {
        (tab as HTMLElement).click();
        return;
      }
    }
  }, tabText);
  await browser.pause(400);
}

/** Get the active tab text in the first project box. */
async function getActiveTabText(): Promise<string> {
  return exec(() => {
    const box = document.querySelector('[data-testid="project-box"]');
    const active = box?.querySelector('[data-testid="project-tabs"] .ptab.active');
    return active?.textContent?.trim() ?? '';
  });
}

/** Check if a tab with given text exists in any project box. */
async function tabExistsWithText(tabText: string): Promise<boolean> {
  return exec((text) => {
    const tabs = document.querySelectorAll('[data-testid="project-tabs"] .ptab');
    return Array.from(tabs).some((t) => t.textContent?.trim() === text);
  }, tabText);
}


describe('Scenario E5 — Project Health Indicators', () => {
  before(async () => {
    await browser.waitUntil(
      async () => {
        const count = await exec(() =>
          document.querySelectorAll('[data-testid="project-box"]').length,
        );
        return (count as number) >= 1;
      },
      { timeout: 10_000, timeoutMsg: 'No project boxes rendered within 10s' },
    );
    await clickTabByText('Model');
  });

  it('should show status dot in ProjectHeader', async () => {
    const statusDot = await exec(() => {
      const header = document.querySelector('.project-header');
      const dot = header?.querySelector('.status-dot');
      return {
        exists: dot !== null,
        classes: dot?.className ?? '',
      };
    });
    expect(statusDot.exists).toBe(true);
    expect(statusDot.classes).toContain('status-dot');
  });

  it('should show status dot with appropriate state class', async () => {
    const dotClass = await exec(() => {
      const header = document.querySelector('.project-header');
      const dot = header?.querySelector('.status-dot');
      return dot?.className ?? '';
    });
    expect(dotClass).toContain('status-dot');
  });

  it('should show CWD path in ProjectHeader info area', async () => {
    const cwdText = await exec(() => {
      const header = document.querySelector('.project-header');
      const cwd = header?.querySelector('.info-cwd');
      return cwd?.textContent?.trim() ?? '';
    });
    expect(cwdText.length).toBeGreaterThan(0);
  });

  it('should have context pressure info element when pressure exists', async () => {
    const ctxInfo = await exec(() => {
      const header = document.querySelector('.project-header');
      const ctx = header?.querySelector('.info-ctx');
      return {
        exists: ctx !== null,
        text: ctx?.textContent?.trim() ?? '',
      };
    });
    if (ctxInfo.exists) {
      expect(ctxInfo.text).toMatch(/ctx \d+%/);
    }
  });

  it('should have burn rate info element when agents are active', async () => {
    const rateInfo = await exec(() => {
      const header = document.querySelector('.project-header');
      const rate = header?.querySelector('.info-rate');
      return {
        exists: rate !== null,
        text: rate?.textContent?.trim() ?? '',
      };
    });
    if (rateInfo.exists) {
      expect(rateInfo.text).toMatch(/\$[\d.]+\/hr/);
    }
  });

  it('should render ProjectHeader with all structural elements', async () => {
    const structure = await exec(() => {
      const header = document.querySelector('.project-header');
      return {
        hasMain: header?.querySelector('.header-main') !== null,
        hasInfo: header?.querySelector('.header-info') !== null,
        hasStatusDot: header?.querySelector('.status-dot') !== null,
        hasIcon: header?.querySelector('.project-icon') !== null,
        hasName: header?.querySelector('.project-name') !== null,
        hasCwd: header?.querySelector('.info-cwd') !== null,
      };
    });
    expect(structure.hasMain).toBe(true);
    expect(structure.hasInfo).toBe(true);
    expect(structure.hasStatusDot).toBe(true);
    expect(structure.hasIcon).toBe(true);
    expect(structure.hasName).toBe(true);
    expect(structure.hasCwd).toBe(true);
  });
});


describe('Scenario E6 — Metrics Tab', () => {
  before(async () => {
    await clickTabByText('Model');
    await browser.pause(200);
  });

  it('should show Metrics tab button in project tab bar', async () => {
    const hasMetrics = await tabExistsWithText('Metrics');
    expect(hasMetrics).toBe(true);
  });

  it('should switch to Metrics tab and show metrics panel', async () => {
    await clickTabByText('Metrics');
    const activeTab = await getActiveTabText();
    expect(activeTab).toBe('Metrics');

    await browser.waitUntil(
      async () => {
        const exists = await exec(() =>
          document.querySelector('.metrics-panel') !== null,
        );
        return exists as boolean;
      },
      { timeout: 5000, timeoutMsg: 'Metrics panel did not render within 5s' },
    );
  });

  it('should show Live view with fleet aggregates', async () => {
    const liveView = await exec(() => {
      const panel = document.querySelector('.metrics-panel');
      const live = panel?.querySelector('.live-view');
      const aggBar = panel?.querySelector('.agg-bar');
      return {
        hasLive: live !== null,
        hasAgg: aggBar !== null,
      };
    });
    expect(liveView.hasLive).toBe(true);
    expect(liveView.hasAgg).toBe(true);
  });

  it('should show fleet badges in aggregates bar', async () => {
    const badges = await exec(() => {
      const panel = document.querySelector('.metrics-panel');
      const aggBadges = panel?.querySelectorAll('.agg-badge');
      return Array.from(aggBadges ?? []).map((b) => b.textContent?.trim() ?? '');
    });
    expect(badges.length).toBeGreaterThanOrEqual(1);
  });

  it('should show health cards for current project', async () => {
    const cardLabels = await exec(() => {
      const panel = document.querySelector('.metrics-panel');
      const labels = panel?.querySelectorAll('.hc-label');
      return Array.from(labels ?? []).map((l) => l.textContent?.trim() ?? '');
    });
    expect(cardLabels).toContain('Status');
  });

  it('should show view tabs for Live and History toggle', async () => {
    const viewTabs = await exec(() => {
      const panel = document.querySelector('.metrics-panel');
      const tabs = panel?.querySelectorAll('.vtab');
      return Array.from(tabs ?? []).map((t) => t.textContent?.trim() ?? '');
    });
    expect(viewTabs.length).toBeGreaterThanOrEqual(2);
  });

  after(async () => {
    await clickTabByText('Model');
  });
});


describe('Scenario E7 — Conflict Detection UI', () => {
  it('should NOT show external write badge on fresh launch', async () => {
    const hasExternalBadge = await exec(() => {
      const headers = document.querySelectorAll('.project-header');
      for (const header of headers) {
        const ext = header.querySelector('.info-conflict-external');
        if (ext) return true;
      }
      return false;
    });
    expect(hasExternalBadge).toBe(false);
  });

  it('should NOT show agent conflict badge on fresh launch', async () => {
    const hasConflictBadge = await exec(() => {
      const headers = document.querySelectorAll('.project-header');
      for (const header of headers) {
        const conflict = header.querySelector('.info-conflict:not(.info-conflict-external)');
        if (conflict) return true;
      }
      return false;
    });
    expect(hasConflictBadge).toBe(false);
  });

  it('should NOT show file conflict count in status bar on fresh launch', async () => {
    const hasConflict = await exec(() => {
      const bar = document.querySelector('[data-testid="status-bar"]');
      const conflictEl = bar?.querySelector('.state-conflict');
      return conflictEl !== null;
    });
    expect(hasConflict).toBe(false);
  });
});


describe('Scenario E8 — Audit Log Tab', () => {
  it('should show Audit tab only for manager role projects', async () => {
    const auditTabInfo = await exec(() => {
      const boxes = document.querySelectorAll('[data-testid="project-box"]');
      const results: { projectId: string; hasAudit: boolean }[] = [];
      for (const box of boxes) {
        const id = box.getAttribute('data-project-id') ?? '';
        const tabs = box.querySelectorAll('[data-testid="project-tabs"] .ptab');
        const hasAudit = Array.from(tabs).some((t) => t.textContent?.trim() === 'Audit');
        results.push({ projectId: id, hasAudit });
      }
      return results;
    });

    expect(auditTabInfo.length).toBeGreaterThanOrEqual(1);
    for (const info of auditTabInfo) {
      expect(typeof info.hasAudit).toBe('boolean');
    }
  });

  it('should render audit log content when Audit tab is activated', async () => {
    const auditProjectId = await exec(() => {
      const boxes = document.querySelectorAll('[data-testid="project-box"]');
      for (const box of boxes) {
        const tabs = box.querySelectorAll('[data-testid="project-tabs"] .ptab');
        const auditTab = Array.from(tabs).find((t) => t.textContent?.trim() === 'Audit');
        if (auditTab) {
          (auditTab as HTMLElement).click();
          return box.getAttribute('data-project-id') ?? '';
        }
      }
      return '';
    });

    if (!auditProjectId) return; // No manager agent — skip

    await browser.pause(500);
    const auditContent = await exec(() => {
      const tab = document.querySelector('.audit-log-tab');
      if (!tab) return { exists: false, hasToolbar: false, hasEntries: false };
      return {
        exists: true,
        hasToolbar: tab.querySelector('.audit-toolbar') !== null,
        hasEntries: tab.querySelector('.audit-entries') !== null,
      };
    });

    expect(auditContent.exists).toBe(true);
    expect(auditContent.hasToolbar).toBe(true);
    expect(auditContent.hasEntries).toBe(true);

    await clickTabByText('Model');
  });
});
