<?php
require __DIR__ . '/includes.php';
require_login();

if(!function_exists('can_manage_all_companies')){
    function can_manage_all_companies(){ $u=current_user(); return $u && in_array($u['rol']??'', ['super_admin','admin_general'], true); }
}

function sec_ensure_schema_v18(){
    try{
        if(!column_exists('security_studies','concepto_detalle')) db()->exec("ALTER TABLE security_studies ADD COLUMN concepto_detalle TEXT NULL AFTER concepto");
        if(!column_exists('security_studies','finalizado_at')) db()->exec("ALTER TABLE security_studies ADD COLUMN finalizado_at DATETIME NULL AFTER estado");
        if(!column_exists('security_studies','documento_word_ruta')) db()->exec("ALTER TABLE security_studies ADD COLUMN documento_word_ruta VARCHAR(500) NULL AFTER documento_generado_ruta");
        if(!column_exists('security_studies','documento_pdf_ruta')) db()->exec("ALTER TABLE security_studies ADD COLUMN documento_pdf_ruta VARCHAR(500) NULL AFTER documento_word_ruta");
        if(!column_exists('companies','whatsapp_group_url')) db()->exec("ALTER TABLE companies ADD COLUMN whatsapp_group_url VARCHAR(500) NULL AFTER logo_ruta");
    }catch(Throwable $e){ /* ejecutar migración manual si el hosting bloquea ALTER */ }
}
sec_ensure_schema_v18();

function sec_study_sources(){
    return [
        ['cat'=>'JUDICIALES','key'=>'POL_PEN','label'=>'Antecedentes penales - Policía Nacional','url'=>'https://antecedentes.policia.gov.co:7005/WebJudicial/index.xhtml','type'=>'binary'],
        ['cat'=>'JUDICIALES','key'=>'POL_CON','label'=>'Antecedentes contravenciones - Policía Nacional','url'=>'https://srvcnpc.policia.gov.co/PSC/frm_cnp_consulta.aspx','type'=>'binary'],
        ['cat'=>'JUDICIALES','key'=>'RJ_PEN','label'=>'Antecedentes penales - Rama Judicial','url'=>'https://procesos.ramajudicial.gov.co/jepms/bogotajepms/conectar.asp','type'=>'binary'],
        ['cat'=>'JUDICIALES','key'=>'RJ_GEN','label'=>'Antecedentes judiciales (civil, laboral, familia y administrativo)','url'=>'https://consultaprocesos.ramajudicial.gov.co/procesos/bienvenida','type'=>'binary'],
        ['cat'=>'SANCIONES NACIONALES','key'=>'CONTRAL','label'=>'Responsabilidad fiscal - Contraloría General de la Nación','url'=>'https://www.contraloria.gov.co/web/guest/persona-natural','type'=>'binary'],
        ['cat'=>'SANCIONES NACIONALES','key'=>'PROC','label'=>'Responsabilidad disciplinaria - Procuraduría General de la Nación','url'=>'https://www.procuraduria.gov.co/Pages/Consulta-de-Antecedentes.aspx','type'=>'binary'],
        ['cat'=>'SANCIONES NACIONALES','key'=>'RUNT_SIMIT','label'=>'Multas y comparendos de tránsito - RUNT / SIMIT','url'=>'https://www.runt.com.co/consultaCiudadana/#/consultaPersona','type'=>'binary'],
        ['cat'=>'SANCIONES NACIONALES','key'=>'BDME','label'=>'Deudas con el Estado - BDME','url'=>'','type'=>'binary'],
        ['cat'=>'INFORMACIÓN PÚBLICA','key'=>'REG_CIVIL','label'=>'Registro civil de nacimiento - Registraduría Nacional','url'=>'https://consultasrc.registraduria.gov.co:28080/ProyectoSCCRC/','type'=>'textlong'],
        ['cat'=>'INFORMACIÓN PÚBLICA','key'=>'RUT','label'=>'RUT - DIAN','url'=>'https://muisca.dian.gov.co/WebRutMuisca/DefConsultaEstadoRUT.faces','type'=>'yesdetail','detail'=>'Número de RUT / información encontrada'],
        ['cat'=>'INFORMACIÓN PÚBLICA','key'=>'RUES','label'=>'Registro mercantil - RUES','url'=>'https://www.rues.org.co/','type'=>'yesdetail','detail'=>'Matrícula / cámara / información encontrada'],
        ['cat'=>'INFORMACIÓN PÚBLICA','key'=>'LIC_RUNT','label'=>'Licencias de tránsito - RUNT','url'=>'https://www.runt.com.co/consultaCiudadana/#/consultaPersona','type'=>'yesdetail','detail'=>'Clase, vigencia o información encontrada'],
        ['cat'=>'RUAF','key'=>'RUAF_AF','label'=>'Afiliación / calidad','url'=>'https://ruaf.sispro.gov.co/TerminosCondiciones.aspx','type'=>'text'],
        ['cat'=>'RUAF','key'=>'RUAF_EPS','label'=>'EPS','url'=>'https://ruaf.sispro.gov.co/TerminosCondiciones.aspx','type'=>'text'],
        ['cat'=>'RUAF','key'=>'RUAF_AFP','label'=>'AFP','url'=>'https://ruaf.sispro.gov.co/TerminosCondiciones.aspx','type'=>'text'],
        ['cat'=>'RUAF','key'=>'RUAF_ARL','label'=>'ARL','url'=>'https://ruaf.sispro.gov.co/TerminosCondiciones.aspx','type'=>'text'],
        ['cat'=>'BDUA','key'=>'BDUA_EST','label'=>'Estado de afiliación','url'=>'https://servicios.adres.gov.co/BDUA/Consulta-Afiliados-BDUA','type'=>'text'],
        ['cat'=>'BDUA','key'=>'BDUA_EPS','label'=>'EPS','url'=>'https://servicios.adres.gov.co/BDUA/Consulta-Afiliados-BDUA','type'=>'text'],
        ['cat'=>'BDUA','key'=>'BDUA_FECHA','label'=>'Fecha fin de afiliación','url'=>'https://servicios.adres.gov.co/BDUA/Consulta-Afiliados-BDUA','type'=>'date'],
        ['cat'=>'LISTAS Y REPUTACIÓN','key'=>'INTERPOL','label'=>'Interpol','url'=>'https://www.interpol.int/es/Como-trabajamos/Notificaciones/Notificaciones-rojas/Ver-las-notificaciones-rojas','type'=>'binary'],
        ['cat'=>'LISTAS Y REPUTACIÓN','key'=>'OFAC','label'=>'OFAC','url'=>'https://sanctionssearch.ofac.treas.gov/','type'=>'binary'],
        ['cat'=>'LISTAS Y REPUTACIÓN','key'=>'REPUT','label'=>'Reputacional','url'=>'','type'=>'binary'],
        ['cat'=>'VALIDACIÓN DOCUMENTAL','key'=>'DOCS','label'=>'Documentos aportados / validación documental','url'=>'','type'=>'textlong'],
    ];
}
function sec_binary_results(){ return ['NO','SI','PENDIENTE','NO APLICA']; }
function sec_yesdetail_results(){ return ['NO','SI','PENDIENTE','NO APLICA']; }
function sec_concepts(){ return ['FAVORABLE SIN NOVEDAD','FAVORABLE CON OBSERVACIONES','NO FAVORABLE','PENDIENTE DE VALIDACIÓN']; }
function sec_contract_types(){ return ['Personal - Laboral','Personal - Prestación de servicios','Negocio / contratación civil','Otro']; }
function sec_concept_to_collaborator_result($concepto){
    $c=mb_strtoupper(trim((string)$concepto),'UTF-8');
    if(strpos($c,'NO FAVORABLE')!==false) return 'No favorable';
    if(strpos($c,'OBSERV')!==false) return 'Favorable con observación';
    if(strpos($c,'FAVORABLE')!==false) return 'Favorable';
    return 'Pendiente';
}
function sec_doc_id($tipo,$numero){ return trim(($tipo ?: 'C.C').' No. '.trim((string)$numero)); }
function sec_storage_dir($sub){ $dir=rtrim(cfg('upload_dir'),'/').'/'.$sub; if(!is_dir($dir)) mkdir($dir,0775,true); return $dir; }
function sec_relative_path($abs){ return str_replace(rtrim(__DIR__,'/').'/', '', $abs); }
function sec_safe_filename($name){ $name=preg_replace('/[^A-Za-z0-9_\-\. ]+/','',trim((string)$name)); return preg_replace('/\s+/','_',$name) ?: 'estudio_seguridad'; }
function sec_get_collaborator($id){ if(!$id) return null; $st=db()->prepare('SELECT c.*, co.nombre company_name FROM collaborators c JOIN companies co ON co.id=c.company_id WHERE c.id=? LIMIT 1'); $st->execute([(int)$id]); $c=$st->fetch(); return ($c && can_read_company($c['company_id'])) ? $c : null; }
function sec_study_fetch($id){ $st=db()->prepare('SELECT s.*, co.nombre company_name, co.whatsapp_group_url, co.logo_ruta company_logo FROM security_studies s JOIN companies co ON co.id=s.company_id WHERE s.id=? LIMIT 1'); $st->execute([(int)$id]); $r=$st->fetch(); return ($r && can_read_company($r['company_id'])) ? $r : null; }
function sec_checks_fetch($id){ $st=db()->prepare('SELECT * FROM security_study_checks WHERE study_id=? ORDER BY id'); $st->execute([(int)$id]); $out=[]; foreach($st->fetchAll() as $r) $out[$r['clave']]=$r; return $out; }
function sec_public_url($path){ if(!$path) return ''; if(preg_match('#^https?://#i',$path)) return $path; return base_url($path); }
function sec_save_evidence($key,$companyId,$existing=''){
    $field='check_evidence_file';
    if(!empty($_FILES[$field]['name'][$key]) && ($_FILES[$field]['error'][$key] ?? UPLOAD_ERR_NO_FILE)===UPLOAD_ERR_OK){
        $tmp=$_FILES[$field]['tmp_name'][$key]; $mime=mime_content_type($tmp); $allowed=['image/jpeg'=>'jpg','image/png'=>'png','image/webp'=>'webp','application/pdf'=>'pdf'];
        if(!isset($allowed[$mime])) throw new RuntimeException('Evidencia no permitida en '.$key.'. Use JPG, PNG, WEBP o PDF.');
        $dir=sec_storage_dir('security_evidence/company_'.$companyId.'/'.date('Y/m'));
        $dest=$dir.'/'.sec_safe_filename($key.'_'.date('Ymd_His').'_'.bin2hex(random_bytes(4))).'.'.$allowed[$mime];
        if(!move_uploaded_file($tmp,$dest)) throw new RuntimeException('No fue posible guardar la evidencia de '.$key.'.');
        return sec_relative_path($dest);
    }
    $data=$_POST['check_evidence_data'][$key] ?? '';
    if($data && preg_match('#^data:image/(png|jpeg|webp);base64,(.+)$#',$data,$m)){
        $raw=base64_decode($m[2],true); if($raw===false) return $existing;
        $ext=$m[1]==='jpeg'?'jpg':$m[1]; $dir=sec_storage_dir('security_evidence/company_'.$companyId.'/'.date('Y/m'));
        $dest=$dir.'/'.sec_safe_filename($key.'_'.date('Ymd_His').'_'.bin2hex(random_bytes(4))).'.'.$ext;
        file_put_contents($dest,$raw); return sec_relative_path($dest);
    }
    return trim($_POST['check_evidence'][$key] ?? '') ?: $existing;
}
function sec_json_response($payload,$status=200){
    http_response_code($status);
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($payload,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
    exit;
}
function sec_store_async_evidence($companyId,$key){
    if(empty($_FILES['evidence_upload']) || !isset($_FILES['evidence_upload']['error'])) throw new RuntimeException('No se recibió el archivo de evidencia.');
    $error=(int)$_FILES['evidence_upload']['error'];
    if($error!==UPLOAD_ERR_OK){
        $messages=[UPLOAD_ERR_INI_SIZE=>'El archivo supera el límite configurado por el servidor.',UPLOAD_ERR_FORM_SIZE=>'El archivo supera el límite permitido.',UPLOAD_ERR_PARTIAL=>'El archivo se cargó parcialmente.',UPLOAD_ERR_NO_FILE=>'No se seleccionó archivo.',UPLOAD_ERR_NO_TMP_DIR=>'El servidor no tiene carpeta temporal.',UPLOAD_ERR_CANT_WRITE=>'El servidor no pudo escribir el archivo.',UPLOAD_ERR_EXTENSION=>'Una extensión del servidor bloqueó la carga.'];
        throw new RuntimeException($messages[$error]??('Error de carga '.$error.'.'));
    }
    $tmp=$_FILES['evidence_upload']['tmp_name'];
    if(!is_uploaded_file($tmp)) throw new RuntimeException('La evidencia recibida no es un archivo cargado válido.');
    $size=(int)($_FILES['evidence_upload']['size']??0);
    if($size<=0) throw new RuntimeException('El archivo de evidencia está vacío.');
    if($size>1900000) throw new RuntimeException('La evidencia supera 1,8 MB. Reduzca el tamaño o use una captura comprimida.');
    $mime=function_exists('mime_content_type')?mime_content_type($tmp):($_FILES['evidence_upload']['type']??'');
    $allowed=['image/jpeg'=>'jpg','image/png'=>'png','image/webp'=>'webp','application/pdf'=>'pdf'];
    if(!isset($allowed[$mime])) throw new RuntimeException('Evidencia no permitida. Use JPG, PNG, WEBP o PDF.');
    $key=preg_replace('/[^A-Za-z0-9_\-]/','',(string)$key) ?: 'EVIDENCIA';
    $dir=sec_storage_dir('security_evidence/company_'.$companyId.'/'.date('Y/m'));
    $dest=$dir.'/'.sec_safe_filename($key.'_'.date('Ymd_His').'_'.bin2hex(random_bytes(4))).'.'.$allowed[$mime];
    if(!move_uploaded_file($tmp,$dest)) throw new RuntimeException('No fue posible guardar la evidencia en el servidor.');
    $rel=sec_relative_path($dest);
    return ['path'=>$rel,'url'=>sec_public_url($rel),'mime'=>$mime,'is_image'=>strpos($mime,'image/')===0,'name'=>basename($dest)];
}
function sec_upload_evidence_action(){
    require_write();
    if($_SERVER['REQUEST_METHOD']!=='POST') sec_json_response(['ok'=>false,'message'=>'Método no permitido.'],405);
    try{
        check_csrf();
        $u=current_user();
        $companyId=user_restricts_company()?(int)($u['company_id']??0):(int)($_POST['company_id']??0);
        if(!$companyId || !can_read_company($companyId)) throw new RuntimeException('Empresa no válida para la evidencia.');
        $result=sec_store_async_evidence($companyId,$_POST['evidence_key']??'EVIDENCIA');
        sec_json_response(['ok'=>true]+$result);
    }catch(Throwable $e){
        sec_json_response(['ok'=>false,'message'=>$e->getMessage()],422);
    }
}
function sec_xml_escape($v){ return htmlspecialchars((string)$v,ENT_XML1|ENT_QUOTES,'UTF-8'); }
function sec_replace_docx_placeholders($template,$dest,$rep,$links=[]){
    if(!class_exists('ZipArchive')) throw new RuntimeException('El servidor no tiene habilitada la extensión ZipArchive.');
    if(!copy($template,$dest)) throw new RuntimeException('No fue posible copiar la plantilla Word.');
    $zip=new ZipArchive(); if($zip->open($dest)!==true) throw new RuntimeException('No fue posible abrir el documento Word generado.');
    $relsName='word/_rels/document.xml.rels'; $rels=$zip->getFromName($relsName) ?: '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>';
    preg_match_all('/Id="rId(\d+)"/',$rels,$ids); $rid=empty($ids[1])?20:(max(array_map('intval',$ids[1]))+1); $total=0;
    for($i=0;$i<$zip->numFiles;$i++){
        $name=$zip->getNameIndex($i); if(!preg_match('#^word/(document|header\d*|footer\d*)\.xml$#',$name)) continue;
        $xml=$zip->getFromName($name);
        foreach($rep as $k=>$v){ $count=0; $xml=str_replace($k,sec_xml_escape($v),$xml,$count); $total+=$count; }
        if($name==='word/document.xml'){
            foreach($links as $placeholder=>$link){
                $url=trim((string)($link['url']??'')); $label=(string)($link['label']??'Ver evidencia');
                if($url===''){ $xml=str_replace($placeholder,'',$xml); continue; }
                $relId='rId'.$rid++; $rel='<Relationship Id="'.$relId.'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="'.sec_xml_escape($url).'" TargetMode="External"/>';
                $rels=str_replace('</Relationships>',$rel.'</Relationships>',$rels);
                $snippet='</w:t></w:r><w:hyperlink r:id="'.$relId.'"><w:r><w:rPr><w:color w:val="0563C1"/><w:u w:val="single"/></w:rPr><w:t>'.sec_xml_escape($label).'</w:t></w:r></w:hyperlink><w:r><w:t>';
                $xml=str_replace($placeholder,$snippet,$xml,$count); $total+=$count;
            }
        }
        $zip->addFromString($name,$xml);
    }
    $zip->addFromString($relsName,$rels); $zip->close(); return $total;
}
function sec_find_office_converter(){
    $configured=trim((string)cfg('libreoffice_path',''));
    $candidates=array_filter([$configured,'/usr/bin/libreoffice','/usr/bin/soffice','/usr/local/bin/libreoffice','/usr/local/bin/soffice']);
    foreach($candidates as $bin) if(is_file($bin) && is_executable($bin)) return ['type'=>'libreoffice','bin'=>$bin];
    if(function_exists('shell_exec')){
        foreach(['libreoffice','soffice','unoconv'] as $cmd){ $found=trim((string)@shell_exec('command -v '.escapeshellarg($cmd).' 2>/dev/null')); if($found!=='') return ['type'=>$cmd==='unoconv'?'unoconv':'libreoffice','bin'=>$found]; }
    }
    return null;
}
function sec_convert_docx_to_pdf($docx,$pdf){
    $conv=sec_find_office_converter(); if(!$conv) throw new RuntimeException('El estudio se guardó, pero el servidor no tiene LibreOffice/soffice para convertir la plantilla Word a PDF. Solicite al hosting habilitar LibreOffice o configure libreoffice_path en config.php.');
    if(!function_exists('exec')) throw new RuntimeException('El servidor tiene deshabilitada la función exec requerida para convertir Word a PDF.');
    $outDir=dirname($pdf); $output=[]; $code=1;
    if($conv['type']==='unoconv') $cmd=escapeshellarg($conv['bin']).' -f pdf -o '.escapeshellarg($pdf).' '.escapeshellarg($docx).' 2>&1';
    else $cmd=escapeshellarg($conv['bin']).' --headless --convert-to pdf --outdir '.escapeshellarg($outDir).' '.escapeshellarg($docx).' 2>&1';
    @exec($cmd,$output,$code);
    $generated=$outDir.'/'.pathinfo($docx,PATHINFO_FILENAME).'.pdf';
    if($conv['type']!=='unoconv' && is_file($generated) && $generated!==$pdf) @rename($generated,$pdf);
    if($code!==0 || !is_file($pdf) || filesize($pdf)<1000) throw new RuntimeException('No fue posible convertir la plantilla Word a PDF. Detalle: '.implode(' ',array_slice($output,-4)));
}
function sec_observation_summary($checks){
    $lines=[]; foreach(sec_study_sources() as $src){ $r=$checks[$src['key']]??null; if($r && trim((string)$r['observacion'])!=='') $lines[]='* '.$src['label'].': '.trim($r['observacion']); }
    return implode("\n",$lines);
}
function sec_generate_documents($id){
    $s=sec_study_fetch($id); if(!$s) throw new RuntimeException('Estudio no encontrado.'); $checks=sec_checks_fetch($id);
    $template=__DIR__.'/templates/estudio_seguridad_plantilla.docx'; if(!is_file($template)) throw new RuntimeException('No existe la plantilla Word del estudio de seguridad.');
    $rep=['{{F_EST}}'=>dt($s['fecha_estudio']),'{{NOMBRE}}'=>$s['nombre_consulta'],'{{ID}}'=>sec_doc_id($s['tipo_documento'],$s['numero_documento']),'{{F_EXP}}'=>dt($s['fecha_expedicion_documento']),'{{OBS}}'=>$s['observacion'],'{{TIPO}}'=>$s['tipo_prospecto'],'{{CONCEPTO}}'=>$s['concepto'],'{{CONCEPTO_DETALLE}}'=>$s['concepto_detalle']??'','{{OBS_RESUMEN}}'=>sec_observation_summary($checks)];
    $links=[];
    foreach(sec_study_sources() as $src){ $r=$checks[$src['key']]??[]; $rep['{{'.$src['key'].'}}']=$r['resultado']??''; $rep['{{'.$src['key'].'_OBS}}']=$r['observacion']??''; $links['{{'.$src['key'].'_EVI}}']=['url'=>!empty($r['evidencia_url'])?sec_public_url($r['evidencia_url']):'','label'=>'Ver evidencia']; }
    $dir=sec_storage_dir('security_studies/company_'.$s['company_id'].'/'.date('Y/m',strtotime($s['fecha_estudio']?:date('Y-m-d'))));
    $base=sec_safe_filename('Estudio de seguridad - '.$s['nombre_consulta'].' - '.$s['numero_documento']); $docx=$dir.'/'.$base.'.docx'; $pdf=$dir.'/'.$base.'.pdf';
    $total=sec_replace_docx_placeholders($template,$docx,$rep,$links);
    $docxRel=sec_relative_path($docx); $pdfRel=null;
    $converter=sec_find_office_converter();
    if($converter && function_exists('exec')){
        try{ sec_convert_docx_to_pdf($docx,$pdf); if(is_file($pdf) && filesize($pdf)>1000) $pdfRel=sec_relative_path($pdf); }
        catch(Throwable $e){ $pdfRel=null; }
    }
    $primaryRel=$pdfRel ?: $docxRel;
    db()->prepare('UPDATE security_studies SET documento_generado_ruta=?,documento_word_ruta=?,documento_pdf_ruta=?,total_reemplazos=?,updated_by=? WHERE id=?')->execute([$primaryRel,$docxRel,$pdfRel,$total,current_user()['id']??null,$id]);
    if(!empty($s['collaborator_id'])){
        $displayName=$pdfRel?basename($pdf):basename($docx); $mime=$pdfRel?'application/pdf':'application/vnd.openxmlformats-officedocument.wordprocessingml.document'; $size=$pdfRel?filesize($pdf):filesize($docx);
        db()->prepare('UPDATE collaborators SET estudio_seguridad_id=?,estudio_seguridad_resultado=?,estudio_seguridad_fecha=?,estudio_seguridad_nombre=?,estudio_seguridad_ruta=?,estudio_seguridad_observacion=?,updated_by=? WHERE id=?')->execute([$id,sec_concept_to_collaborator_result($s['concepto']),$s['fecha_estudio'],$displayName,$primaryRel,$s['concepto_detalle']??$s['observacion'],current_user()['id']??null,$s['collaborator_id']]);
        try{ db()->prepare('INSERT INTO documents(company_id,collaborator_id,tipo_documento,nombre_original,ruta,mime_type,size_bytes,created_by) VALUES(?,?,?,?,?,?,?,?)')->execute([$s['company_id'],$s['collaborator_id'],'Estudio de seguridad generado',$displayName,$primaryRel,$mime,$size,current_user()['id']??null]); }catch(Throwable $e){}
    }
    return ['docx'=>$docxRel,'pdf'=>$pdfRel,'pdf_name'=>$pdfRel?basename($pdf):null,'browser_pdf'=>!$pdfRel];
}
function sec_docx_preview_page($s,$docxRel){
    $docxUrl=sec_public_url($docxRel); $title='Estudio de seguridad - '.$s['nombre_consulta'];
    ?><!doctype html><html lang="es"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title><?= e($title) ?></title>
    <script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/docx-preview@0.3.7/dist/docx-preview.min.js"></script>
    <style>
    :root{--petroleo:#01495E;--celeste:#6DC2D5}*{box-sizing:border-box}body{margin:0;background:#eef4f6;font-family:Arial,sans-serif;color:#17313a}.toolbar{position:sticky;top:0;z-index:20;display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:12px 16px;background:#fff;border-bottom:1px solid #cadde3;box-shadow:0 4px 16px rgba(0,0,0,.08)}.toolbar strong{margin-right:auto;color:var(--petroleo)}.btn{border:0;border-radius:9px;padding:10px 15px;background:var(--petroleo);color:#fff;font-weight:700;cursor:pointer;text-decoration:none}.btn.secondary{background:#e8f3f6;color:var(--petroleo)}.btn:disabled{opacity:.5;cursor:not-allowed}.status{padding:9px 12px;border-radius:9px;background:#fff8dc;color:#725600}.preview-shell{padding:22px;overflow:auto}.docx-wrapper{background:#d8e1e5!important;padding:20px!important}.docx-wrapper>section.docx{box-shadow:0 6px 24px rgba(0,0,0,.14)!important;margin:0 auto 20px!important}.error-box{max-width:900px;margin:30px auto;padding:20px;background:#fff0f0;border:1px solid #e69b9b;border-radius:12px;color:#8b1e1e}@page{size:Letter portrait;margin:0}@media print{body{background:#fff}.toolbar{display:none!important}.preview-shell{padding:0!important;overflow:visible!important}.docx-wrapper{background:#fff!important;padding:0!important}.docx-wrapper>section.docx{box-shadow:none!important;margin:0!important;page-break-after:always}.docx-wrapper>section.docx:last-child{page-break-after:auto}}
    </style></head><body><div class="toolbar"><strong><?= e($title) ?></strong><span id="status" class="status">Preparando plantilla Word…</span><button class="btn" type="button" id="printBtn" disabled>Imprimir / guardar PDF</button><a class="btn secondary" href="<?= e($docxUrl) ?>" download>Descargar Word</a><button class="btn secondary" type="button" onclick="window.close()">Cerrar</button></div><div class="preview-shell"><div id="docxContainer"></div><div id="errorBox" class="error-box" hidden></div></div>
    <script>
    (async()=>{const status=document.getElementById('status'),btn=document.getElementById('printBtn'),box=document.getElementById('errorBox');try{if(!window.JSZip||!window.docx||typeof window.docx.renderAsync!=='function')throw new Error('No fue posible cargar el visor de Word. Verifique la conexión a Internet o use Descargar Word.');const response=await fetch(<?= json_encode($docxUrl,JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE) ?>,{credentials:'same-origin'});if(!response.ok)throw new Error('No fue posible abrir el documento Word generado.');const blob=await response.blob();await window.docx.renderAsync(blob,document.getElementById('docxContainer'),null,{className:'docx',inWrapper:true,ignoreWidth:false,ignoreHeight:false,ignoreFonts:false,breakPages:true,renderHeaders:true,renderFooters:true,useBase64URL:true});status.textContent='Plantilla Word lista';status.style.background='#e9f8ee';status.style.color='#176b32';btn.disabled=false;btn.addEventListener('click',()=>window.print());if(new URLSearchParams(location.search).get('autoprint')==='1')setTimeout(()=>window.print(),700);}catch(err){status.textContent='No se pudo preparar el PDF';box.hidden=false;box.textContent=err.message||String(err);}})();
    </script></body></html><?php exit;
}
function sec_pdf($id){
    $s=sec_study_fetch($id); if(!$s) exit('No encontrado.');
    $pdfRel=trim((string)($s['documento_pdf_ruta']??''));
    if($pdfRel!=='' && is_file(__DIR__.'/'.$pdfRel)){
        $abs=__DIR__.'/'.$pdfRel; $name='Estudio de seguridad - '.$s['nombre_consulta'].'.pdf';
        header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="'.str_replace('"','',basename($name)).'"'); header('Content-Length: '.filesize($abs)); readfile($abs); exit;
    }
    $docxRel=trim((string)($s['documento_word_ruta']??''));
    if($docxRel==='' || !is_file(__DIR__.'/'.$docxRel)){ $files=sec_generate_documents($id); $docxRel=$files['docx']; }
    sec_docx_preview_page($s,$docxRel);
}
function sec_evidence_button($row){ $path=trim((string)($row['evidencia_url']??'')); if($path==='') return '<span class="security-no-evidence">Sin evidencia</span>'; return '<a class="security-evidence-link" href="'.e(sec_public_url($path)).'" target="_blank" rel="noopener">Ver evidencia</a>'; }
function sec_whatsapp_message($s){
    $text="ESTUDIO DE SEGURIDAD\n";
    $text.="Persona: ".$s['nombre_consulta']."\nDocumento: ".$s['tipo_documento'].' '.$s['numero_documento']."\nEmpresa: ".$s['company_name']."\nConcepto: ".$s['concepto'];
    if(trim((string)($s['concepto_detalle']??''))!=='') $text.="\n\n".trim($s['concepto_detalle']);
    return $text;
}
function sec_render_readonly($s,$checks){ $last=''; ?>
<section class="security-readonly-report">
<header class="security-report-header"><div class="security-report-logo"><img src="<?= e(mandatos_logo_url()) ?>" alt="Mandatos"></div><div class="security-report-title"><h1>ESTUDIO DE SEGURIDAD NIVEL 1</h1><strong><?= e($s['company_name']) ?></strong><small>Cerrado: <?= e($s['finalizado_at']?date('d/m/Y H:i',strtotime($s['finalizado_at'])):date('d/m/Y H:i')) ?></small></div><div class="security-report-meta"><div><b>Código:</b> GE-MD-32-B</div><div><b>Versión:</b> 002</div><div><b>Fecha:</b> <?= e(dt($s['fecha_estudio'])) ?></div></div><div class="security-report-client-logo"><?php $logo=company_logo_url($s['company_id']); if($logo): ?><img src="<?= e($logo) ?>" alt="Empresa"><?php else: ?><strong><?= e($s['company_name']) ?></strong><?php endif; ?></div></header>
<div class="security-report-identity"><div><span>Fecha estudio</span><strong><?= e(dt($s['fecha_estudio'])) ?></strong></div><div><span>Nombre</span><strong><?= e($s['nombre_consulta']) ?></strong></div><div><span>Documento</span><strong><?= e(sec_doc_id($s['tipo_documento'],$s['numero_documento'])) ?></strong></div><div><span>Fecha expedición</span><strong><?= e(dt($s['fecha_expedicion_documento'])) ?></strong></div><div><span>Tipo contratación</span><strong><?= e($s['tipo_prospecto']) ?></strong></div><div><span>Observación / cargo</span><strong><?= e($s['observacion']?:'—') ?></strong></div></div>
<div class="security-readonly-table-wrap"><table class="security-readonly-table"><thead><tr><th>Validación</th><th>Resultado</th><th>Detalle</th><th>Evidencia</th></tr></thead><tbody><?php foreach(sec_study_sources() as $src): $r=$checks[$src['key']]??[]; if($last!==$src['cat']): $last=$src['cat']; ?><tr class="security-readonly-category"><th colspan="4"><?= e($last) ?></th></tr><?php endif; ?><tr><td><strong><?= e($src['label']) ?></strong></td><td><?= nl2br(e($r['resultado']??'')) ?></td><td><?= nl2br(e(trim((string)($r['observacion']??''))?:'—')) ?></td><td><?= sec_evidence_button($r) ?></td></tr><?php endforeach; ?></tbody></table></div>
<div class="security-final-concept"><div class="security-final-concept-title"><span>Concepto final</span><?= status_pill($s['estado']) ?></div><div class="security-final-concept-class"><?= e($s['concepto']) ?></div><div class="security-final-concept-text"><?= nl2br(e(trim((string)($s['concepto_detalle']??''))?:'Sin concepto detallado.')) ?></div></div>
</section><?php }
function sec_view($id){
    $s=sec_study_fetch($id); if(!$s) exit('No encontrado.'); $checks=sec_checks_fetch($id); header_html('Estudio de seguridad - '.$s['nombre_consulta']); $group=trim((string)($s['whatsapp_group_url']??'')); $message=sec_whatsapp_message($s); ?>
<div class="card no-print"><div class="actions"><a class="btn secondary" href="<?= e(base_url('security_studies.php')) ?>">Volver</a><a class="btn" href="<?= e(base_url('security_studies.php?action=form&id='.$id.'&edit_closed=1')) ?>">Editar</a><a class="btn secondary" target="_blank" href="<?= e(base_url('security_studies.php?action=pdf&id='.$id)) ?>">Ver PDF</a><?php if($group!==''): ?><button type="button" class="btn whatsapp-btn" onclick='return secShareWhatsApp(<?= json_encode($group,JSON_HEX_APOS|JSON_HEX_QUOT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE) ?>,<?= json_encode($message,JSON_HEX_APOS|JSON_HEX_QUOT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE) ?>)'>Enviar por WhatsApp</button><?php else: ?><a class="btn secondary" href="<?= e(base_url('index.php?page=company_form&id='.$s['company_id'])) ?>">Configurar WhatsApp empresa</a><?php endif; ?><?php if(!empty($s['collaborator_id'])): ?><a class="btn secondary" href="<?= e(base_url('index.php?page=collaborator_view&id='.$s['collaborator_id'])) ?>">Ficha del colaborador</a><?php endif; ?></div></div>
<?php sec_render_readonly($s,$checks); ?>
<script>function secFallbackCopy(t){const a=document.createElement('textarea');a.value=t;a.style.position='fixed';a.style.opacity='0';document.body.appendChild(a);a.focus();a.select();let ok=false;try{ok=document.execCommand('copy')}catch(e){}a.remove();return ok}function secShareWhatsApp(url,msg){const w=window.open(url,'_blank');if(!w){alert('Chrome bloqueó la ventana de WhatsApp. Habilite ventanas emergentes.');return false;}const done=()=>alert('El mensaje fue copiado. En el grupo de WhatsApp abierto, péguelo con Ctrl+V y envíelo.');if(navigator.clipboard&&window.isSecureContext){navigator.clipboard.writeText(msg).then(done).catch(()=>{secFallbackCopy(msg);done()});}else{secFallbackCopy(msg);done();}return false}</script><?php footer_html();
}
function sec_list(){
    $u=current_user(); $company=(int)($_GET['company_id']??0); $q=trim($_GET['q']??'');
    $sql='SELECT s.*,co.nombre company_name,co.whatsapp_group_url FROM security_studies s JOIN companies co ON co.id=s.company_id WHERE 1=1'; $params=[];
    if(user_restricts_company()){ $sql.=' AND s.company_id=?'; $params[]=$u['company_id']; } elseif($company){ $sql.=' AND s.company_id=?'; $params[]=$company; }
    if($q){ $sql.=' AND (s.nombre_consulta LIKE ? OR s.numero_documento LIKE ? OR s.concepto LIKE ?)'; array_push($params,"%$q%","%$q%","%$q%"); }
    $sql.=' ORDER BY s.fecha_estudio DESC,s.id DESC LIMIT 1000'; $st=db()->prepare($sql); $st->execute($params); $rows=$st->fetchAll(); header_html('Estudios de seguridad'); ?>
<div class="card no-print"><form method="get" class="filters"><div><label>Empresa</label><select name="company_id"><option value="">Todas</option><?= company_options($company) ?></select></div><div><label>Búsqueda</label><input name="q" value="<?= e($q) ?>"></div><div><label>&nbsp;</label><button class="btn">Filtrar</button></div></form><div class="actions"><a class="btn ok" href="<?= e(base_url('security_studies.php?action=form')) ?>">Nuevo estudio</a></div></div>
<div class="card"><div class="table-wrap"><table class="sortable"><thead><tr><th>Fecha</th><th>Empresa</th><th>Nombre</th><th>Documento</th><th>Tipo</th><th>Concepto</th><th>Estado</th><th class="no-sort no-print">Acciones</th></tr></thead><tbody><?php foreach($rows as $r): ?><tr><td><?= e(dt($r['fecha_estudio'])) ?></td><td><?= e($r['company_name']) ?></td><td><?= e($r['nombre_consulta']) ?></td><td><?= e($r['numero_documento']) ?></td><td><?= e($r['tipo_prospecto']) ?></td><td><?= e($r['concepto']) ?></td><td><?= status_pill($r['estado']) ?></td><td class="no-print"><?php if(($r['estado']??'')==='Finalizado'): ?><a href="<?= e(base_url('security_studies.php?action=view&id='.$r['id'])) ?>">Ver</a> · <a target="_blank" href="<?= e(base_url('security_studies.php?action=pdf&id='.$r['id'])) ?>">PDF</a> · <a href="<?= e(base_url('security_studies.php?action=form&id='.$r['id'].'&edit_closed=1')) ?>">Editar</a><?php if(!empty($r['whatsapp_group_url'])): ?> · <button type="button" class="security-inline-send" onclick='return secShareWhatsApp(<?= json_encode($r['whatsapp_group_url'],JSON_HEX_APOS|JSON_HEX_QUOT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE) ?>,<?= json_encode(sec_whatsapp_message($r),JSON_HEX_APOS|JSON_HEX_QUOT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE) ?>)'>Enviar</button><?php endif; ?><?php else: ?><a href="<?= e(base_url('security_studies.php?action=form&id='.$r['id'])) ?>">Continuar</a><?php endif; ?> · <a class="btn danger mini" onclick="return confirm('¿Eliminar estudio?')" href="<?= e(base_url('security_studies.php?action=delete&id='.$r['id'])) ?>">Eliminar</a></td></tr><?php endforeach; ?></tbody></table></div></div><script>function secFallbackCopy(t){const a=document.createElement('textarea');a.value=t;a.style.position='fixed';a.style.opacity='0';document.body.appendChild(a);a.focus();a.select();try{document.execCommand('copy')}catch(e){}a.remove()}function secShareWhatsApp(url,msg){const w=window.open(url,'_blank');if(!w){alert('Chrome bloqueó la ventana de WhatsApp. Habilite ventanas emergentes.');return false;}const done=()=>alert('El mensaje fue copiado. En el grupo abierto, péguelo con Ctrl+V y envíelo.');if(navigator.clipboard&&window.isSecureContext){navigator.clipboard.writeText(msg).then(done).catch(()=>{secFallbackCopy(msg);done()});}else{secFallbackCopy(msg);done();}return false}</script><?php footer_html();
}
function sec_form(){
    require_write(); $u=current_user(); $id=(int)($_GET['id']??0); $pref=(int)($_GET['collaborator_id']??0); $returnMode=$_GET['return_mode']??($_POST['return_mode']??'');
    $r=['company_id'=>can_manage_all_companies()?'':($u['company_id']??''),'collaborator_id'=>$pref,'fecha_estudio'=>date('Y-m-d'),'nombre_consulta'=>'','tipo_documento'=>'C.C','numero_documento'=>'','fecha_expedicion_documento'=>'','tipo_prospecto'=>'Personal - Laboral','observacion'=>'','concepto'=>'FAVORABLE SIN NOVEDAD','concepto_detalle'=>'','estado'=>'Borrador','finalizado_at'=>null]; $checks=[];
    if($id){ $row=sec_study_fetch($id); if(!$row) exit('No encontrado.'); $r=array_merge($r,$row); $checks=sec_checks_fetch($id); }
    elseif($pref && ($c=sec_get_collaborator($pref))){ $r['company_id']=$c['company_id']; $r['nombre_consulta']=$c['nombre_completo']; $r['tipo_documento']=$c['tipo_documento']; $r['numero_documento']=$c['numero_documento']; $r['fecha_expedicion_documento']=$c['fecha_expedicion_documento']??''; $r['observacion']=$c['cargo']??''; $r['tipo_prospecto']=($c['tipo_vinculacion']??'')==='Prestación de servicios'?'Personal - Prestación de servicios':'Personal - Laboral'; }
    if($_SERVER['REQUEST_METHOD']==='POST'){
        check_csrf(); $companyId=can_manage_all_companies()?(int)$_POST['company_id']:(int)($u['company_id']?:$_POST['company_id']); $coll=!empty($_POST['collaborator_id'])?(int)$_POST['collaborator_id']:null; $fechaExp=dbdate($_POST['fecha_expedicion_documento']); $action=$_POST['submit_action']??'draft'; $wasClosed=$id && (($r['estado']??'')==='Finalizado'); $closeNow=($action==='close'||$action==='save_closed'||$wasClosed); $estado=$closeNow?'Finalizado':'Borrador';
        $vals=[$companyId,$coll,dbdate($_POST['fecha_estudio'])?:date('Y-m-d'),trim($_POST['nombre_consulta']),trim($_POST['tipo_documento']),trim($_POST['numero_documento']),$fechaExp,$_POST['tipo_prospecto'],trim($_POST['observacion']),$_POST['concepto'],trim($_POST['concepto_detalle']??''),$estado,$closeNow?date('Y-m-d H:i:s'):null];
        if($id){ $vals[]=$u['id']; $vals[]=$id; db()->prepare('UPDATE security_studies SET company_id=?,collaborator_id=?,fecha_estudio=?,nombre_consulta=?,tipo_documento=?,numero_documento=?,fecha_expedicion_documento=?,tipo_prospecto=?,observacion=?,concepto=?,concepto_detalle=?,estado=?,finalizado_at=?,updated_by=? WHERE id=?')->execute($vals); db()->prepare('DELETE FROM security_study_checks WHERE study_id=?')->execute([$id]); }
        else { $vals[]=$u['id']; db()->prepare('INSERT INTO security_studies(company_id,collaborator_id,fecha_estudio,nombre_consulta,tipo_documento,numero_documento,fecha_expedicion_documento,tipo_prospecto,observacion,concepto,concepto_detalle,estado,finalizado_at,created_by) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)')->execute($vals); $id=db()->lastInsertId(); }
        foreach(sec_study_sources() as $src){ $key=$src['key']; $existing=$checks[$key]['evidencia_url']??''; $evi=sec_save_evidence($key,$companyId,$existing); db()->prepare('INSERT INTO security_study_checks(study_id,categoria,clave,item,fuente_url,resultado,observacion,evidencia_url,fecha_validacion) VALUES(?,?,?,?,?,?,?,?,?)')->execute([$id,$src['cat'],$key,$src['label'],$src['url'],trim($_POST['check_result'][$key]??''),trim($_POST['check_obs'][$key]??''),$evi,date('Y-m-d')]); }
        if($coll) db()->prepare('UPDATE collaborators SET fecha_expedicion_documento=?,estudio_seguridad_id=?,estudio_seguridad_resultado=?,estudio_seguridad_fecha=?,estudio_seguridad_observacion=?,updated_by=? WHERE id=?')->execute([$fechaExp,$id,sec_concept_to_collaborator_result($_POST['concepto']),dbdate($_POST['fecha_estudio'])?:date('Y-m-d'),trim($_POST['concepto_detalle']??''),$u['id']??null,$coll]);
        if($closeNow){ try{ $generated=sec_generate_documents($id); }catch(Throwable $e){ if(!$wasClosed){ db()->prepare('UPDATE security_studies SET estado="Borrador",finalizado_at=NULL WHERE id=?')->execute([$id]); } flash('err','La información quedó guardada, pero el estudio no se cerró porque no fue posible generar la plantilla Word: '.$e->getMessage()); header('Location: '.base_url('security_studies.php?action=form&id='.$id.'&edit_closed=1')); exit; } if(!empty($generated['pdf'])) flash('ok',$wasClosed?'Cambios guardados y PDF actualizado.':'Estudio cerrado, PDF generado y documento vinculado.'); else flash('ok',$wasClosed?'Cambios guardados. Use el botón PDF para abrir la plantilla Word y guardarla como PDF desde Chrome.':'Estudio cerrado y plantilla Word generada. Use el botón PDF para visualizarla y guardarla como PDF desde Chrome.'); header('Location: '.base_url('security_studies.php?action=view&id='.$id)); exit; }
                flash('ok','Borrador guardado.'); header('Location: '.base_url('security_studies.php?action=form&id='.$id)); exit;
    }
    $sql='SELECT id,company_id,nombre_completo,tipo_documento,numero_documento,fecha_expedicion_documento,cargo,tipo_vinculacion FROM collaborators WHERE 1=1'; $params=[]; if(user_restricts_company()){ $sql.=' AND company_id=?'; $params[]=$u['company_id']; } $sql.=' ORDER BY numero_documento,nombre_completo'; $st=db()->prepare($sql); $st->execute($params); $colls=$st->fetchAll(); $linked=$r['collaborator_id']?sec_get_collaborator($r['collaborator_id']):null;
    header_html($id?'Editar estudio de seguridad':'Nuevo estudio de seguridad'); ?>
    <?php if($linked): ?><div class="card"><div class="actions"><span class="pill ok">Vinculado</span><strong><?= e($linked['nombre_completo']) ?></strong><a class="btn secondary small" href="<?= e(base_url('index.php?page=collaborator_view&id='.$linked['id'])) ?>">Ver ficha</a></div></div><?php endif; ?>
    <div class="card security-study-card"><div class="security-intro"><strong>Registro manual trazable.</strong> Abra la fuente en ventana flotante, realice la consulta y pegue o cargue el pantallazo en la casilla de evidencia correspondiente.</div>
    <form method="post" enctype="multipart/form-data"><?= csrf_field() ?><input type="hidden" name="return_mode" value="<?= e($returnMode) ?>">
    <div class="grid cols-3"><div class="field"><label>Empresa</label><select id="companySelect" name="company_id" <?= user_restricts_company()?'disabled':'' ?>><?= company_options($r['company_id']) ?></select></div><div class="field"><label>Prospecto / colaborador</label><select id="collaboratorSelect" name="collaborator_id"><option value="">Persona externa</option><?php foreach($colls as $c): ?><option data-nombre="<?= e($c['nombre_completo']) ?>" data-tipodoc="<?= e($c['tipo_documento']) ?>" data-numdoc="<?= e($c['numero_documento']) ?>" data-fexp="<?= e($c['fecha_expedicion_documento']) ?>" data-cargo="<?= e($c['cargo']) ?>" value="<?= e($c['id']) ?>" <?= (string)$r['collaborator_id']===(string)$c['id']?'selected':'' ?>><?= e($c['numero_documento'].' - '.$c['nombre_completo']) ?></option><?php endforeach; ?></select></div><div class="field"><label>Fecha estudio</label><input type="date" name="fecha_estudio" value="<?= e($r['fecha_estudio']) ?>"></div><div class="field"><label>Nombre consultado</label><input id="secNombre" name="nombre_consulta" value="<?= e($r['nombre_consulta']) ?>" required></div><div class="field"><label>Tipo documento</label><input id="secTipoDoc" name="tipo_documento" value="<?= e($r['tipo_documento']) ?>"></div><div class="field"><label>Número documento</label><input id="secNumDoc" name="numero_documento" value="<?= e($r['numero_documento']) ?>" required></div><div class="field"><label>Fecha expedición</label><input id="secFExp" type="date" name="fecha_expedicion_documento" value="<?= e($r['fecha_expedicion_documento']) ?>"></div><div class="field"><label>Prospecto de contratación</label><select name="tipo_prospecto"><?= option_list(sec_contract_types(),$r['tipo_prospecto']) ?></select></div><div class="field"><label>Observación inicial / cargo</label><input id="secObs" name="observacion" value="<?= e($r['observacion']) ?>"></div></div>
    <h3>Validaciones</h3><div class="security-checks"><?php $last=''; foreach(sec_study_sources() as $src): $ck=$checks[$src['key']]??[]; if($last!==$src['cat']): $last=$src['cat']; ?><div class="security-category"><?= e($last) ?></div><?php endif; ?><div class="security-check-row" data-type="<?= e($src['type']) ?>"><div class="security-check-main"><strong><?= e($src['label']) ?></strong><?php if($src['url']): ?><a class="btn secondary small" href="<?= e($src['url']) ?>" onclick="return openFloating(this.href,'consulta_<?= e($src['key']) ?>')">Abrir consulta</a><?php endif; ?></div><div class="security-result"><?php if(in_array($src['type'],['binary','yesdetail'],true)): ?><select class="sec-result-select" name="check_result[<?= e($src['key']) ?>]"><?= option_list($src['type']==='binary'?sec_binary_results():sec_yesdetail_results(),$ck['resultado']??'NO','Seleccione') ?></select><?php elseif($src['type']==='date'): ?><input type="date" name="check_result[<?= e($src['key']) ?>]" value="<?= e($ck['resultado']??'') ?>"><?php elseif($src['type']==='textlong'): ?><textarea name="check_result[<?= e($src['key']) ?>]" placeholder="Escriba el resultado completo de la consulta"><?= e($ck['resultado']??'') ?></textarea><?php else: ?><input name="check_result[<?= e($src['key']) ?>]" value="<?= e($ck['resultado']??'') ?>" placeholder="Escriba el resultado obtenido"><?php endif; ?></div><div class="security-observation <?= in_array($src['type'],['binary','yesdetail'],true)?'conditional-observation':'' ?>"><label><?= e($src['detail']??'Detalle / observación cuando el resultado sea SÍ') ?></label><input name="check_obs[<?= e($src['key']) ?>]" value="<?= e($ck['observacion']??'') ?>"></div><div class="security-evidence" tabindex="0" data-key="<?= e($src['key']) ?>"><input type="hidden" class="evidence-path" name="check_evidence[<?= e($src['key']) ?>]" value="<?= e($ck['evidencia_url']??'') ?>"><input type="file" class="evidence-file" accept="image/*,application/pdf"><button type="button" class="btn secondary small paste-evidence">Pegar captura</button><span class="hint">La captura se comprime y carga inmediatamente. También puede usar Ctrl+V o arrastrar una imagen.</span><span class="evidence-upload-status" aria-live="polite"></span><div class="evidence-preview"><?php if(!empty($ck['evidencia_url'])): $url=sec_public_url($ck['evidencia_url']); if(preg_match('/\.(png|jpe?g|webp)$/i',$ck['evidencia_url'])): ?><a href="<?= e($url) ?>" target="_blank"><img src="<?= e($url) ?>" alt="Evidencia"></a><?php else: ?><a href="<?= e($url) ?>" target="_blank">Abrir evidencia</a><?php endif; endif; ?></div></div></div><?php endforeach; ?></div>
    <div class="security-concept-box"><div class="field"><label>Clasificación del concepto</label><select name="concepto"><?= option_list(sec_concepts(),$r['concepto']) ?></select></div><div class="field"><label>Concepto detallado / mensaje a remitir</label><textarea name="concepto_detalle" rows="5" placeholder="Redacte el concepto completo, conclusiones y recomendaciones."><?= e($r['concepto_detalle']??'') ?></textarea></div><div class="field"><label>Estado</label><div class="security-state-display"><?= status_pill($r['estado']) ?></div></div></div>
    <div class="actions"><?php if(($r['estado']??'')==='Finalizado'): ?><button class="btn ok" name="submit_action" value="save_closed">Guardar cambios</button><a class="btn secondary" href="<?= e(base_url('security_studies.php?action=view&id='.$id)) ?>">Cancelar</a><?php else: ?><button class="btn" name="submit_action" value="draft">Guardar borrador</button><button class="btn ok" name="submit_action" value="close" onclick="return confirm('¿Cerrar el estudio y generar el PDF definitivo desde la plantilla Word?')">Cerrar estudio</button><?php endif; ?></div></form></div>
    <script>
    function toggleObservation(row){const sel=row.querySelector('.sec-result-select'),box=row.querySelector('.conditional-observation');if(!sel||!box)return;const on=sel.value==='SI';box.classList.toggle('is-enabled',on);box.querySelector('input').disabled=!on;if(!on)box.querySelector('input').value='';}
    function showEvidence(zone,src,isImage=true){const p=zone.querySelector('.evidence-preview');p.innerHTML='';const a=document.createElement('a');a.href=src;a.target='_blank';a.rel='noopener';if(isImage){const img=document.createElement('img');img.src=src;img.alt='Evidencia';a.appendChild(img);}else{a.textContent='Abrir evidencia cargada';}p.appendChild(a);}
    function evidenceStatus(zone,text,kind=''){const el=zone.querySelector('.evidence-upload-status');el.textContent=text;el.className='evidence-upload-status '+kind;}
    async function compressEvidenceImage(file){
        const bitmap=await createImageBitmap(file);const maxSide=1600;let w=bitmap.width,h=bitmap.height;const scale=Math.min(1,maxSide/Math.max(w,h));w=Math.max(1,Math.round(w*scale));h=Math.max(1,Math.round(h*scale));
        const canvas=document.createElement('canvas');canvas.width=w;canvas.height=h;const ctx=canvas.getContext('2d',{alpha:false});ctx.fillStyle='#fff';ctx.fillRect(0,0,w,h);ctx.drawImage(bitmap,0,0,w,h);if(bitmap.close)bitmap.close();
        let quality=.82;let blob=await new Promise(r=>canvas.toBlob(r,'image/jpeg',quality));while(blob&&blob.size>1200000&&quality>.5){quality-=.08;blob=await new Promise(r=>canvas.toBlob(r,'image/jpeg',quality));}
        if(!blob)throw new Error('No fue posible comprimir la imagen.');return new File([blob],'captura_'+Date.now()+'.jpg',{type:'image/jpeg'});
    }
    async function uploadEvidence(zone,file){
        if(!file)return;const maxBytes=1800000;zone.dataset.uploading='1';evidenceStatus(zone,'Preparando evidencia…','is-uploading');
        try{
            let uploadFile=file;if(file.type.startsWith('image/'))uploadFile=await compressEvidenceImage(file);else if(file.type==='application/pdf'&&file.size>maxBytes)throw new Error('El PDF supera 1,8 MB. Comprímalo antes de cargarlo.');
            if(uploadFile.size>maxBytes)throw new Error('La evidencia supera 1,8 MB después de comprimirla.');
            const form=zone.closest('form'),fd=new FormData();fd.append('csrf',form.querySelector('input[name="csrf"]').value);fd.append('company_id',document.getElementById('companySelect')?.value||'');fd.append('evidence_key',zone.dataset.key||'EVIDENCIA');fd.append('evidence_upload',uploadFile,uploadFile.name);
            const response=await fetch('security_studies.php?action=upload_evidence',{method:'POST',body:fd,credentials:'same-origin'});const text=await response.text();let data;try{data=JSON.parse(text);}catch(e){if(response.status===413)throw new Error('El servidor rechazó el archivo por tamaño. Use una captura más pequeña.');throw new Error('El servidor no devolvió una respuesta válida al cargar la evidencia.');}
            if(!response.ok||!data.ok)throw new Error(data.message||'No fue posible cargar la evidencia.');zone.querySelector('.evidence-path').value=data.path;showEvidence(zone,data.url,!!data.is_image);evidenceStatus(zone,'Evidencia cargada correctamente.','is-ok');
        }catch(err){evidenceStatus(zone,err.message||'Error al cargar evidencia.','is-error');alert(err.message||'Error al cargar evidencia.');}
        finally{delete zone.dataset.uploading;const input=zone.querySelector('.evidence-file');if(input)input.value='';}
    }
    async function pasteEvidence(zone){try{const items=await navigator.clipboard.read();for(const item of items){const type=item.types.find(x=>x.startsWith('image/'));if(type){const blob=await item.getType(type);await uploadEvidence(zone,new File([blob],'captura_portapapeles.png',{type:blob.type||'image/png'}));return;}}alert('No hay una imagen en el portapapeles.');}catch(e){zone.focus();alert('Use Ctrl+V dentro del recuadro de evidencia o seleccione el archivo.');}}
    document.addEventListener('DOMContentLoaded',()=>{
        document.querySelectorAll('.security-check-row').forEach(toggleObservation);document.querySelectorAll('.sec-result-select').forEach(s=>s.addEventListener('change',()=>toggleObservation(s.closest('.security-check-row'))));
        document.querySelectorAll('.security-evidence').forEach(zone=>{
            zone.querySelector('.paste-evidence').addEventListener('click',()=>pasteEvidence(zone));
            zone.addEventListener('paste',e=>{const item=[...e.clipboardData.items].find(i=>i.type.startsWith('image/'));if(!item)return;e.preventDefault();uploadEvidence(zone,new File([item.getAsFile()],'captura_pegada.png',{type:item.type||'image/png'}));});
            zone.addEventListener('dragover',e=>{e.preventDefault();zone.classList.add('is-dragover')});zone.addEventListener('dragleave',()=>zone.classList.remove('is-dragover'));zone.addEventListener('drop',e=>{e.preventDefault();zone.classList.remove('is-dragover');const file=e.dataTransfer.files[0];if(file)uploadEvidence(zone,file);});
            zone.querySelector('.evidence-file').addEventListener('change',e=>uploadEvidence(zone,e.target.files[0]));
        });
        const form=document.querySelector('.security-study-card form');if(form)form.addEventListener('submit',e=>{if(document.querySelector('.security-evidence[data-uploading="1"]')){e.preventDefault();alert('Espere a que terminen de cargarse las evidencias antes de guardar el estudio.');}});
        const c=document.getElementById('collaboratorSelect');if(c)c.addEventListener('change',()=>{const o=c.selectedOptions[0];if(!o||!o.value)return;secNombre.value=o.dataset.nombre||'';secTipoDoc.value=o.dataset.tipodoc||'';secNumDoc.value=o.dataset.numdoc||'';secFExp.value=o.dataset.fexp||'';secObs.value=o.dataset.cargo||'';});
    });
    </script><?php footer_html();
}
function sec_delete($id){ require_write(); $s=sec_study_fetch($id); if(!$s) exit('No encontrado.'); db()->prepare('DELETE FROM security_studies WHERE id=?')->execute([$id]); flash('ok','Estudio eliminado.'); header('Location: '.base_url('security_studies.php')); exit; }
$action=$_GET['action']??'list';
try{
    if($action==='upload_evidence') sec_upload_evidence_action();
    elseif($action==='form') sec_form();
    elseif($action==='view') sec_view((int)($_GET['id']??0));
    elseif($action==='pdf') sec_pdf((int)($_GET['id']??0));
    elseif($action==='delete') sec_delete((int)($_GET['id']??0));
    else sec_list();
}catch(Throwable $e){ header_html('Estudios de seguridad'); echo '<div class="card alert err">'.e($e->getMessage()).'</div>'; footer_html(); }
