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

test("usage settings is a separate mobile-friendly detail screen", async () => {
  const [page, css, messages] = await Promise.all([
    readFile(new URL("./UsageSettingsPage.jsx", import.meta.url), "utf8"),
    readFile(new URL("./status.css", import.meta.url), "utf8"),
    readFile(new URL("../../shared/i18n.js", import.meta.url), "utf8")
  ]);

  assert.match(page, /className="settings-page usage-settings-page"/);
  assert.match(page, /className="screen-back conversation-back"/);
  assert.match(page, /t\("settings\.usage"\)/);
  assert.match(page, /t\("usage\.accountDetails"\)/);
  assert.match(page, /sortedAccounts\.map\(\(account\)/);
  assert.doesNotMatch(page, /accountId.*setAccountId/);
  assert.doesNotMatch(page, /<select[^>]*className="usage-sort-select"/);
  assert.match(page, /useOutsideDismiss/);
  assert.doesNotMatch(page, /className="settings-choice usage-sort-control"/);
  assert.match(page, /className="usage-settings-heading"[\s\S]*className="usage-sort-control"[\s\S]*className="usage-sort-trigger"/);
  assert.match(page, /className="usage-sort-actions"[\s\S]*usage-sort-direction[\s\S]*className="usage-sort-control"/);
  assert.match(page, /setSortDirection\(sortDirection === "descending" \? "ascending" : "descending"\)/);
  assert.match(page, /className="usage-sort-trigger"/);
  assert.match(page, /aria-expanded=\{sortMenuOpen\}/);
  assert.match(page, /className="usage-sort-menu" role="menu"/);
  assert.match(page, /role="menuitemradio"/);
  assert.match(page, /sortUsageAccounts/);
  assert.match(page, /sortWeeklySummaryAccounts/);
  assert.match(page, /function WeeklySummary/);
  assert.match(page, /className="settings-section usage-weekly-summary"/);
  assert.match(page, /className="usage-weekly-summary-list"/);
  assert.match(page, /className="usage-weekly-summary-meta"[\s\S]*className="usage-weekly-summary-value"[\s\S]*parts\?\.detail/);
  assert.doesNotMatch(page, /usage\.sortAvailability|"availability"/);
  assert.match(page, /\["primary", t\("usage\.sortPrimary"\)\]/);
  assert.match(page, /\["secondary", t\("usage\.sortSecondary"\)\]/);
  assert.match(page, /\["configured", t\("usage\.sortConfigured"\)\]/);
  assert.match(page, /<UsageTrendChart/);
  assert.match(page, /function AccountTokenGrid/);
  assert.match(page, /buildDailyTokenGrid/);
  assert.match(page, /buildTokenMonthLabels/);
  assert.match(page, /buildTokenPeriodGrid/);
  assert.match(page, /className=\{`usage-token-grid \$\{period\}`\}/);
  assert.match(page, /className="usage-token-months"[^>]*gridTemplateColumns: `repeat\(\$\{periodLabels\.length\}, minmax\(0, 1fr\)\)`/);
  assert.match(page, /const tokenScrollRef = useRef\(null\)/);
  assert.match(page, /tokenScrollRef\.current\.scrollLeft = tokenScrollRef\.current\.scrollWidth/);
  assert.match(page, /className="usage-token-scroll" ref=\{tokenScrollRef\}/);
  assert.match(page, /className="usage-token-tooltip"/);
  assert.match(page, /const selectedDay = selected \? periodDays\.find\(\(day\) => tokenSelectionKey\(day\) === selected\) : null/);
  assert.match(page, /const selectionKey = tokenSelectionKey\(day\)/);
  assert.match(page, /const selectable = period === "daily" \|\| day\.level > 0/);
  assert.match(page, /const periodColumnCount = Math\.ceil\(periodDays\.length \/ 7\)/);
  assert.match(page, /gridTemplateColumns: `repeat\(\$\{periodColumnCount\}, minmax\(8px, 16px\)\)`/);
  assert.match(page, /key=\{day\.key \?\? day\.date\}/);
  assert.match(page, /aria-pressed=\{selectable && selected === selectionKey\}/);
  assert.match(page, /aria-disabled=\{!selectable\}/);
  assert.match(page, /if \(!selectable\) return; setSelected\(selected === selectionKey \? null : selectionKey\)/);
  assert.match(page, /const key = day\.periodStart \?\? day\.date/);
  assert.match(page, /className=\{`usage-token-chart\$\{selectedDay \? " has-selection" : ""\}`\}/);
  assert.match(page, /className="usage-token-period"/);
  assert.match(page, /\["daily", t\("usage\.daily"\)\]/);
  assert.match(page, /\["weekly", t\("usage\.weekly"\)\]/);
  assert.match(page, /\["cumulative", t\("usage\.cumulative"\)\]/);
  assert.doesNotMatch(page, /\["monthly", t\("usage\.monthly"\)\]/);
  assert.match(page, /usage-token-cell--level-/);
  assert.match(page, /t\("usage\.dailyTokens"\)/);
  assert.doesNotMatch(page, /t\("usage\.lastThirtyDays"\)/);
  assert.match(page, /buildDailyTokenGrid\(entry\.tokenUsage\?\.dailyUsageBuckets, 182\)/);
  assert.match(page, /function AccountDetailCard/);
  assert.match(page, /function AccountTrendBlock/);
  assert.match(page, /className="usage-settings-card usage-account-detail"/);
  const accountCardSource = page.slice(page.indexOf("function AccountDetailCard"), page.indexOf("export function UsageSettingsPage"));
  assert.match(accountCardSource, /LimitRow[\s\S]*AccountTokenGrid[\s\S]*UsageTrendChart/);
  const settingsHeadingSource = page.slice(page.indexOf('className="usage-settings-heading"'), page.indexOf('className="usage-account-list"'));
  assert.doesNotMatch(settingsHeadingSource, /usage-range-control|usage-range-trigger/);
  assert.doesNotMatch(page, /className="settings-section usage-token-section"|className="settings-section usage-trend-section"/);
  assert.match(page, /t\("usage\.limitTrend"\)/);
  assert.match(page, /className="usage-trend-scale"/);
  assert.doesNotMatch(page, /className="usage-trend-explainer"|t\("usage\.trendExplainer"\)/);
  assert.match(page, /t\("usage\.fiveHourRemaining"\)/);
  assert.match(page, /t\("usage\.weeklyRemaining"\)/);
  assert.match(page, /useState\(0\.25\)/);
  assert.match(page, /useUsageOverview\(accounts, 30\)/);
  assert.match(page, /rangeOptions = \[\[0\.125, t\("usage\.threeHours"\)\], \[0\.25, t\("usage\.sixHours"\)\], \[0\.5, t\("usage\.twelveHours"\)\], \[1, t\("usage\.oneDay"\)\]/);
  assert.match(page, /function selectTrendDays\(value\) \{ setDays\(value\); setUntil\(null\); setRangeMenuOpen\(false\); \}/);
  assert.match(page, /className="usage-range-trigger"/);
  assert.match(page, /aria-expanded=\{rangeMenuOpen\}/);
  assert.match(page, /className="usage-range-menu" role="menu"/);
  assert.match(page, /function AccountTrendBlock[\s\S]*useState\(0\.25\)[\s\S]*useState\(null\)[\s\S]*usage-range-control/);
  assert.match(page, /role="menuitemradio"/);
  assert.match(page, /onPointerDown=\{handlePointerDown\}/);
  assert.match(page, /onPointerMove=\{handlePointerMove\}/);
  assert.doesNotMatch(page, /zoomTrendViewport|handleWheel|onWheel=|type: "pinch"/);
  assert.match(page, /const hasHistory = historyStart !== null/);
  assert.match(page, /className="usage-trend-no-data"/);
  assert.match(page, /t\("usage\.noDataInRange"\)/);
  assert.match(page, /buildTrendAxisTicks\(since, until\)/);
  assert.match(page, /style=\{\{ left: `\$\{position \* 100\}%` \}\}/);
  assert.doesNotMatch(page, /t\("usage\.now"\)/);
  assert.match(page, /hourCycle: "h23"/);
  assert.match(page, /kind="primary"/);
  assert.match(page, /kind="weekly"/);
  assert.doesNotMatch(page, /usage\.currentContext|formatContextUsage/);
  assert.match(page, /resetCreditsAvailable/);
  assert.match(page, /resetCredits/);
  assert.match(page, /expiresAt/);
  assert.match(page, /className="usage-credit-row"[\s\S]*t\("usage\.resetAvailableCount", \{ count: credits \?\? t\("usage\.unavailable"\) \}\)[\s\S]*className="usage-settings-action usage-credit-action"[\s\S]*<\/div>/);
  assert.match(page, /className="usage-settings-limit-meta"[\s\S]*usage-settings-limit-value[\s\S]*usage-settings-detail/);
  assert.doesNotMatch(page, /<UsageProgress[\s\S]*\{detail && <span className="usage-settings-detail"/);
  assert.match(page, /overview\.reload/);
  assert.match(page, /overview\.reset/);
  assert.match(page, /<ResetCreditDialog/);
  assert.doesNotMatch(page, /window\.(?:confirm|alert)/);
  assert.match(page, /role="progressbar"/);

  assert.match(css, /\.usage-settings-content\{[^}]*overflow:auto/s);
  assert.match(css, /\.usage-settings-card\{[^}]*border-radius:14px/s);
  assert.match(css, /\.usage-settings-action\{[^}]*min-height:48px/s);
  assert.match(css, /\.usage-settings-progress\{[^}]*overflow:hidden/s);
  assert.match(css, /\.usage-trend-chart\{[^}]*width:100%/s);
  assert.match(css, /\.usage-token-grid\{[^}]*grid-template-rows:repeat\(7,1fr\)[^}]*grid-template-columns:repeat\(26,minmax\(8px,16px\)\)[^}]*grid-auto-flow:column/s);
  assert.doesNotMatch(css, /\.usage-token-grid\.weekly,\.usage-token-grid\.monthly\{[^}]*grid-template-rows:1fr/s);
  assert.match(css, /\.usage-token-cell\{[^}]*width:100%[^}]*aspect-ratio:1[^}]*border-radius:3px/s);
  assert.match(css, /\.usage-token-cell\[aria-pressed="true"\]\{[^}]*outline:0[^}]*box-shadow:inset 0 0 0 2px/s);
  assert.match(css, /\.usage-token-scroll\{[^}]*overflow-x:auto[^}]*overscroll-behavior-inline:contain/s);
  assert.match(css, /@media\(max-width:640px\)\{\.usage-token-grid,\.usage-token-months\{[^}]*width:150%/s);
  assert.match(css, /\.usage-token-cell--level-4/);
  assert.match(css, /\.usage-account-card\{[^}]*display:grid/s);
  assert.match(css, /\.usage-weekly-summary-list\{[^}]*display:grid/s);
  assert.match(css, /\.usage-weekly-summary-card\{[^}]*grid-template-columns:minmax\(0,1fr\) auto/s);
  assert.match(css, /\.usage-weekly-summary-meta\{[^}]*display:flex[^}]*justify-content:flex-end/s);
  assert.match(css, /\.usage-weekly-summary-meta>span:last-child\{[^}]*overflow:hidden/s);
  assert.match(css, /\.usage-token-months\{[^}]*display:grid/s);
  assert.match(css, /\.usage-token-months span\{[^}]*text-align:center/s);
  assert.match(css, /\.usage-token-tooltip\{[^}]*position:absolute[^}]*top:0[^}]*right:0/s);
  assert.match(css, /\.usage-token-chart\.has-selection\{[^}]*padding-top:/s);
  assert.match(css, /\.usage-account-detail\{[^}]*display:grid/s);
  assert.match(css, /\.usage-sort-trigger,\.usage-sort-direction\{[^}]*width:40px[^}]*height:40px/s);
  assert.match(css, /\.usage-sort-trigger::before\{[^}]*mask-image:/s);
  assert.match(css, /\.usage-sort-actions\{[^}]*display:flex[^}]*align-items:center/s);
  assert.match(css, /\.usage-sort-trigger,\.usage-sort-direction\{[^}]*width:40px[^}]*height:40px/s);
  assert.match(css, /\.usage-sort-menu\{[^}]*position:absolute[^}]*right:0[^}]*border-radius:12px/s);
  assert.match(css, /\.usage-sort-menu button\{[^}]*min-height:48px/s);
  assert.match(css, /\.usage-trend-scale\{[^}]*display:flex/s);
  assert.match(css, /\.usage-range-trigger\{[^}]*width:40px[^}]*height:40px/s);
  assert.match(css, /\.usage-range-menu\{[^}]*position:absolute[^}]*right:0/s);
  assert.match(css, /\.usage-range-menu\{[^}]*top:calc\(100% \+ 8px\)[^}]*bottom:auto/s);
  assert.doesNotMatch(css, /\.usage-range-menu\{[^}]*bottom:calc\(100% \+ 8px\)/s);
  assert.match(css, /\.usage-trend-chart\{[^}]*touch-action:pan-y/s);
  assert.match(css, /\.usage-trend-no-data\{[^}]*pointer-events:none/s);
  assert.match(css, /\.usage-trend-axis\{[^}]*position:relative[^}]*height:14px/s);
  assert.match(css, /\.usage-credit-expiry\.warning/);
  assert.match(css, /\.usage-credit-action\{[^}]*min-height:36px[^}]*padding:0 10px[^}]*width:auto/s);
  assert.doesNotMatch(css, /@media\(max-width:640px\)\{\.usage-credit-action\{[^}]*min-height:48px/s);
  assert.match(css, /@media\(max-width:640px\)/s);
  assert.match(css, /@media\(max-width:640px\)\{\.usage-trend-range button\{[^}]*min-width:48px[^}]*min-height:48px/s);
  assert.match(css, /@media\(max-width:640px\)\{\.usage-sort-trigger,\.usage-sort-direction\{[^}]*width:48px[^}]*height:48px/s);
  assert.match(css, /html\[data-theme="light"\] \.app-shell \.usage-settings-limit\.usage-good \.usage-settings-limit-value\{[^}]*color:#1a7f37!important/s);
  assert.match(css, /html\[data-theme="light"\] \.app-shell \.usage-token-cell--level-4\{[^}]*background:#0969da!important/s);
  assert.match(css, /html\[data-theme="light"\] \.app-shell \.usage-sort-trigger,html\[data-theme="light"\] \.app-shell \.usage-sort-direction,html\[data-theme="light"\] \.app-shell \.usage-range-trigger\{[^}]*border:0!important[^}]*background:transparent!important[^}]*box-shadow:none!important/s);

  assert.match(messages, /"settings\.usage": "Usage"/);
  assert.match(messages, /"settings\.usage": "사용량"/);
  assert.match(messages, /"usage\.accountLimits"/);
  assert.doesNotMatch(messages, /"usage\.sortAvailability"/);
  assert.doesNotMatch(messages, /"usage\.sortPrimary": "Most 5h remaining"/);
  assert.doesNotMatch(messages, /"usage\.sortAvailability": "\\uC0AC\\uC6A9 \\uC5EC\\uC720 \\uB9CE\\uC740 \\uC21C"/);
  assert.match(messages, /"usage\.earliestExpiry"/);
  assert.match(messages, /"usage\.resetAvailableCount": "Can reset \{count\} times"/);
  assert.match(messages, /"usage\.resetAvailableCount": "\\uCD08\\uAE30\\uD654 \{count\}\\uD68C \\uAC00\\uB2A5"/);
  assert.match(messages, /"usage\.trendsTitle"/);
  assert.match(messages, /"usage\.dailyTokens": "Daily tokens"/);
  assert.match(messages, /"usage\.weeklySummary": "Weekly summary"/);
  assert.match(messages, /"usage\.cumulative": "Cumulative"/);
  assert.match(messages, /"usage\.cumulative": "\\uB204\\uC801"/);
  assert.match(messages, /"usage\.accountDetails": "Account details"/);
  assert.match(messages, /"usage\.lastThirtyDays": "Last 30 days"/);
  assert.match(messages, /"usage\.trendExplainer"/);
  assert.match(messages, /"usage\.fiveHourRemaining"/);
  assert.match(messages, /"usage\.oneDay": "1 day"/);
  assert.match(messages, /"usage\.threeHours": "3 hours"/);
  assert.match(messages, /"usage\.sixHours": "6 hours"/);
  assert.match(messages, /"usage\.twelveHours": "12 hours"/);
  assert.match(messages, /"usage\.threeDays": "3 days"/);
  assert.match(messages, /"usage\.chartGestures"/);
  assert.doesNotMatch(messages, /pinch or scroll|두 손가락 또는 휠/);
  assert.match(messages, /"usage\.noDataInRange"/);
  assert.match(messages, /"usage\.threeDays": "3\uC77C"/);
  assert.doesNotMatch(messages, /"usage\.currentContext"/);
});
