import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
import { fileURLToPath } from 'node:url'

const documentsCenterView = readFileSync(
  fileURLToPath(new URL('../src/views/DocumentsCenterView.vue', import.meta.url)),
  'utf8'
)

const documentsCenterStyles = readFileSync(
  fileURLToPath(new URL('../src/assets/styles/views/documents-center-view.css', import.meta.url)),
  'utf8'
)

test('documents center keeps only the top scope tabs and renders status as a dropdown filter', () => {
  assert.match(documentsCenterView, /<nav class="status-tabs document-scope-tabs"/)
  assert.doesNotMatch(documentsCenterView, /<nav class="status-tabs document-state-tabs"/)
  assert.match(documentsCenterView, /class="document-status-filter"[\s\S]*class="document-filter status-dropdown-filter"/)
  assert.match(
    documentsCenterView,
    /<div class="filter-set">[\s\S]*<div class="list-search">[\s\S]*<div class="document-status-filter"[\s\S]*<div v-if="showDocumentTypeFilter" class="document-filter">/
  )
  assert.match(documentsCenterView, /v-for="option in statusFilterOptions"/)
  assert.match(documentsCenterView, /@click="selectStatusTab\(option\.value\)"/)
})

test('documents center top tabs start from all and show document category labels', () => {
  assert.match(documentsCenterView, /const DOCUMENT_SCOPE_ALL = '全部'/)
  assert.match(documentsCenterView, /const DOCUMENT_SCOPE_APPLICATION = '申请单'/)
  assert.match(documentsCenterView, /const DOCUMENT_SCOPE_REIMBURSEMENT = '报销单'/)
  assert.match(documentsCenterView, /const DOCUMENT_SCOPE_REVIEW = '审核单'/)
  assert.match(documentsCenterView, /const DOCUMENT_SCOPE_ARCHIVE = '归档'/)
  assert.match(documentsCenterView, /const activeScopeTab = ref\(readDocumentScope\(DOCUMENT_SCOPE_ALL, scopeTabs\)\)/)
  assert.match(
    documentsCenterView,
    /const scopeTabs = \[[\s\S]*DOCUMENT_SCOPE_ALL[\s\S]*DOCUMENT_SCOPE_APPLICATION[\s\S]*DOCUMENT_SCOPE_REIMBURSEMENT[\s\S]*DOCUMENT_SCOPE_REVIEW[\s\S]*DOCUMENT_SCOPE_ARCHIVE[\s\S]*\]/
  )
})

test('documents center category tabs map to the intended row sources', () => {
  assert.match(documentsCenterView, /excludeArchivedDocumentRows/)
  assert.match(documentsCenterView, /approvalRows\.value = excludeArchivedDocumentRows/)
  assert.match(documentsCenterView, /const nonArchivedRows = computed\(\(\) => mergeDocumentRows\(\[\.\.\.ownedRows\.value, \.\.\.approvalRows\.value\]\)\)/)
  assert.match(documentsCenterView, /activeScopeTab\.value !== DOCUMENT_SCOPE_ARCHIVE && isArchivedDocumentRow\(row\)/)
  assert.match(
    documentsCenterView,
    /activeScopeTab\.value === DOCUMENT_SCOPE_ALL[\s\S]*return nonArchivedRows\.value/
  )
  assert.match(
    documentsCenterView,
    /activeScopeTab\.value === DOCUMENT_SCOPE_APPLICATION[\s\S]*return applicationScopeRows\.value/
  )
  assert.match(
    documentsCenterView,
    /activeScopeTab\.value === DOCUMENT_SCOPE_REIMBURSEMENT[\s\S]*ownedRows\.value\.filter/
  )
  assert.match(
    documentsCenterView,
    /activeScopeTab\.value === DOCUMENT_SCOPE_REVIEW[\s\S]*return approvalRows\.value/
  )
  assert.match(
    documentsCenterView,
    /activeScopeTab\.value === DOCUMENT_SCOPE_ARCHIVE[\s\S]*return archiveRows\.value/
  )
  assert.match(documentsCenterView, /return nonArchivedRows\.value/)
})

test('documents center preserves application document type from mapped requests', () => {
  assert.match(
    documentsCenterView,
    /const documentTypeCode = normalized\.documentTypeCode \|\| DOCUMENT_TYPE_REIMBURSEMENT/
  )
  assert.match(
    documentsCenterView,
    /documentTypeCode === DOCUMENT_TYPE_APPLICATION \? '申请单' : '报销单'/
  )
  assert.doesNotMatch(
    documentsCenterView,
    /documentTypeCode:\s*DOCUMENT_TYPE_REIMBURSEMENT,[\s\S]*documentTypeLabel:\s*'报销单'/
  )
})

test('documents center list shows created time and conditional stay time columns', () => {
  assert.match(documentsCenterView, /import \{[\s\S]*formatDocumentListTime[\s\S]*resolveDocumentStayTimeDisplay[\s\S]*\} from '..\/utils\/documentCenterTime\.js'/)
  assert.match(documentsCenterView, /<col class="col-created">/)
  assert.match(documentsCenterView, /<col v-if="showStayTimeColumn" class="col-stay">/)
  assert.match(documentsCenterView, /<col class="col-initiator">/)
  assert.match(documentsCenterView, /<th>单号<\/th>[\s\S]*<th>创建时间<\/th>[\s\S]*<th v-if="showStayTimeColumn">停留时间<\/th>/)
  assert.match(documentsCenterView, /<th>费用场景<\/th>[\s\S]*<th>发起人<\/th>[\s\S]*<th>事项<\/th>/)
  assert.match(documentsCenterView, /<td>\{\{ row\.createdAtDisplay \}\}<\/td>/)
  assert.match(documentsCenterView, /<td v-if="showStayTimeColumn">\{\{ row\.stayTimeDisplay \}\}<\/td>/)
  assert.match(documentsCenterView, /<td>\{\{ row\.initiatorName \}\}<\/td>/)
  assert.match(
    documentsCenterView,
    /const showStayTimeColumn = computed\(\(\) =>[\s\S]*DOCUMENT_SCOPE_APPLICATION[\s\S]*DOCUMENT_SCOPE_REVIEW/
  )
  assert.match(documentsCenterView, /createdAtDisplay: formatDocumentListTime\(createdAtSource\)/)
  assert.match(documentsCenterView, /stayTimeDisplay: resolveDocumentStayTimeDisplay\(normalized\)/)
  assert.match(documentsCenterView, /initiatorName,/)
  assert.match(documentsCenterView, /row\.initiatorName/)
})

test('documents center action buttons are scoped to application and reimbursement tabs', () => {
  assert.match(
    documentsCenterView,
    /v-if="\[DOCUMENT_SCOPE_APPLICATION, DOCUMENT_SCOPE_REIMBURSEMENT\]\.includes\(activeScopeTab\)"[\s\S]*class="document-actions"/
  )
  assert.match(
    documentsCenterView,
    /v-if="activeScopeTab === DOCUMENT_SCOPE_APPLICATION"[\s\S]*@click="emit\('create-application'\)"[\s\S]*发起申请/
  )
  assert.match(
    documentsCenterView,
    /v-if="activeScopeTab === DOCUMENT_SCOPE_REIMBURSEMENT"[\s\S]*@click="emit\('create-request'\)"[\s\S]*发起报销/
  )
  assert.doesNotMatch(documentsCenterView, /create-request-btn secondary/)
})

test('documents center category tabs render bubble counts for new documents', () => {
  assert.match(documentsCenterView, /readViewedDocumentKeys/)
  assert.match(documentsCenterView, /const viewedDocumentKeys = ref\(readViewedDocumentKeys\(\)\)/)
  assert.match(documentsCenterView, /v-for="tab in scopeTabItems"/)
  assert.match(documentsCenterView, /<span v-if="tab\.badgeCount > 0" class="scope-tab-badge"/)
  assert.match(documentsCenterView, /tab\.badgeCount > 99 \? '99\+' : tab\.badgeCount/)
  assert.match(documentsCenterView, /const scopeNewCountMap = computed\(\(\) => \(\{/)
  assert.match(documentsCenterView, /\[DOCUMENT_SCOPE_ALL\]: countNewDocuments\(nonArchivedRows\.value, viewedDocumentKeys\.value\)/)
  assert.match(
    documentsCenterView,
    /const applicationScopeRows = computed\(\(\) => prepareApplicationScopeRows\(ownedRows\.value\)\)/
  )
  assert.match(
    documentsCenterView,
    /\[DOCUMENT_SCOPE_APPLICATION\]: countNewDocuments\(filterApplicationScopeNewRows\(applicationScopeRows\.value\), viewedDocumentKeys\.value\)/
  )
  assert.match(
    documentsCenterView,
    /\[DOCUMENT_SCOPE_REIMBURSEMENT\]: countNewDocuments\(ownedRows\.value\.filter\(\(row\) => row\.documentTypeCode === DOCUMENT_TYPE_REIMBURSEMENT\), viewedDocumentKeys\.value\)/
  )
  assert.match(documentsCenterView, /\[DOCUMENT_SCOPE_REVIEW\]: countNewDocuments\(approvalRows\.value, viewedDocumentKeys\.value\)/)
  assert.match(documentsCenterView, /\[DOCUMENT_SCOPE_ARCHIVE\]: countNewDocuments\(archiveRows\.value, viewedDocumentKeys\.value\)/)
  assert.match(
    documentsCenterView,
    /const scopeTabItems = computed\(\(\) =>[\s\S]*badgeCount: scopeNewCountMap\.value\[tab\] \|\| 0/
  )
})

test('documents center rows show NEW marker until the row is opened', () => {
  assert.match(documentsCenterView, /<span v-if="row\.isNewDocument" class="new-document-badge">NEW<\/span>/)
  assert.match(documentsCenterView, /isNewDocument: isNewDocument\(/)
  assert.match(
    documentsCenterView,
    /function openDocument\(row\) \{[\s\S]*writeDocumentScope\(activeScopeTab\.value, scopeTabs\)[\s\S]*viewedDocumentKeys\.value = markDocumentViewed\(row, viewedDocumentKeys\.value\)[\s\S]*emit\('open-document', row\.rawRequest \|\| row\)/
  )
  assert.match(documentsCenterStyles, /\.new-document-badge\s*\{[\s\S]*background:\s*#fff5f5;/)
  assert.match(documentsCenterStyles, /\.new-document-badge\s*\{[\s\S]*border:\s*1px solid #fecaca;/)
  assert.match(documentsCenterStyles, /\.new-document-badge::before\s*\{[\s\S]*background:\s*#ef4444;/)
  assert.doesNotMatch(documentsCenterStyles, /newDocumentPulse/)
})

test('documents center empty states follow theme tone across all scope tabs', () => {
  const emptyStateBlock = documentsCenterView.match(/const emptyState = computed\(\(\) => \{[\s\S]*?\n\}\)/)?.[0] || ''

  assert.match(emptyStateBlock, /eyebrow: '申请单'[\s\S]*tone: 'theme'/)
  assert.match(emptyStateBlock, /title: filtered \? '没有符合当前条件的单据'[\s\S]*tone: 'theme'/)
  assert.doesNotMatch(emptyStateBlock, /tone:\s*'emerald'/)
  assert.doesNotMatch(emptyStateBlock, /tone:\s*'sky'/)
  assert.doesNotMatch(emptyStateBlock, /tone:\s*'slate'/)
  assert.doesNotMatch(emptyStateBlock, /tone:\s*'amber'/)
})

test('documents center empty states do not render small action buttons', () => {
  const emptyStateBlock = documentsCenterView.match(/const emptyState = computed\(\(\) => \{[\s\S]*?\n\}\)/)?.[0] || ''

  assert.match(emptyStateBlock, /actionLabel:\s*''/)
  assert.match(emptyStateBlock, /actionIcon:\s*''/)
  assert.doesNotMatch(emptyStateBlock, /actionLabel:\s*filtered/)
  assert.doesNotMatch(emptyStateBlock, /actionIcon:\s*filtered/)
  assert.doesNotMatch(emptyStateBlock, /actionLabel:\s*'发起申请'/)
  assert.doesNotMatch(emptyStateBlock, /actionLabel:\s*'发起报销'/)
  assert.doesNotMatch(emptyStateBlock, /actionLabel:\s*'清空筛选'/)
})

test('documents center switches filter conditions by category tab', () => {
  assert.match(documentsCenterView, /const FILTER_CONFIG_BY_SCOPE = \{/)
  assert.match(
    documentsCenterView,
    /\[DOCUMENT_SCOPE_ALL\]: \{[\s\S]*sceneFallbackLabel: '单据场景'[\s\S]*statusTitle: '单据状态'[\s\S]*showDocumentType: true/
  )
  assert.match(
    documentsCenterView,
    /\[DOCUMENT_SCOPE_APPLICATION\]: \{[\s\S]*sceneFallbackLabel: '申请场景'[\s\S]*statusTitle: '申请状态'[\s\S]*showDocumentType: false/
  )
  assert.match(
    documentsCenterView,
    /\[DOCUMENT_SCOPE_REIMBURSEMENT\]: \{[\s\S]*statusTitle: '报销状态'[\s\S]*showDocumentType: false/
  )
  assert.match(
    documentsCenterView,
    /\[DOCUMENT_SCOPE_REVIEW\]: \{[\s\S]*sceneFallbackLabel: '审核场景'[\s\S]*statusTitle: '审核状态'[\s\S]*statusTabs: \['全部', '审批中', '待补充', '已完成'\]/
  )
  assert.match(
    documentsCenterView,
    /\[DOCUMENT_SCOPE_ARCHIVE\]: \{[\s\S]*dateLabel: '归档时间'[\s\S]*statusTitle: '归档状态'[\s\S]*statusTabs: \['全部', '已付款', '已完成'\]/
  )
  assert.match(documentsCenterView, /v-if="showDocumentTypeFilter" class="document-filter"/)
  assert.match(documentsCenterView, /:placeholder="activeFilterConfig\.searchPlaceholder"/)
  assert.match(documentsCenterView, /class="document-status-filter" :aria-label="activeFilterConfig\.statusTitle"/)
  assert.doesNotMatch(documentsCenterView, /class="status-filter-label"/)
  assert.match(
    documentsCenterView,
    /watch\(activeFilterConfig, \(\) => \{[\s\S]*openFilterKey\.value = ''[\s\S]*datePopover\.value = false/
  )
  assert.match(documentsCenterView, /<EnterpriseSelect v-model="pageSize"[\s\S]*:options="pageSizeOptions"/)
  assert.doesNotMatch(documentsCenterView, /pageSizeOpen/)
})

test('documents center status dropdown derives labels and closes after selection', () => {
  assert.match(documentsCenterView, /const statusFilterOptions = computed\(\(\) =>/)
  assert.match(documentsCenterView, /activeFilterConfig\.value\.statusTabs\.map/)
  assert.match(documentsCenterView, /label: tab === '全部' \? '全部状态' : tab/)
  assert.match(documentsCenterView, /const statusFilterLabel = computed\(\(\) =>/)
  assert.match(
    documentsCenterView,
    /function selectStatusTab\(value\) \{[\s\S]*activeStatusTab\.value = value[\s\S]*openFilterKey\.value = ''[\s\S]*\}/
  )
})

test('documents center status dropdown uses compact filter styling', () => {
  assert.match(documentsCenterStyles, /\.documents-list\s*\{[\s\S]*grid-template-rows:\s*auto auto minmax\(0,\s*1fr\) auto;/)
  assert.match(documentsCenterStyles, /\.status-tabs button\s*\{[\s\S]*display:\s*inline-flex;/)
  assert.match(documentsCenterStyles, /\.scope-tab-badge\s*\{[\s\S]*border-radius:\s*999px;/)
  assert.match(documentsCenterStyles, /min-width:\s*1420px;/)
  assert.match(documentsCenterStyles, /\.col-created\s*\{\s*width:\s*10%;\s*\}/)
  assert.match(documentsCenterStyles, /\.col-stay\s*\{\s*width:\s*9%;\s*\}/)
  assert.match(documentsCenterStyles, /\.col-initiator\s*\{\s*width:\s*8%;\s*\}/)
  assert.match(documentsCenterStyles, /\.document-status-filter\s*\{[\s\S]*display:\s*inline-flex;/)
  assert.match(documentsCenterStyles, /\.document-status-filter\s*\{[\s\S]*min-height:\s*38px;/)
  assert.match(documentsCenterStyles, /\.status-filter-trigger\s*\{[\s\S]*min-width:\s*154px;/)
  assert.match(documentsCenterStyles, /\.status-filter-menu\s*\{[\s\S]*min-width:\s*154px;/)
  assert.doesNotMatch(documentsCenterStyles, /\.document-state-tabs\s*\{/)
  assert.doesNotMatch(documentsCenterStyles, /\.document-status-filter\s*\{[^}]*margin-top:/)
})
