<?php
declare(strict_types=1);
namespace App\Services;
use App\Core\Database;
final class AuditComplianceService
{
 public function dashboard():array{$pdo=Database::connection();$latest=$pdo->query("SELECT id,score,status,summary,created_at FROM system_compliance_audits ORDER BY id DESC LIMIT 1")->fetch()?:['score'=>0,'status'=>'never','summary'=>'Aucun audit exécuté.','created_at'=>null];$checks=$pdo->query("SELECT framework,control_code,title,status,severity,details,checked_at FROM system_compliance_findings ORDER BY checked_at DESC,id DESC LIMIT 100")->fetchAll()?:[];$trail=$pdo->query("SELECT event_type,subject_type,subject_ref,actor_id,details,created_at FROM system_audit_trail ORDER BY created_at DESC,id DESC LIMIT 100")->fetchAll()?:[];return compact('latest','checks','trail');}
 public function runAudit():void{$pdo=Database::connection();$pdo->beginTransaction();try{$checks=[];$checks[]=$this->check($pdo,'RGPD','RGPD-01','Traçabilité des opérations sensibles',$this->table($pdo,'system_audit_trail'),'high','Le journal d’audit natif doit être disponible.');$checks[]=$this->check($pdo,'ISO27001','A.8.15','Journalisation des événements',$this->table($pdo,'system_security_events'),'high','Le journal des événements de sécurité doit être disponible.');$checks[]=$this->check($pdo,'NIS2','NIS2-21','Gestion des incidents',$this->table($pdo,'system_security_incidents'),'critical','Le registre des incidents doit être disponible.');$checks[]=$this->check($pdo,'ISO27001','A.8.13','Sauvegardes',((int)$pdo->query("SELECT COUNT(*) FROM cda_backup_jobs WHERE statut='succes'")->fetchColumn())>0,'high','Au moins une sauvegarde réussie doit exister.');$checks[]=$this->check($pdo,'NIS2','NIS2-21.2','Mises à jour signées',((int)$pdo->query("SELECT COUNT(*) FROM cda_update_packages WHERE statut='installe'")->fetchColumn())>0,'high','Les mises à jour doivent être tracées par le centre natif.');$checks[]=$this->check($pdo,'ZERO_TRUST','ZT-01','Politiques Zero Trust',((int)$pdo->query("SELECT COUNT(*) FROM system_zero_trust_policies WHERE enabled=1")->fetchColumn())>0,'medium','Au moins une politique Zero Trust active est attendue.');$passed=count(array_filter($checks,fn($x)=>$x));$score=(int)round($passed/max(1,count($checks))*100);$status=$score>=90?'compliant':($score>=70?'warning':'non_compliant');$s=$pdo->prepare("INSERT INTO system_compliance_audits(score,status,summary,created_at) VALUES(:score,:status,:summary,NOW())");$s->execute(['score'=>$score,'status'=>$status,'summary'=>$passed.'/'.count($checks).' contrôles conformes.']);$this->log($pdo,'compliance.audit','system','audit-'.$pdo->lastInsertId(),null,'Audit de conformité exécuté : '.$score.'/100');$pdo->commit();}catch(\Throwable $e){$pdo->rollBack();throw $e;}}
 private function check($pdo,string $framework,string $code,string $title,bool $ok,string $severity,string $details):bool{$s=$pdo->prepare("INSERT INTO system_compliance_findings(framework,control_code,title,status,severity,details,checked_at) VALUES(:framework,:code,:title,:status,:severity,:details,NOW())");$s->execute(['framework'=>$framework,'code'=>$code,'title'=>$title,'status'=>$ok?'pass':'fail','severity'=>$severity,'details'=>$details]);return $ok;}
 private function table($pdo,string $name):bool{$s=$pdo->prepare("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name=:name");$s->execute(['name'=>$name]);return (int)$s->fetchColumn()>0;}
 private function log($pdo,string $event,string $type,string $ref,?int $actor,string $details):void{$s=$pdo->prepare("INSERT INTO system_audit_trail(event_type,subject_type,subject_ref,actor_id,details,hash_prev,hash_current,created_at) VALUES(:event,:type,:ref,:actor,:details,NULL,:hash,NOW())");$s->execute(['event'=>$event,'type'=>$type,'ref'=>$ref,'actor'=>$actor,'details'=>$details,'hash'=>hash('sha256',$event.'|'.$type.'|'.$ref.'|'.$details.'|'.date('c'))]);}
 public function exportCsv():void{$rows=Database::connection()->query("SELECT framework,control_code,title,status,severity,details,checked_at FROM system_compliance_findings ORDER BY checked_at DESC,id DESC LIMIT 5000")->fetchAll()?:[];header('Content-Type: text/csv; charset=UTF-8');header('Content-Disposition: attachment; filename=axiom-compliance-'.date('Ymd-His').'.csv');$o=fopen('php://output','wb');fwrite($o,"\xEF\xBB\xBF");fputcsv($o,['Référentiel','Contrôle','Titre','Statut','Gravité','Détails','Date'],';');foreach($rows as $r)fputcsv($o,$r,';');fclose($o);exit;}
}
