import test from 'node:test'
import assert from 'node:assert/strict'
import { existsSync, readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { dirname, resolve } from 'node:path'

const currentDir = dirname(fileURLToPath(import.meta.url))
const srcDir = resolve(currentDir, '..')

function readSource(relativePath) {
  return readFileSync(resolve(srcDir, relativePath), 'utf8')
}

function cssBlock(source, selector, offset = 0) {
  const start = source.indexOf(`${selector} {`, offset)
  assert.notEqual(start, -1)
  const end = source.indexOf('\n}', start)
  assert.notEqual(end, -1)
  return source.slice(start, end)
}

test('router exposes standalone page designer route', () => {
  const routerSource = readSource('router/index.js')

  assert.equal(routerSource.includes("import PageDesignerView from '@/views/PageDesignerView.vue'"), true)
  assert.equal(routerSource.includes("path: '/project/:projectId/page-designer'"), true)
  assert.equal(routerSource.includes("name: 'page-designer'"), true)
  assert.equal(routerSource.includes('component: PageDesignerView'), true)
})

test('standalone page designer wraps the focused designer component', () => {
  assert.equal(existsSync(resolve(srcDir, 'views/PageDesignerView.vue')), true)
  const source = readSource('views/PageDesignerView.vue')

  assert.equal(source.includes("import FrontendPageDesigner from '@/components/FrontendPageDesigner.vue'"), true)
  assert.equal(source.includes('<FrontendPageDesigner'), true)
  assert.equal(source.includes(':show-header="false"'), true)
  assert.equal(source.includes('designer-shell-page'), true)
  assert.equal(source.includes('designer-topbar'), true)
  assert.equal(source.includes('保存设计'), true)
  assert.equal(source.includes('返回工作台'), true)
  assert.equal(source.includes('预览页面'), true)
})

test('standalone page designer does not trap sticky designer sidebars', () => {
  const source = readSource('views/PageDesignerView.vue')
  const sharedCardStyleStart = source.indexOf('.designer-card {')
  const cardStyle = cssBlock(source, '.designer-card', sharedCardStyleStart + 1)

  assert.equal(cardStyle.includes('overflow: hidden'), false)
  assert.equal(cardStyle.includes('overflow: visible'), true)
})

test('standalone page designer loads scope-specific designs and business blocks', () => {
  const source = readSource('views/PageDesignerView.vue')
  const apiSource = readSource('api/project.js')

  assert.equal(source.includes('const scope = computed'), true)
  assert.equal(source.includes("route.query.scope === 'admin'"), true)
  assert.equal(source.includes('listPageDesigns(projectId.value, scope.value)'), true)
  assert.equal(source.includes('listBusinessBlocks(projectId.value, scope.value)'), true)
  assert.equal(source.includes(':block-definitions="businessBlockDefinitions"'), true)
  assert.equal(source.includes("scope === 'frontend' ? businessBlockDefinitions : []"), false)
  assert.equal(apiSource.includes("export function listBusinessBlocks(projectId, scope = 'frontend')"), true)
  assert.equal(apiSource.includes('params: { scope }'), true)
  assert.equal(source.includes('initPageDesigns(projectId.value, scope.value)'), true)
  assert.equal(source.includes('createPageDesign(projectId.value, design, scope.value)'), true)
  assert.equal(source.includes('savePageDesign(projectId.value, design.designId, design, scope.value)'), true)
  assert.equal(source.includes('deletePageDesign(projectId.value, design.designId, scope.value)'), true)
})

test('standalone page designer guards dirty local edits across scope route changes', () => {
  const source = readSource('views/PageDesignerView.vue')

  assert.equal(source.includes('@dirty-change="handleDirtyChange"'), true)
  assert.equal(source.includes('function handleDirtyChange'), true)
  assert.equal(source.includes('onBeforeRouteUpdate'), true)
  assert.equal(source.includes('return confirmLeaveDirty()'), true)
})

test('frontend page designer can hide its internal header when hosted by standalone page', () => {
  const source = readSource('components/FrontendPageDesigner.vue')

  assert.equal(source.includes('showHeader: { type: Boolean, default: true }'), true)
  assert.equal(source.includes('v-if="showHeader"'), true)
})
