<?php
declare(strict_types=1);
namespace App\Services;
use App\Core\Database;
use PDO;
final class ExecutiveSecurityService
{
    public function dashboard(int $days=30): array
    {
        $pdo=Database::connection();
        $since=(new \DateTimeImmutable('-'.$days.' days'))->format('Y-m-d H:i:s');
        $inc=$this->row($pdo,"SELECT COUNT(*) total,SUM(status IN ('open','investigating')) active,SUM(status IN ('open','investigating') AND severity='critical') critical,SUM(status IN ('open','investigating') AND due_at IS NOT NULL AND due_at<NOW()) overdue,COALESCE(MAX(CASE WHEN status IN ('open','investigating') THEN risk_score END),0) max_risk FROM system_security_incidents WHERE created_at>=:since",['since'=>$since]);
        $det=$this->row($pdo,"SELECT COUNT(*) total,SUM(status='open') open_count,SUM(status='open' AND severity='critical') critical FROM system_security_detections WHERE detected_at>=:since",['since'=>$since]);
        $comp=$this->row($pdo,"SELECT score,status,summary,created_at FROM system_compliance_audits ORDER BY id DESC LIMIT 1");
        $backup=$this->row($pdo,"SELECT statut,created_at,finished_at,taille_totale,message FROM cda_backup_jobs ORDER BY id DESC LIMIT 1");
        $update=$this->row($pdo,"SELECT version_cible,statut,installe_at,installation_fin,message FROM cda_update_packages ORDER BY id DESC LIMIT 1");
        $health=$this->row($pdo,"SELECT SUM(acknowledged_at IS NULL) active_alerts,SUM(acknowledged_at IS NULL AND severity='critical') critical_alerts FROM system_health_alerts");
        $zt=$this->row($pdo,"SELECT COUNT(*) total,SUM(enabled=1) active,SUM(enabled=1 AND simulation_only=0) enforced FROM system_zero_trust_policies");
        $trend=$this->all($pdo,"SELECT DATE(created_at) day,ROUND(AVG(risk_score),1) avg_risk,MAX(risk_score) max_risk,COUNT(*) incidents FROM system_security_incidents WHERE created_at>=:since GROUP BY DATE(created_at) ORDER BY day",['since'=>$since]);
        $modules=$this->all($pdo,"SELECT COALESCE(NULLIF(module,''),'non_renseigne') module,COUNT(*) incidents,MAX(risk_score) max_risk,SUM(status IN ('open','investigating')) active FROM system_security_incidents WHERE created_at>=:since GROUP BY COALESCE(NULLIF(module,''),'non_renseigne') ORDER BY max_risk DESC,incidents DESC LIMIT 10",['since'=>$since]);
        $actions=$this->recommendations($inc,$det,$comp,$backup,$update,$health,$zt);
        $securityScore=$this->securityScore($inc,$det,$comp,$backup,$update,$health,$zt);
        return compact('days','since','inc','det','comp','backup','update','health','zt','trend','modules','actions','securityScore')+['generatedAt'=>date('Y-m-d H:i:s')];
    }
    private function securityScore(array $i,array $d,array $c,array $b,array $u,array $h,array $z): int
    {
        $score=100;
        $score-=min(30,(int)($i['critical']??0)*10);
        $score-=min(15,(int)($i['overdue']??0)*5);
        $score-=min(15,(int)($d['critical']??0)*5);
        $score-=min(15,(int)($h['critical_alerts']??0)*5);
        if(($b['statut']??'')!=='succes')$score-=10;
        if(($u['statut']??'')!=='installe')$score-=5;
        if((int)($z['enforced']??0)<1)$score-=5;
        $compliance=(int)($c['score']??0);
        if($compliance<90)$score-=min(10,(int)ceil((90-$compliance)/9));
        return max(0,min(100,$score));
    }
    private function recommendations(array $i,array $d,array $c,array $b,array $u,array $h,array $z): array
    {
        $a=[];
        if((int)($i['critical']??0)>0)$a[]=['priority'=>'critique','title'=>'Traiter les incidents critiques','detail'=>(int)$i['critical'].' incident(s) critique(s) actif(s).'];
        if((int)($i['overdue']??0)>0)$a[]=['priority'=>'élevée','title'=>'Résorber les incidents en retard','detail'=>(int)$i['overdue'].' échéance(s) dépassée(s).'];
        if((int)($d['critical']??0)>0)$a[]=['priority'=>'élevée','title'=>'Qualifier les détections critiques','detail'=>(int)$d['critical'].' détection(s) critique(s) ouverte(s).'];
        if(($b['statut']??'')!=='succes')$a[]=['priority'=>'élevée','title'=>'Vérifier les sauvegardes','detail'=>'La dernière sauvegarde n’est pas marquée comme réussie.'];
        if((int)($h['critical_alerts']??0)>0)$a[]=['priority'=>'critique','title'=>'Traiter les alertes de santé','detail'=>(int)$h['critical_alerts'].' alerte(s) critique(s) non acquittée(s).'];
        if((int)($c['score']??0)<90)$a[]=['priority'=>'moyenne','title'=>'Améliorer la conformité','detail'=>'Score actuel : '.(int)($c['score']??0).'/100.'];
        if((int)($z['enforced']??0)<1)$a[]=['priority'=>'moyenne','title'=>'Activer une politique Zero Trust','detail'=>'Aucune politique appliquée hors simulation.'];
        if(!$a)$a[]=['priority'=>'faible','title'=>'Maintenir la surveillance','detail'=>'Aucune action prioritaire détectée.'];
        return $a;
    }
    private function row(PDO $pdo,string $sql,array $params=[]): array{$s=$pdo->prepare($sql);$s->execute($params);return $s->fetch(PDO::FETCH_ASSOC)?:[];}
    private function all(PDO $pdo,string $sql,array $params=[]): array{$s=$pdo->prepare($sql);$s->execute($params);return $s->fetchAll(PDO::FETCH_ASSOC)?:[];}
    public function exportCsv(int $days): void
    {
        $r=$this->dashboard($days);
        header('Content-Type: text/csv; charset=UTF-8');
        header('Content-Disposition: attachment; filename=axiom-executive-security-'.date('Ymd-His').'.csv');
        $o=fopen('php://output','wb');fwrite($o,"\xEF\xBB\xBF");fputcsv($o,['Indicateur','Valeur'],';');
        $rows=[['Score sécurité',$r['securityScore'].'/100'],['Score conformité',(int)($r['comp']['score']??0).'/100'],['Incidents actifs',(int)($r['inc']['active']??0)],['Incidents critiques',(int)($r['inc']['critical']??0)],['Incidents en retard',(int)($r['inc']['overdue']??0)],['Détections ouvertes',(int)($r['det']['open_count']??0)],['Alertes santé critiques',(int)($r['health']['critical_alerts']??0)],['Dernière sauvegarde',$r['backup']['statut']??'inconnue'],['Dernière mise à jour',$r['update']['version_cible']??'inconnue'],['Politiques Zero Trust actives',(int)($r['zt']['active']??0)]];
        foreach($rows as $x)fputcsv($o,$x,';');fclose($o);exit;
    }
}
