'use strict';

const fs = require('fs');
const path = require('path');
const root = __dirname;
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
const files = {
  functions: read('app/functions.php'),
  create: read('ticket_create.php'),
  view: read('ticket_view.php'),
  settings: read('ticket_settings.php'),
  users: read('users.php'),
  register: read('register.php'),
  header: read('app/header.php'),
  css: read('assets/css/style.css'),
  migration: read('upgrade_v3_22_0.sql'),
};

let passed = 0;
let failed = 0;
function check(label, condition) {
  if (condition) {
    passed++;
    console.log(`PASS | ${label}`);
  } else {
    failed++;
    console.log(`FAIL | ${label}`);
  }
}

const allRoles = ['USERF','USERDS','OFCF','OFCDS','VHCF','VHCDS','ICTF','ICTDS','OTHF','OTHDS'];
const dsRoles = ['USERDS','OFCDS','VHCDS','ICTDS','OTHDS'];

check('Migracija obuhvata svih 10 F/DS role kodova', allRoles.every((role) => files.migration.includes(`'${role}'`)));
check('Migracija dodaje svih pet DS rola idempotentno', dsRoles.every((role) => new RegExp(`WHERE NOT EXISTS \\(SELECT 1 FROM roles WHERE role_code = '${role}'\\)`).test(files.migration)));
check('Migracija ne menja SQL šemu', !/\bALTER\s+TABLE\b/i.test(files.migration) && !/\bCREATE\s+TABLE\b/i.test(files.migration));
check('Migracija ne menja user_roles niti tickets podatke', !/\b(?:INSERT|UPDATE|DELETE)\s+(?:INTO\s+|FROM\s+)?user_roles\b/i.test(files.migration) && !/\b(?:INSERT|UPDATE|DELETE)\s+(?:INTO\s+|FROM\s+)?tickets\b/i.test(files.migration));
check('Postojeći F role kodovi se ne preimenuju', ['USERF','OFCF','VHCF','ICTF','OTHF'].every((role) => new RegExp(`WHERE role_code = '${role}'`).test(files.migration)));

check('Organizacione jedinice su centralizovane u helper-u', /function organization_unit_definitions\(\): array[\s\S]*'F'\s*=>\s*'Fondacija'[\s\S]*'DS'\s*=>\s*'Dečije selo'/.test(files.functions));
check('Obe osnovne korisničke role su centralizovane', /function base_user_role_codes\(\): array[\s\S]*USERF[\s\S]*USERDS/.test(files.functions));
check('Postoji centralno mapiranje role na organizacionu jedinicu', /function role_organization_unit/.test(files.functions) && /function role_code_for_unit/.test(files.functions));
check('Nije uvedena organization_unit DB kolona kroz migraciju', !/\borganization_unit\b/i.test(files.migration));
check('Category routing bira F/DS varijantu na backendu', /function category_responsible_role_code\(string \$category, string \$organizationUnit = 'F'\)[\s\S]*role_code_for_unit\(\$canonicalRoleCode, \$organizationUnit\)/.test(files.functions));
check('Kreiranje tiketa određuje jedinicu iz prijavljenog korisnika', /user_organization_unit\(\$user\)/.test(files.create));
check('Kreiranje tiketa prosleđuje jedinicu category resolver-u', /category_responsible_role_code\(\$category, \$ticketOrganizationUnit\)/.test(files.create));
check('Izmena tiketa čuva postojeću organizacionu jedinicu', /ticket_organization_unit\(\$ticket\)/.test(files.view) && /category_responsible_role_code\(\$newCategory, \$ticketOrganizationUnit\)/.test(files.view));
check('Ticket queue koristi exact role_code poređenje', /r_assigned\.role_code = t\.responsible_role_code/.test(files.functions));
check('Detalj tiketa koristi exact user_has_role proveru', /user_has_role\(\$user, \(string\)\(\$ticket\['responsible_role_code'\]/.test(files.functions));
check('Eligible assignee koristi exact role_code', /function eligible_assignees[\s\S]*r\.role_code = \?/.test(files.functions));
check('Notifikacije odgovornoj ulozi koriste exact role_code', /function notify_responsible_role[\s\S]*r\.role_code = \?/.test(files.functions));

check('Admin backend odbija istovremeni USERF i USERDS', (files.users.match(/count\(\$selectedBaseRoles\) > 1/g) || []).length >= 2);
check('Centralni sync_user_roles takođe odbija dve osnovne role', /function sync_user_roles[\s\S]*count\(\$selectedBaseRoles\) > 1[\s\S]*InvalidArgumentException/.test(files.functions));
check('Create forma čuva izabranu F/DS rolu nakon validacione greške', /\$createRoleCodes = \['USERF'\][\s\S]*safe_checked\(in_array\(\$roleCode, \$createRoleCodes, true\)\)/.test(files.users));
check('Admin dropdown ostaje dinamički vezan za roles tabelu', /foreach \(business_role_definitions\(\) as \$roleCode => \$roleName\)/.test(files.users));
check('Registracija dozvoljava samo jednu od dve osnovne role', /in_array\(\$registeredRole, base_user_role_codes\(\), true\)/.test(files.register));
check('Assigned SQL isključuje USERF i USERDS iz processing rola', /r_assigned\.role_code NOT IN/.test(files.functions) && /base_user_role_codes\(\)/.test(files.functions));

check('Podešavanje kategorije čuva kanonsku funkcionalnu rolu', /category_processing_role_codes\(\)/.test(files.settings) && /role_code_for_unit[\s\S]*'F'/.test(files.settings));
check('Masovna promena kategorije obrađuje svaku organizacionu jedinicu posebno', /foreach \(array_keys\(organization_unit_definitions\(\)\) as \$organizationUnit\)/.test(files.settings));
check('Masovna promena role ažurira samo tikete sa tačnim starim role kodom', /WHERE category = \? AND responsible_role_code = \?/.test(files.settings));
check('Audit promene odgovorne role čuva stvarne F/DS kodove', /responsible_role_changed[\s\S]*\$oldRoleForUnit[\s\S]*\$newRoleForUnit/.test(files.settings));
check('Audit formatter koristi user-friendly role_label', /responsible_role_changed[\s\S]*role_label\(\$value\)/.test(files.functions));

check('Evidencija ima lokalnu karticu za layout korekciju', files.view.includes('class="card ticket-evidence-card"'));
check('Desktop ticket-layout koristi stretch', /@media \(min-width:\s*1161px\)[\s\S]*?\.ticket-layout\s*\{[^}]*align-items:\s*stretch/s.test(files.css));
check('Desktop side-stack je vertikalni flex sa content-driven minimalnom visinom', /\.ticket-layout > \.side-stack\s*\{[^}]*display:\s*flex[^}]*flex-direction:\s*column[^}]*min-height:\s*min-content/s.test(files.css));
check('Evidence card koristi preostali prostor bez nultog basis-a i clipping-a', /\.ticket-layout > \.side-stack > \.ticket-evidence-card\s*\{[^}]*display:\s*flex[^}]*flex:\s*1 1 auto/s.test(files.css) && !/ticket-evidence-card[^}]*overflow:\s*hidden/s.test(files.css));
check('Timeline na desktopu koristi interni scroll i content-driven redove', /\.ticket-evidence-card \.ticket-events-timeline\s*\{[^}]*flex:\s*1 1 auto[^}]*max-height:\s*518px[^}]*overflow-y:\s*auto[^}]*align-content:\s*start/s.test(files.css));
check('Tablet/mobile breakpoint ostaje prirodan ispod 1161px', /@media \(max-width:\s*1160px\)[\s\S]*\.ticket-layout, \.user-layout\s*\{\s*grid-template-columns:\s*1fr/.test(files.css));
check('Asset cache verzija je 3.25.0', (files.header.match(/\?v=3\.25\.0/g) || []).length >= 2);

const opens = (files.css.match(/\{/g) || []).length;
const closes = (files.css.match(/\}/g) || []).length;
check('CSS vitičaste zagrade su izbalansirane', opens === closes);

console.log(`\nRezultat: ${passed}/${passed + failed} provera uspešno.`);
process.exit(failed === 0 ? 0 : 1);
