import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const root = join(dirname(fileURLToPath(import.meta.url)), '..');
const read = rel => readFileSync(join(root, rel), 'utf8');
const assert = (condition, message) => { if (!condition) throw new Error(message); };
const pkg = JSON.parse(read('package.json'));
const lock = JSON.parse(read('package-lock.json'));
const index = read('public/index.html');
const app = read('public/app.js');
const css = read('public/style.css');
const server = read('server.mjs');
const db = read('lib/db.mjs');
const fees = read('lib/fees.mjs');
const icons = read('public/vendoo-icons.js');
const setup = read('setup.ps1');

assert(pkg.version === '1.26.0', 'Paketversion ist nicht 1.26.0.');
assert(lock.version === '1.26.0' && lock.packages?.['']?.version === '1.26.0', 'Lockfile-Version ist nicht 1.26.0.');
assert(index.includes('name="vendoo-build" content="1.26.0"'), 'Build-Metadatum fehlt.');
assert(index.includes('style.css?v=1.26.0'), 'CSS-Cache-Buster fehlt.');
assert(index.includes('vendoo-icons.js?v=1.26.0'), 'Iconbibliothek ist nicht eingebunden.');
assert(index.includes('app.js?v=1.26.0'), 'JS-Cache-Buster fehlt.');
assert(app.includes("VENDOO_UI_BUILD = '1.26.0'"), 'UI-Buildkennung fehlt.');
assert(setup.includes('/?build=1.26.0'), 'Windows-Start-Cache-Buster fehlt.');

const dashboardPos = index.indexOf('data-tab="dashboard"');
const newArticlePos = index.indexOf('data-tab="generator"');
const todayPos = index.indexOf('data-tab="today"');
assert(dashboardPos >= 0 && newArticlePos > dashboardPos && newArticlePos < todayPos, 'Neuer Artikel steht nicht direkt unter Dashboard.');
assert(index.includes('<span>Neuer Artikel</span>'), 'Navigationsbezeichnung Neuer Artikel fehlt.');
assert(index.includes('<span>Artikel</span>'), 'Navigationsbezeichnung Artikel fehlt.');
assert(index.includes('Artikel generieren'), 'Artikel-generieren-Bezeichnung fehlt.');
assert(!index.includes('>Neues Listing<'), 'Alte UI-Bezeichnung Neues Listing ist noch vorhanden.');
assert(!index.includes('>Listing generieren<'), 'Alte UI-Bezeichnung Listing generieren ist noch vorhanden.');

assert(index.includes('id="extensions"'), 'Extension Center fehlt.');
assert(index.includes('id="extensions-prepare-active"'), 'Ein-Klick-Vorbereitung für aktiven Browser fehlt.');
assert(app.includes('detectActiveBrowser'), 'Browsererkennung fehlt.');
assert(server.includes("app.get('/api/extensions/info'"), 'Extension-Info-Route fehlt.');
assert(server.includes("app.post('/api/extensions/prepare'"), 'Extension-Prepare-Route fehlt.');
assert(server.includes("app.get('/api/extensions/download/:browser'"), 'Extension-Download-Route fehlt.');
for (const browser of ['chrome', 'edge', 'firefox', 'safari']) {
  assert(existsSync(join(root, 'extensions', browser)), `Extension-Ordner ${browser} fehlt.`);
  assert(existsSync(join(root, 'extensions', 'packages', `vendoo-link-${browser}-1.7.0.zip`)), `Extension-Paket ${browser} fehlt.`);
}
assert(existsSync(join(root, 'extensions', 'safari', 'web-extension', 'manifest.json')), 'Safari-WebExtension-Manifest fehlt.');
assert(existsSync(join(root, 'extensions', 'safari', 'build-safari-extension.command')), 'Safari-Konvertierungsskript fehlt.');

for (const id of ['media-zoom-in','media-zoom-out','media-zoom-fit','media-zoom-original','media-zoom-range','media-lightbox-stage']) {
  assert(index.includes(`id="${id}"`), `Zoom-Steuerung ${id} fehlt.`);
}
assert(app.includes('function fitMediaLightbox'), 'Fit-Zoom fehlt.');
assert(app.includes("zoomStage?.addEventListener('wheel'"), 'Mausrad-Zoom fehlt.');
assert(app.includes("zoomStage?.addEventListener('pointerdown'"), 'Zoom-Panning fehlt.');
assert(icons.includes("'heart-filled'"), 'Favoriten-Icon fehlt.');
assert(icons.includes('check:'), 'Auswahl-Icon fehlt.');

assert(db.includes('function parseJsonArray(value)'), 'Robuster JSON-Array-Parser fehlt.');
assert(db.includes("String(value).split(',')"), 'Fallback für ältere Artikeldaten fehlt.');
assert(app.includes('const workspace = document.getElementById(\'publish-workspace\')'), 'Publish-Workspace-Container fehlt.');
assert(!app.includes('scope.querySelector(\'[data-publish-direct]'), 'Alter Publish-Scope-Fehler ist noch vorhanden.');
assert(app.includes('openSmartCopyModal(selectedPublishListing())'), 'Smart-Copy-Popup-Verknüpfung fehlt.');
assert(app.includes('smart-copy-center-description'), 'Zentrale Smart-Copy-Datenansicht fehlt.');

assert(fees.includes("'ebay-de':") && fees.includes("fees: 0"), 'eBay-Privatgebühr ist nicht auf 0 gesetzt.');
assert(fees.includes("vinted:") && fees.includes('Käuferschutz'), 'Vinted-Gebührenhinweis fehlt.');
assert(fees.includes("'ebay-ka':") && fees.includes('normalen Privatverkauf'), 'Kleinanzeigen-Hinweis fehlt.');
assert(fees.includes('gross * 0.065') && fees.includes('gross * 0.04 + 0.30'), 'Etsy-Kalkulation fehlt.');
assert(index.includes('Stand 08.07.2026'), 'Gebührenstand fehlt.');

const ids = [...index.matchAll(/\bid="([^"]+)"/g)].map(match => match[1]);
const duplicates = [...new Set(ids.filter((id, i) => ids.indexOf(id) !== i))];
assert(!duplicates.length, `Doppelte HTML-IDs: ${duplicates.join(', ')}`);
let depth = 0;
for (const char of css.replace(/\/\*[\s\S]*?\*\//g, '')) {
  if (char === '{') depth++;
  if (char === '}') depth--;
  assert(depth >= 0, 'CSS enthält eine vorzeitig geschlossene Klammer.');
}
assert(depth === 0, 'CSS-Klammern sind nicht ausgeglichen.');

const result = {
  release: '1.26.0',
  html_ids: ids.length,
  extension_targets: 4,
  checks: [
    'version-and-cache-busting', 'article-navigation', 'publish-hardening',
    'smart-copy-modal', 'media-zoom', 'local-icon-library', 'fee-model',
    'extension-center', 'safari-source', 'unique-html-ids', 'balanced-css'
  ]
};
console.log(JSON.stringify(result, null, 2));
