import test from "node:test";
import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";

test("app chrome is not selectable while form fields remain selectable", async () => {
  const css = await readFile(new URL("../../app/app.css", import.meta.url), "utf8");

  assert.match(css, /\.app-shell\{[^}]*user-select:none/);
  assert.match(css, /\.app-shell input,\.app-shell textarea\{[^}]*user-select:text/);
});

test("context header owns account menu and app removes selector row", async () => {
  const [app, appCss, bar, css] = await Promise.all([
    readFile(new URL("../../App.jsx", import.meta.url), "utf8"),
    readFile(new URL("../../app/app.css", import.meta.url), "utf8"),
    readFile(new URL("./ContextBar.jsx", import.meta.url), "utf8"),
    readFile(new URL("./context.css", import.meta.url), "utf8")
  ]);
  const [settingsWindow, accountManagement] = await Promise.all([
    readFile(new URL("./SettingsWindow.jsx", import.meta.url), "utf8"),
    readFile(new URL("../accounts/AccountManagementPage.jsx", import.meta.url), "utf8")
  ]);

  assert.doesNotMatch(app, /<ContextSelectors\b/);
  assert.match(app, /const displaySession = conversation\.displaySession \?\? app\.session/);
  assert.match(app, /const visibleSession = transitionSession \?\? displaySession/);
  assert.match(app, /headerProject\(visibleSession, app\.selectedWorkspace, app\.workspaces, app\.newChatOpen \|\| app\.tab === "threads"\)/);
  assert.match(app, /<ContextBar account=\{app\.selectedAccount\} project=\{project\} session=\{visibleSession\}/);
  assert.match(app, /onAccountChange=\{handleAccountChange\}/);
  assert.match(app, /const accountSwitchAccountId = accountSwitchLockAccountId\(notifications\.sessions, visibleSession\)/);
  assert.match(app, /accountSwitchLocked=\{accountSwitchLocked\(notifications\.sessions, visibleSession\)\}/);
  assert.match(app, /accountSwitchAccountId=\{accountSwitchAccountId\}/);
  assert.match(app, /onChatOpen=\{\(\) => app\.session && app\.selectTab\("chat"\)\}/);
  assert.match(app, /SettingsWindow/);
  assert.match(app, /function openSettings\(\)/);
  assert.match(app, /app\.openSettings\(\)/);
  assert.match(app, /onSettingsOpen=\{openSettings\}/);
  assert.match(app, /const closeSettings = useBackLayer\(app\.tab === "settings", settingsMotion\.startExit/);
  assert.match(app, /const screenLayerActive = \(app\.tab !== "threads" && app\.tab !== "settings"\)/);
  assert.match(app, /const closeScreen = useBackLayer\(screenLayerActive, screenMotion\.startExit/);
  assert.match(app, /app\.settingsReturnTab !== "threads"/);
  assert.doesNotMatch(app, /settingsReturnTabRef/);
  assert.match(app, /app\.tab === "settings"/);
  assert.match(app, /<SettingsWindow accounts=\{app\.accounts\} accountMosaic=\{accountMosaic\} manager=\{accounts\}/);
  assert.doesNotMatch(app, /<SettingsWindow[^>]*(?:account=|usageStatus=)/);
  assert.doesNotMatch(app, /<SettingsWindow[^>]*tokenUsage=/);
  assert.match(app, /onBack=\{closeSettings\}/);
  assert.match(app, /chats\.setArchived\(true\)/);
  assert.match(app, /app\.selectTab\("threads"\)/);
  assert.match(app, /manager=\{accounts\}/);
  assert.match(app, /onUseResetCredit=\{status\.useResetCredit\}/);
  assert.match(appCss, /grid-template-rows:auto auto 1fr/);
  assert.match(appCss, /\.app-shell>\.panel,\.app-shell>\.chats-panel,\.app-shell>\.new-chat-overlay,\.app-shell>\.chat,\.app-shell>\.chat-transition,\.app-shell>\.settings-page\{grid-row:3\}/);
  assert.doesNotMatch(app, /selectTab\("accounts"\)/);
  assert.doesNotMatch(app, />Accounts<\/button>/);
  assert.doesNotMatch(appCss, /\.tabs/);

  assert.match(bar, /className="context-account-button"/);
  assert.match(bar, /title=\{account \? t\("context\.manageAccount"\) : t\("context\.signIn"\)\}/);
  assert.match(bar, /accountDisplayName/);
  assert.match(bar, /accountStatusLabel/);
  assert.match(bar, /runtimeChannel/);
  assert.match(bar, /runtimeChannel === "development" && <span className="context-runtime-badge context-runtime-badge--development">\{t\("runtime\.development"\)\}<\/span>/);
  assert.doesNotMatch(bar, /t\(`runtime\.\$\{runtimeChannel\}`\)/);
  assert.match(bar, /className="context-account-menu"/);
  assert.match(bar, /context-account-menu-title[^>]*>\{t\("context\.accounts"\)\}</);
  assert.match(bar, /\{t\("context\.settings"\)\}<\/button>/);
  assert.doesNotMatch(bar, />Manage accounts<\/button>/);
  assert.match(bar, /closeAccountMenu\(\(\) => onSettingsOpen\?\.\(\)\)/);
  assert.doesNotMatch(bar, /setSettingsOpen/);
  assert.doesNotMatch(bar, /<AccountsPanel accounts=\{accounts\} manager=\{manager\}/);
  assert.match(settingsWindow, /<AccountManagementPage accounts=\{accounts\} manager=\{manager\}/);
  assert.match(accountManagement, /<AccountsPanel accounts=\{accounts\} manager=\{manager\}/);
  assert.match(settingsWindow, /className="settings-page"/);
  assert.match(settingsWindow, /className="screen-back conversation-back"/);
  assert.match(settingsWindow, /<BackIcon \/>/);
  assert.doesNotMatch(settingsWindow, /settings-back/);
  assert.match(settingsWindow, /className="settings-content"/);
  assert.match(settingsWindow, /className="settings-prompt"/);
  assert.doesNotMatch(settingsWindow, /settings-dialog/);
  assert.match(settingsWindow, /settings-section/);
  assert.match(settingsWindow, /t\("settings\.accounts"\)/);
  assert.match(settingsWindow, /t\("settings\.chats"\)/);
  assert.match(settingsWindow, /t\("settings\.archivedChats"\)/);
  assert.match(settingsWindow, /onClick=\{onArchivedOpen\}/);
  assert.match(settingsWindow, /const \[usageOpen, setUsageOpen\] = useState\(false\)/);
  assert.match(settingsWindow, /useBackLayer\(usageOpen, \(\) => setUsageOpen\(false\), "settings-usage"\)/);
  assert.match(settingsWindow, /onUsageOpen=\{\(\) => setUsageOpen\(true\)\}/);
  assert.match(accountManagement, /t\("settings\.usage"\)/);
  assert.match(accountManagement, /onClick=\{onUsageOpen\}/);
  assert.match(settingsWindow, /<UsageSettingsPage/);
  assert.match(settingsWindow, /onClick=\{onBack\}/);
  assert.match(settingsWindow, /t\("settings\.appearance"\)/);
  assert.match(settingsWindow, /className="settings-choice"/);
  assert.match(settingsWindow, /<span>Language<\/span>/);
  assert.match(settingsWindow, /aria-label="Language"/);
  assert.match(settingsWindow, /t\("settings\.theme"\)/);
  assert.match(settingsWindow, /const \[languageMenuOpen, setLanguageMenuOpen\] = useState\(false\)/);
  assert.match(settingsWindow, /const \[themeMenuOpen, setThemeMenuOpen\] = useState\(false\)/);
  assert.match(settingsWindow, /function selectLanguage\(nextLanguage\)/);
  assert.match(settingsWindow, /setLanguage\(nextLanguage\);\s*setLanguageMenuOpen\(false\);/s);
  assert.doesNotMatch(settingsWindow, /setLanguage\(nextLanguage\);\s*closeLanguageMenu\(\);/s);
  assert.match(settingsWindow, /function selectTheme\(nextTheme\)/);
  assert.match(settingsWindow, /setTheme\(nextTheme\);\s*setThemeMenuOpen\(false\);/s);
  assert.doesNotMatch(settingsWindow, /setTheme\(nextTheme\);\s*closeThemeMenu\(\);/s);
  assert.match(settingsWindow, /className="settings-language-trigger"/);
  assert.match(settingsWindow, /className="settings-language-trigger".*?<span>\{language === "ko" \? "Korean" : "English"\}<\/span><ForwardIcon className="settings-choice-chevron" \/><\/button>/s);
  assert.match(settingsWindow, /className="settings-theme-trigger"/);
  assert.match(settingsWindow, /className="settings-language-menu" role="menu"/);
  assert.match(settingsWindow, /className="settings-theme-menu" role="menu"/);
  assert.match(settingsWindow, /option value="en">English<\/option>/);
  assert.match(settingsWindow, /option value="ko">Korean<\/option>/);
  assert.match(bar, /function toggleAccountMenu\(\)/);
  assert.match(bar, /onClick=\{toggleAccountMenu\}/);
  assert.match(bar, /onAccountChange\(accountOption\.id\)/);
  assert.match(bar, /const lockedAccountId = accountSwitchLocked \? accountSwitchAccountId \|\| accountId : ""/);
  assert.match(bar, /accountSwitchAllowed\(accountOption\.id, accountId, lockedAccountId\)/);
  assert.match(bar, /disabled=\{accountOption\.entitlementLocked \|\| !accountSwitchAllowed\(accountOption\.id, accountId, lockedAccountId\)\}/);
  assert.match(bar, /t\("context\.switchLocked"\)/);
  assert.match(bar, /accountOption\.status !== "logged_in"/);
  assert.match(bar, /manager\.connect\(accountOption\.id\)/);
  assert.match(bar, /accountOption\.id === accountId && accountOption\.status === "logged_in"/);
  assert.match(bar, /resetCreditsAvailable/);
  assert.match(bar, /t\("context\.resetCredits"/);
  assert.match(bar, /onUseResetCredit/);
  assert.match(bar, /<ResetCreditDialog/);
  assert.doesNotMatch(bar, /window\.(?:confirm|alert)/);
  assert.match(bar, /setMenuOpen\(false\)/);
  assert.match(bar, /account-login-dialog/);
  assert.match(bar, /!manager\.login\.userCode && <button[^>]+onClick=\{manager\.requestLoginCode\}[^>]*>\{manager\.pending \? t\("context\.requestingCode"\) : t\("context\.getLoginCode"\)\}<\/button>/);
  assert.match(bar, /import \{ MessageCopyButton \} from "\.\.\/conversation\/MessageCopyButton\.jsx"/);
  assert.match(bar, /className="account-login-copy-action"/);
  assert.match(bar, /<MessageCopyButton text=\{manager\.login\.userCode\} active onDismiss=\{noop\} standalone \/>/);
  assert.match(bar, /t\("context\.openChatGpt"\)/);
  assert.match(bar, /manager\.checkConnection/);
  assert.doesNotMatch(bar, /Checking\?\?|횞/);
  assert.match(bar, /setMenuOpen\(false\)/);
  assert.match(bar, /useOutsideDismiss\(accountMenuRef/);
  assert.match(bar, /ref=\{accountMenuRef\}/);
  assert.match(bar, /className="context-project-button context-project-title"/);
  assert.match(bar, /lastChatProjectLabel\(session, project, t\)/);
  assert.match(bar, /onClick=\{onChatOpen\}/);
  assert.match(bar, /chatProgressLabel\(session, t\)/);
  assert.match(bar, /statusDisabled=\{!session\}/);
  assert.match(bar, /onStatusOpen=\{onChatOpen\}/);
  assert.match(bar, /<NotificationCenter notifications=\{notifications\} accounts=\{accounts\} currentStatus=\{chatProgressLabel\(session, t\)\}/);

  assert.match(css, /\.context-account-button\{[^}]*min-height:48px/s);
  assert.match(css, /\.context-account-meta\{[^}]*display:flex/s);
  assert.match(css, /\.context-runtime-badge\{[^}]*border-radius:999px/s);
  assert.match(css, /\.context-runtime-badge--development\{[^}]*#f0a33a/s);
  assert.match(css, /\.context-account-menu\{[^}]*position:absolute/s);
  assert.match(css, /\.context-account-menu button\{[^}]*min-height:48px/s);
  assert.match(css, /\.context-project\{[^}]*grid-template-areas:"title alarm" "status alarm"[^}]*grid-template-columns:minmax\(0,1fr\) 44px/s);
  assert.match(css, /\.context-project-button\{[^}]*min-height:0[^}]*text-align:left/s);
  assert.match(css, /\.context-project-title\{[^}]*grid-area:title/s);
  assert.match(css, /\.context-project-status\{[^}]*grid-area:status/s);
  assert.match(css, /\.context-project-button>strong\{[^}]*min-width:0[^}]*overflow:hidden[^}]*text-overflow:ellipsis[^}]*white-space:nowrap/s);
  assert.match(css, /\.context-project-indicator\{[^}]*border-radius:50%/s);
  assert.match(css, /\.context-project-button\{[^}]*position:relative/s);
  assert.match(css, /\.context-project-indicator--complete\{[^}]*#35c46a/s);
  assert.match(css, /\.context-project-indicator--active\{[^}]*#f0a33a/s);
  assert.match(css, /\.context-project-indicator--error\{[^}]*#ef5350/s);
  assert.match(css, /\.settings-page\{[^}]*position:relative[^}]*overflow:hidden/s);
  assert.match(css, /\.settings-content\{[^}]*width:min\(100%,560px\)[^}]*padding:72px 12px 24px/s);
  assert.match(css, /\.settings-prompt\{[^}]*font-size:clamp\(24px,7vw,36px\)[^}]*text-align:center/s);
  assert.doesNotMatch(css, /\.settings-header/);
  assert.doesNotMatch(css, /\.settings-back/);
  assert.doesNotMatch(css, /\.settings-window/);
  assert.doesNotMatch(css, /\.settings-dialog/);
  assert.match(css, /\.settings-overlay\{[^}]*position:fixed/s);
  assert.match(css, /\.settings-close\{[^}]*border:0/s);
  assert.match(css, /\.settings-section\{[^}]*display:grid/s);
  assert.match(css, /\.settings-section h2,\.settings-section h3\{[^}]*font-size:16px[^}]*font-weight:700/s);
  assert.match(css, /\.settings-select,\.settings-action\{[^}]*min-height:48px/s);
  assert.match(css, /\.settings-action\{[^}]*display:flex/s);
  assert.match(css, /\.settings-choice\{[^}]*grid-template-columns:minmax\(0,1fr\) minmax\(180px,240px\)/s);
  assert.match(css, /\.settings-language-picker,\.settings-theme-picker\{[^}]*position:relative/s);
  assert.match(css, /\.settings-language-menu,\.settings-theme-menu\{[^}]*position:absolute/s);
  assert.match(css, /html\[data-theme="light"\] \.app-shell :is\(\.settings-language-picker,\.settings-theme-picker\)\{[^}]*background:#eaeef2!important[^}]*background-color:#eaeef2!important/s);
  assert.match(css, /\.settings-select-wrap::after\{[^}]*rotate\(45deg\)/s);
  assert.match(css, /\.settings-choice \.settings-select\{[^}]*appearance:none/s);
  assert.match(css, /\.context-reset-credit\{[^}]*display:flex/s);
  assert.match(css, /\.context-account-option>button\{[^}]*border-bottom:0/s);
  assert.match(css, /\.context-reset-credit\{[^}]*position:relative[^}]*gap:4px/s);
  assert.match(css, /\.context-reset-credit::before\{[^}]*left:12px[^}]*right:8px[^}]*height:1px/s);
  assert.match(css, /\.context-reset-credit\{[^}]*min-height:36px[^}]*margin-top:-4px/s);
  assert.match(css, /\.context-reset-credit button\{[^}]*min-height:32px/s);
  assert.match(css, /\.account-login-code-row\{[^}]*grid-template-columns:minmax\(0,1fr\) auto/s);
  assert.match(css, /\.account-login-copy-action\{[^}]*min-width:48px/s);
});
