const fs = require('fs');
const path = require('path');
const root = __dirname;
const read = p => fs.readFileSync(path.join(root, p), 'utf8');
const users = read('users.php');
const equipment = read('equipment.php');
const exportPhp = read('equipment_export.php');
const funcs = read('app/functions.php');
const xlsx = read('app/xlsx.php');
const css = read('assets/css/style.css');
const js = read('assets/js/app.js');
const header = read('app/header.php');
let pass = 0, fail = 0;
function check(name, cond) {
  if (cond) { console.log('PASS', name); pass++; }
  else { console.error('FAIL', name); fail++; }
}

check('Users ostaje samo za sistemske administratore', /require_system_admin\(\)/.test(users));
check('Users koristi 10 korisnika po stranici', /\$userPageSize\s*=\s*10\s*;/.test(users));
check('Users koristi server-side COUNT', /SELECT COUNT\(\*\) FROM users u/.test(users));
check('Users SELECT ima LIMIT/OFFSET', /LIMIT '\s*\.\s*\$userPageSize\s*\.\s*' OFFSET '\s*\.\s*\$userOffset/.test(users));
check('Users search radi na serveru preko postojećih polja', /LOCATE\(\?, u\.name\)/.test(users) && /LOCATE\(\?, u\.email\)/.test(users) && /LOCATE\(\?, u\.department\)/.test(users) && /LOCATE\(\?, u\.location\)/.test(users));
check('Users search uključuje role bez JOIN duplikata', /EXISTS \([\s\S]*FROM user_roles ur_search/.test(users));
check('Client-side admin user filter je uklonjen', !/adminUserSearch/.test(js));
check('Users ima pagination UI', /aria-label="Paginacija korisnika"/.test(users) && /pagination_page_numbers/.test(users));
check('Postojeće user akcije ostaju prisutne', /name="action" value="create"/.test(users) && /name="action" value="update"/.test(users) && /name="action" value="delete_user"/.test(users) && />Profil<\/a>/.test(users));
check('New user card je lokalno poravnat bez sticky offseta', /\.user-admin-layout > \.admin-create-user-card\s*\{[^}]*position:\s*relative;[^}]*top:\s*auto;[^}]*align-self:\s*start;/s.test(css));
check('User admin se na manjim ekranima vraća u jednu kolonu', /@media \(max-width: 1180px\)[\s\S]*?\.user-admin-layout\s*\{[^}]*grid-template-columns:\s*1fr/s.test(css));
check('Pagination se na mobile slaže vertikalno', /@media \(max-width: 760px\)[\s\S]*?\.pagination\s*\{[^}]*flex-direction:\s*column/s.test(css));
check('Server search forma nema 560px vertikalni flex-basis kada toolbar pređe u kolonu', /@media \(max-width: 900px\)[\s\S]*?\.admin-users-toolbar \.admin-user-search-form\s*\{[^}]*flex:\s*0 0 auto/s.test(css));

check('Equipment koristi namensku permission granicu', /require_equipment_manager\(\)/.test(equipment) && /require_equipment_manager\(\)/.test(exportPhp));
check('Equipment nudi 10 25 50 po stranici', /\$equipmentPageSizes\s*=\s*\[10,\s*25,\s*50\]/.test(equipment));
check('Equipment koristi server-side COUNT/statistiku i LIMIT', /COUNT\(\*\) AS total/.test(equipment) && /LIMIT '\s*\.\s*\$equipmentPageSize\s*\.\s*' OFFSET '\s*\.\s*\$equipmentOffset/.test(equipment));
check('Glavni equipment filter tipovi su traženih 5 grupa', /'Laptop'\s*=>\s*'Laptop'[\s\S]*'Telefon'\s*=>\s*'Telefon'[\s\S]*'Monitor'\s*=>\s*'Monitor'[\s\S]*'Tablet'\s*=>\s*'Tablet'[\s\S]*'Ostalo'\s*=>\s*'Ostalo'/.test(funcs));
check('Ostalo obuhvata ne-glavne tipove bez gubitka detaljnog tipa', /e\.asset_type NOT IN \('Laptop', 'Telefon', 'Monitor', 'Tablet'\)/.test(funcs));
check('Equipment search i filter dele centralni scoped SQL helper', /equipment_filter_sql\(\$equipmentFilters, \$user\)/.test(equipment) && /equipment_filter_sql\(\$filters, \$user\)/.test(exportPhp));
check('Export ne prosleđuje page/per_page i zadržava ceo filtrirani skup', !/LIMIT/.test(exportPhp) && !/per_page/.test(exportPhp));
check('Equipment tabela prikazuje operativne detalje', /Korisnik<\/th>/.test(equipment) && /Identifikatori<\/th>/.test(equipment) && /Datum dodele<\/th>/.test(equipment) && /Ažurirano<\/th>/.test(equipment));
check('Equipment ima pagination UI', /aria-label="Paginacija opreme"/.test(equipment));
check('Postojeće equipment akcije ostaju prisutne', /value="create"/.test(equipment) && /value="update"/.test(equipment) && /value="delete"/.test(equipment));
check('Equipment filter na mobile ide u jednu kolonu', /@media \(max-width: 760px\)[\s\S]*?\.equipment-filter-form\s*\{[^}]*grid-template-columns:\s*1fr/s.test(css));
check('Equipment filter CTA ostaje kompaktan na phone breakpoint-u', /@media \(max-width: 640px\)[\s\S]*?\.equipment-filter-form \.inline-actions \.button\s*\{[^}]*flex:\s*0 0 auto;[^}]*min-height:\s*48px/s.test(css));
check('Equipment hero akcije ne nasleđuju globalni 180px inline-actions basis', equipment.includes('class="equipment-hero-actions"') && !/equipment-hero[\s\S]{0,500}class="inline-actions"/.test(equipment));
check('Equipment hero akcije koriste standardnu mobilnu visinu', /@media \(max-width: 760px\)[\s\S]*?\.equipment-hero-actions \.button\s*\{[^}]*width:\s*100%;[^}]*height:\s*auto;[^}]*min-height:\s*48px/s.test(css));
check('Table wrapper zadržava lokalni horizontalni scroll', /\.table-wrap\s*\{[^}]*overflow-x:\s*auto/s.test(css));

check('CSV export je uklonjen', !/text\/csv|fputcsv|\.csv/.test(exportPhp));
check('Export vraća pravi XLSX content type', /application\/vnd\.openxmlformats-officedocument\.spreadsheetml\.sheet/.test(exportPhp));
check('XLSX filename prati SOS-pregled-opreme format', /SOS-pregled-opreme-.*Ymd-Hi.*\.xlsx/.test(exportPhp));
check('XLSX ima oba tražena worksheet-a', /Pregled opreme/.test(xlsx) && /Sažetak/.test(xlsx));
check('XLSX ima pravno lice i tačan redosled 13 kolona', /\['Korisnik','Sektor','Lokacija','Pravno lice','Tip opreme','Naziv opreme','Inventarski broj','Serijski broj','Status','Datum dodele','Email','Napomena','Ažurirano'\]/.test(xlsx));
check('Inventarski i serijski broj idu kao tekst', /xlsx_cell_inline\('G'/.test(xlsx) && /xlsx_cell_inline\('H'/.test(xlsx));
check('Formula injection je neutralisana inlineStr ćelijama', /t="inlineStr"/.test(xlsx) && /begin with = \+ - @/.test(xlsx));
check('Sažetak je dinamički iz exportovanih redova', /\$typeCounts/.test(xlsx) && /\$statusCounts/.test(xlsx) && /\$locationCounts/.test(xlsx));
check('XLSX packaging koristi runtime ZIP podršku bez Composer zahteva', /ZipArchive/.test(xlsx) && /PharData/.test(xlsx));
check('Asset cache verzija je 3.25.0', (header.match(/\?v=3\.25\.0/g) || []).length >= 2);

console.log(`RESULT ${pass}/${pass + fail} PASS`);
process.exit(fail ? 1 : 0);
