<?php
declare(strict_types=1);
namespace App\Services;
use App\Core\Database;
use PDO;
final class AiSecurityAssistantService
{
    public function dashboard(): array
    {
        $pdo=Database::connection();
        return [
            'settings'=>$this->settings($pdo),
            'incidents'=>$this->all($pdo,"SELECT id,incident_uuid,title,severity,risk_score,status,module,updated_at FROM system_security_incidents ORDER BY updated_at DESC LIMIT 12"),
            'detections'=>$this->all($pdo,"SELECT rule_name,severity,score,status,entity_type,entity_id,detected_at FROM system_security_detections ORDER BY detected_at DESC LIMIT 12"),
            'compliance'=>$this->row($pdo,"SELECT score,status,summary,created_at FROM system_compliance_audits ORDER BY id DESC LIMIT 1"),
            'history'=>$this->all($pdo,"SELECT id,provider,question_redacted,response_summary,status,created_at FROM system_ai_security_queries ORDER BY id DESC LIMIT 20"),
            'stats'=>$this->row($pdo,"SELECT COUNT(*) total,SUM(status='success') successes,SUM(created_at>=DATE_SUB(NOW(),INTERVAL 24 HOUR)) last24h FROM system_ai_security_queries"),
        ];
    }
    public function ask(string $question,?int $userId): array
    {
        $pdo=Database::connection();$settings=$this->settings($pdo);
        if(!(int)($settings['enabled']??0))return ['status'=>'disabled','text'=>'L’assistant IA est désactivé par l’administrateur.'];
        $redacted=$this->redact($question);
        $context=$this->context($pdo,$redacted);
        $provider=(string)($settings['provider']??'local');
        $started=microtime(true);
        try{
            if($provider==='local'){$text=$this->localAnswer($redacted,$context);}
            else{
                if(!(int)($settings['allow_external']??0))throw new \RuntimeException('Les fournisseurs externes sont désactivés.');
                $text=$this->remoteAnswer($provider,$redacted,$context,$settings);
            }
            $status='success';
        }catch(\Throwable $e){$text='Analyse indisponible : '.$e->getMessage();$status='error';}
        $duration=(int)round((microtime(true)-$started)*1000);
        $s=$pdo->prepare("INSERT INTO system_ai_security_queries(user_id,provider,model_name,question_hash,question_redacted,response_summary,status,duration_ms,created_at) VALUES(:u,:p,:m,:h,:q,:r,:s,:d,NOW())");
        $s->execute(['u'=>$userId,'p'=>$provider,'m'=>(string)($settings['model']??''),'h'=>hash('sha256',$redacted),'q'=>mb_substr($redacted,0,2000),'r'=>mb_substr($text,0,4000),'s'=>$status,'d'=>$duration]);
        return ['status'=>$status,'text'=>$text,'provider'=>$provider,'duration_ms'=>$duration,'context'=>$context];
    }
    private function localAnswer(string $q,array $c): string
    {
        $lower=mb_strtolower($q);$parts=[];
        $parts[]='Synthèse AXIOM : '.(int)$c['active_incidents'].' incident(s) actif(s), '.(int)$c['critical_incidents'].' critique(s), '.(int)$c['open_detections'].' détection(s) ouverte(s), conformité '.(int)$c['compliance_score'].'/100.';
        if(str_contains($lower,'incident')||str_contains($lower,'risque')){
            if($c['top_incident']){$i=$c['top_incident'];$parts[]='Incident prioritaire : « '.($i['title']??'Sans titre').' », gravité '.($i['severity']??'inconnue').', risque '.(int)($i['risk_score']??0).'/100, statut '.($i['status']??'inconnu').'.';}
            $parts[]='Actions recommandées : confirmer le périmètre, préserver les preuves, affecter un responsable, appliquer un confinement proportionné, puis documenter la clôture.';
        }elseif(str_contains($lower,'conform')||str_contains($lower,'rgpd')||str_contains($lower,'nis2')||str_contains($lower,'iso')){
            $parts[]='Priorité conformité : traiter d’abord les constats critiques et élevés, joindre une preuve à chaque correction, puis relancer un audit afin de mesurer le gain.';
        }elseif(str_contains($lower,'détection')||str_contains($lower,'detection')||str_contains($lower,'alerte')){
            $parts[]='Méthode de qualification : vérifier la règle déclenchée, la fréquence, l’entité concernée, les événements voisins et l’existence d’un indicateur de compromission avant de créer un incident.';
        }elseif(str_contains($lower,'rapport')||str_contains($lower,'résumé')||str_contains($lower,'resume')){
            $parts[]='Rapport conseillé : contexte, chronologie, actifs concernés, impact, preuves, mesures immédiates, cause racine, actions correctives, responsable et échéance.';
        }else{
            $parts[]='Je peux analyser les incidents, détections, audits, politiques Zero Trust et tendances SOC. Les propositions restent soumises à validation humaine.';
        }
        $parts[]='Aucune action n’a été exécutée automatiquement.';
        return implode("\n\n",$parts);
    }
    private function remoteAnswer(string $provider,string $q,array $c,array $settings): string
    {
        if(!function_exists('curl_init'))throw new \RuntimeException('Extension cURL indisponible.');
        $endpoint=trim((string)($settings['endpoint']??''));if($endpoint==='')throw new \RuntimeException('Point de terminaison non configuré.');
        $key=getenv('AXIOM_AI_API_KEY')?:'';if($provider!=='ollama'&&$key==='')throw new \RuntimeException('Variable AXIOM_AI_API_KEY absente.');
        $system='Tu es l’assistant de sécurité AXIOM. Réponds en français, reste factuel, ne déclenche aucune action et rappelle la validation humaine.';
        $payload=['model'=>(string)$settings['model'],'messages'=>[['role'=>'system','content'=>$system],['role'=>'user','content'=>$q."\n\nContexte agrégé : ".json_encode($c,JSON_UNESCAPED_UNICODE)]],'temperature'=>0.2];
        $ch=curl_init($endpoint);$headers=['Content-Type: application/json'];if($key!=='')$headers[]='Authorization: Bearer '.$key;
        curl_setopt_array($ch,[CURLOPT_POST=>true,CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>25,CURLOPT_HTTPHEADER=>$headers,CURLOPT_POSTFIELDS=>json_encode($payload,JSON_UNESCAPED_UNICODE|JSON_THROW_ON_ERROR)]);
        $raw=curl_exec($ch);$code=(int)curl_getinfo($ch,CURLINFO_HTTP_CODE);$err=curl_error($ch);curl_close($ch);
        if($raw===false||$code<200||$code>=300)throw new \RuntimeException('Fournisseur IA indisponible (HTTP '.$code.($err?': '.$err:'').').');
        $data=json_decode($raw,true);$text=$data['choices'][0]['message']['content']??$data['message']['content']??$data['response']??null;
        if(!is_string($text)||trim($text)==='')throw new \RuntimeException('Réponse IA non exploitable.');return trim($text);
    }
    private function context(PDO $pdo,string $q): array
    {
        $summary=$this->row($pdo,"SELECT SUM(status IN ('open','investigating')) active_incidents,SUM(status IN ('open','investigating') AND severity='critical') critical_incidents FROM system_security_incidents");
        $d=$this->row($pdo,"SELECT SUM(status='open') open_detections FROM system_security_detections");
        $comp=$this->row($pdo,"SELECT score compliance_score FROM system_compliance_audits ORDER BY id DESC LIMIT 1");
        $top=$this->row($pdo,"SELECT title,severity,risk_score,status,module FROM system_security_incidents WHERE status IN ('open','investigating') ORDER BY risk_score DESC,updated_at DESC LIMIT 1");
        return ['active_incidents'=>(int)($summary['active_incidents']??0),'critical_incidents'=>(int)($summary['critical_incidents']??0),'open_detections'=>(int)($d['open_detections']??0),'compliance_score'=>(int)($comp['compliance_score']??0),'top_incident'=>$top];
    }
    public function saveSettings(array $v,?int $userId): void
    {
        $provider=in_array($v['provider']??'', ['local','openai','azure_openai','ollama'],true)?$v['provider']:'local';
        $endpoint=trim((string)($v['endpoint']??''));if($endpoint!==''&&!preg_match('~^https?://~i',$endpoint))throw new \InvalidArgumentException('Endpoint invalide.');
        $pdo=Database::connection();$s=$pdo->prepare("UPDATE system_ai_security_settings SET enabled=:e,provider=:p,model_name=:m,endpoint=:n,allow_external=:x,anonymize=:a,updated_by=:u,updated_at=NOW() WHERE id=1");
        $s->execute(['e'=>(int)!empty($v['enabled']),'p'=>$provider,'m'=>mb_substr(trim((string)$v['model']),0,160),'n'=>mb_substr($endpoint,0,500),'x'=>(int)!empty($v['allow_external']),'a'=>(int)!empty($v['anonymize']),'u'=>$userId]);
    }
    public function clearHistory(): void{Database::connection()->exec("DELETE FROM system_ai_security_queries");}
    private function settings(PDO $pdo): array{return $this->row($pdo,"SELECT * FROM system_ai_security_settings WHERE id=1")?:['enabled'=>1,'provider'=>'local','model_name'=>'axiom-security-local','endpoint'=>'','allow_external'=>0,'anonymize'=>1];}
    private function redact(string $s): string
    {
        $s=preg_replace('/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/iu','[EMAIL]',$s)??$s;
        $s=preg_replace('/\b(?:\d[ .-]?){10,13}\b/u','[TELEPHONE]',$s)??$s;
        $s=preg_replace('/\b(?:sk-|Bearer\s+)[A-Za-z0-9._-]{12,}\b/i','[SECRET]',$s)??$s;
        $s=preg_replace('/\b\d{13,15}\b/u','[IDENTIFIANT]',$s)??$s;
        return trim($s);
    }
    private function row(PDO $pdo,string $sql,array $p=[]): array{$s=$pdo->prepare($sql);$s->execute($p);return $s->fetch(PDO::FETCH_ASSOC)?:[];}
    private function all(PDO $pdo,string $sql,array $p=[]): array{$s=$pdo->prepare($sql);$s->execute($p);return $s->fetchAll(PDO::FETCH_ASSOC)?:[];}
}
