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

function contract_doc_types(){ return ['Contrato prestación de servicios','Acta de compromiso','Contrato laboral','Otro documento contractual']; }
function safe_contract_filename($name){ $name=preg_replace('/[^A-Za-z0-9_\-\. ]+/','',trim((string)$name)); $name=preg_replace('/\s+/','_',$name); return $name ?: 'documento'; }
function contract_storage_dir($sub){ $dir=rtrim(cfg('upload_dir'),'/').'/'.$sub; if(!is_dir($dir)) mkdir($dir,0775,true); return $dir; }
function contract_relative_path($abs){ return str_replace(rtrim(__DIR__,'/').'/', '', $abs); }
function contract_company_select($selected=null){ return company_options($selected); }
function contract_template_options($company_id,$selected=null,$tipo=null){
    $params=[]; $sql="SELECT id,nombre,tipo_documento FROM contract_templates WHERE estado='Activo'";
    if($company_id){ $sql.=' AND company_id=?'; $params[]=$company_id; }
    if($tipo){ $sql.=' AND tipo_documento=?'; $params[]=$tipo; }
    $sql.=' ORDER BY tipo_documento,nombre'; $st=db()->prepare($sql); $st->execute($params);
    $html='<option value="">Seleccione plantilla</option>';
    foreach($st->fetchAll() as $t){ $sel=((string)$selected===(string)$t['id'])?' selected':''; $html.='<option value="'.e($t['id']).'"'.$sel.'>'.e($t['tipo_documento'].' - '.$t['nombre']).'</option>'; }
    return $html;
}
function contract_field($row,$keys,$default=''){
    foreach((array)$keys as $k){ if(isset($row[$k]) && trim((string)$row[$k])!=='') return trim((string)$row[$k]); }
    return $default;
}
function contract_doc_id($tipo,$numero){ $tipo=trim((string)$tipo); $numero=trim((string)$numero); return trim(($tipo?$tipo.' ':'').$numero); }
function contract_replacements($collaborator_id){
    $st=db()->prepare("SELECT c.*, co.nombre company_nombre, co.nit company_nit, co.direccion company_direccion, co.telefono_contacto company_telefono, co.correo_contacto company_correo, co.contacto company_contacto, co.ciudad company_ciudad FROM collaborators c JOIN companies co ON co.id=c.company_id WHERE c.id=? LIMIT 1");
    $st->execute([(int)$collaborator_id]); $r=$st->fetch(); if(!$r) throw new RuntimeException('No se encontró el colaborador.');
    if(!can_read_company($r['company_id'])) throw new RuntimeException('No autorizado para esta empresa.');
    $nombre=contract_field($r,['nombre_completo']);
    $empresaNombre=contract_field($r,['company_nombre']);
    $empresaNit=contract_field($r,['company_nit']);
    $tipoDoc=contract_field($r,['tipo_documento']); $numDoc=contract_field($r,['numero_documento']);
    $fechaIngreso=contract_field($r,['fecha_ingreso'],date('Y-m-d'));
    $rep=[
        '{{F_INICIO}}'=>dt($fechaIngreso),
        '{{FECHA_INICIO}}'=>dt($fechaIngreso),
        '{{FECHA_GENERACION}}'=>date('d/m/Y'),
        '{{EMPRESA_NOMBRE}}'=>$empresaNombre,
        '{{EMPRESA_NIT}}'=>$empresaNit,
        '{{EMPRESA_ID}}'=>($empresaNit ? 'NIT. No. '.$empresaNit : ''),
        '{{EMPRESA_DIR}}'=>contract_field($r,['company_direccion','company_ciudad']),
        '{{EMPRESA_DIRECCION}}'=>contract_field($r,['company_direccion','company_ciudad']),
        '{{EMPRESA_TEL}}'=>contract_field($r,['company_telefono']),
        '{{EMPRESA_TELEFONO}}'=>contract_field($r,['company_telefono']),
        '{{EMPRESA_EMAIL}}'=>contract_field($r,['company_correo']),
        '{{EMPRESA_CORREO}}'=>contract_field($r,['company_correo']),
        '{{EMPRESA_CONTACTO}}'=>contract_field($r,['company_contacto']),
        '{{CONTRATISTA_NOMBRE}}'=>$nombre,
        '{{COLABORADOR_NOMBRE}}'=>$nombre,
        '{{CONTRATISTA_ID}}'=>contract_doc_id($tipoDoc,$numDoc),
        '{{COLABORADOR_ID}}'=>contract_doc_id($tipoDoc,$numDoc),
        '{{CONTRATISTA_DOC_TIPO}}'=>$tipoDoc,
        '{{CONTRATISTA_DOC_NUMERO}}'=>$numDoc,
        '{{CONTRATISTA_DIR}}'=>contract_field($r,['direccion','address']),
        '{{CONTRATISTA_DIRECCION}}'=>contract_field($r,['direccion','address']),
        '{{CONTRATISTA_TEL}}'=>contract_field($r,['telefono','celular','phone']),
        '{{CONTRATISTA_TELEFONO}}'=>contract_field($r,['telefono','celular','phone']),
        '{{CONTRATISTA_EMAIL}}'=>contract_field($r,['correo_electronico','email','correo']),
        '{{CONTRATISTA_CORREO}}'=>contract_field($r,['correo_electronico','email','correo']),
        '{{CARGO}}'=>contract_field($r,['cargo']),
        '{{AREA}}'=>contract_field($r,['area']),
        '{{TIPO_CONTRATO}}'=>contract_field($r,['tipo_vinculacion','tipo_contrato']),
        '{{SALARIO}}'=>money(contract_field($r,['salario_base'])),
    ];
    return [$r,$rep];
}
function replace_docx_placeholders($templateAbs,$destAbs,$replacements){
    if(!class_exists('ZipArchive')) throw new RuntimeException('El servidor no tiene habilitada la extensión PHP ZipArchive.');
    copy($templateAbs,$destAbs);
    $zip=new ZipArchive();
    if($zip->open($destAbs)!==true) throw new RuntimeException('No fue posible abrir el DOCX generado.');
    $total=0;
    for($i=0;$i<$zip->numFiles;$i++){
        $name=$zip->getNameIndex($i);
        if(!preg_match('#^word/(document|header\d*|footer\d*|footnotes|endnotes|comments)\.xml$#',$name)) continue;
        $xml=$zip->getFromName($name); if($xml===false) continue;
        foreach($replacements as $k=>$v){ $count=0; $xml=str_replace($k, htmlspecialchars((string)$v, ENT_XML1|ENT_QUOTES, 'UTF-8'), $xml, $count); $total += $count; }
        $zip->addFromString($name,$xml);
    }
    $zip->close();
    return $total;
}
function handle_contract_template_upload(){
    require_write(); check_csrf();
    $company_id=can_manage_all_companies()?(int)$_POST['company_id']:(int)(current_user()['company_id'] ?: $_POST['company_id']);
    if(!$company_id) throw new RuntimeException('Debe seleccionar empresa.');
    if(empty($_FILES['template_docx']) || $_FILES['template_docx']['error']!==UPLOAD_ERR_OK) throw new RuntimeException('Debe cargar una plantilla DOCX.');
    $f=$_FILES['template_docx'];
    $ext=strtolower(pathinfo($f['name'],PATHINFO_EXTENSION)); if($ext!=='docx') throw new RuntimeException('La plantilla debe ser .docx');
    $dir=contract_storage_dir('contract_templates/company_'.$company_id);
    $safe='plantilla_'.date('Ymd_His').'_'.bin2hex(random_bytes(4)).'.docx';
    $dest=$dir.'/'.$safe; move_uploaded_file($f['tmp_name'],$dest);
    db()->prepare('INSERT INTO contract_templates(company_id,tipo_documento,nombre,descripcion,nombre_original,ruta,created_by) VALUES(?,?,?,?,?,?,?)')
        ->execute([$company_id,$_POST['tipo_documento'],trim($_POST['nombre']),trim($_POST['descripcion'] ?? ''),$f['name'],contract_relative_path($dest),current_user()['id'] ?? null]);
    flash('ok','Plantilla cargada correctamente.');
}
function handle_contract_generate(){
    require_write(); check_csrf();
    $template_id=(int)$_POST['template_id']; $collaborator_id=(int)$_POST['collaborator_id'];
    if(!$template_id || !$collaborator_id) throw new RuntimeException('Debe seleccionar plantilla y colaborador.');
    $st=db()->prepare('SELECT t.*, co.nombre company_name FROM contract_templates t JOIN companies co ON co.id=t.company_id WHERE t.id=? LIMIT 1'); $st->execute([$template_id]); $tpl=$st->fetch();
    if(!$tpl) throw new RuntimeException('No se encontró la plantilla.');
    [$coll,$rep]=contract_replacements($collaborator_id);
    if((int)$coll['company_id'] !== (int)$tpl['company_id']) throw new RuntimeException('La plantilla y el colaborador no pertenecen a la misma empresa.');
    $src=__DIR__.'/'.$tpl['ruta']; if(!file_exists($src)) throw new RuntimeException('No se encontró el archivo físico de la plantilla.');
    $dir=contract_storage_dir('generated_contracts/company_'.$tpl['company_id'].'/'.date('Y/m'));
    $base=safe_contract_filename($tpl['tipo_documento'].'_'.$coll['numero_documento'].'_'.$coll['nombre_completo'].'_'.date('Ymd_His')).'.docx';
    $dest=$dir.'/'.$base; $total=replace_docx_placeholders($src,$dest,$rep);
    db()->prepare('INSERT INTO generated_contracts(company_id,collaborator_id,template_id,tipo_documento,nombre_archivo,ruta,reemplazos_json,total_reemplazos,created_by) VALUES(?,?,?,?,?,?,?,?,?)')
        ->execute([$tpl['company_id'],$collaborator_id,$template_id,$tpl['tipo_documento'],$base,contract_relative_path($dest),json_encode($rep,JSON_UNESCAPED_UNICODE),$total,current_user()['id'] ?? null]);
    $id=db()->lastInsertId();
    flash($total>0?'ok':'err',$total>0?'Documento generado correctamente.':'Documento generado, pero no se encontró ningún marcador para reemplazar. Revise que la plantilla tenga placeholders como {{CONTRATISTA_NOMBRE}}.');
    header('Location: '.base_url('contracts.php?action=download&id='.$id)); exit;
}
function contract_download($id){
    $st=db()->prepare('SELECT g.*, c.company_id FROM generated_contracts g JOIN collaborators c ON c.id=g.collaborator_id WHERE g.id=? LIMIT 1'); $st->execute([(int)$id]); $g=$st->fetch();
    if(!$g || !can_read_company($g['company_id'])) exit('No autorizado');
    $path=__DIR__.'/'.$g['ruta']; if(!file_exists($path)) exit('Archivo no encontrado');
    header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
    header('Content-Disposition: attachment; filename="'.basename($g['nombre_archivo']).'"');
    header('Content-Length: '.filesize($path)); readfile($path); exit;
}
function contract_delete_template($id){ require_write(); $st=db()->prepare('SELECT * FROM contract_templates WHERE id=? LIMIT 1'); $st->execute([(int)$id]); $t=$st->fetch(); if(!$t || !can_read_company($t['company_id'])) exit('No autorizado'); try{ db()->prepare('UPDATE contract_templates SET estado="Inactivo", updated_by=? WHERE id=?')->execute([current_user()['id'] ?? null,$id]); flash('ok','Plantilla desactivada correctamente.'); }catch(Throwable $e){ flash('err','No fue posible desactivar la plantilla: '.$e->getMessage()); } header('Location: '.base_url('contracts.php')); exit; }
function contract_delete_generated($id){ require_write(); $st=db()->prepare('SELECT * FROM generated_contracts WHERE id=? LIMIT 1'); $st->execute([(int)$id]); $g=$st->fetch(); if(!$g || !can_read_company($g['company_id'])) exit('No autorizado'); try{ db()->prepare('DELETE FROM generated_contracts WHERE id=?')->execute([$id]); flash('ok','Documento generado eliminado del historial.'); }catch(Throwable $e){ flash('err','No fue posible eliminar el documento: '.$e->getMessage()); } header('Location: '.base_url('contracts.php')); exit; }
$action=$_GET['action'] ?? $_POST['action'] ?? 'home';
try{
    if($action==='upload_template') { handle_contract_template_upload(); header('Location: '.base_url('contracts.php')); exit; }
    if($action==='generate') { handle_contract_generate(); }
    if($action==='download') { contract_download((int)($_GET['id'] ?? 0)); }
    if($action==='delete_template') { contract_delete_template((int)($_GET['id'] ?? 0)); }
    if($action==='delete_generated') { contract_delete_generated((int)($_GET['id'] ?? 0)); }
}catch(Throwable $e){ flash('err',$e->getMessage()); }

$company=(int)($_GET['company_id'] ?? 0); $prefColl=(int)($_GET['collaborator_id'] ?? 0); $tipo=$_GET['tipo_documento'] ?? '';
$where=' WHERE 1=1 '; $params=[]; $u=current_user();
if(user_restricts_company()){ $where.=' AND t.company_id=? '; $params[]=$u['company_id']; }
elseif($company){ $where.=' AND t.company_id=? '; $params[]=$company; }
if($tipo){ $where.=' AND t.tipo_documento=? '; $params[]=$tipo; }
$st=db()->prepare('SELECT t.*, co.nombre company_name FROM contract_templates t JOIN companies co ON co.id=t.company_id '.$where.' ORDER BY t.created_at DESC LIMIT 200'); $st->execute($params); $templates=$st->fetchAll();
$whereG=' WHERE 1=1 '; $paramsG=[];
if(user_restricts_company()){ $whereG.=' AND g.company_id=? '; $paramsG[]=$u['company_id']; } elseif($company){ $whereG.=' AND g.company_id=? '; $paramsG[]=$company; }
if($prefColl){ $whereG.=' AND g.collaborator_id=? '; $paramsG[]=$prefColl; }
$st=db()->prepare('SELECT g.*, co.nombre company_name, c.nombre_completo, c.numero_documento FROM generated_contracts g JOIN companies co ON co.id=g.company_id JOIN collaborators c ON c.id=g.collaborator_id '.$whereG.' ORDER BY g.created_at DESC LIMIT 200'); $st->execute($paramsG); $generated=$st->fetchAll();
header_html('Contratos y documentos'); ?>
<div class="sticky-controls no-print"><div class="card"><form method="get" class="filters"><div><label>Empresa</label><select id="companySelect" name="company_id" onchange="this.form.submit()"><option value="">Todas</option><?= contract_company_select($company) ?></select></div><div><label>Tipo documento</label><select name="tipo_documento"><?= option_list(contract_doc_types(),$tipo,'Todos') ?></select></div><div><label>Colaborador</label><select id="collaboratorSelect" class="combo-collaborator" name="collaborator_id"><?= collaborator_options($company,$prefColl) ?></select></div><div><label>&nbsp;</label><button class="btn" type="submit">Filtrar</button></div></form></div></div>
<div class="grid cols-2">
<div class="card"><h3>Cargar plantilla por empresa</h3><p class="hint">Suba un DOCX con la estructura fija del contrato y placeholders en carátula y firmas.</p><form method="post" enctype="multipart/form-data"><?= csrf_field() ?><input type="hidden" name="action" value="upload_template"><div class="field"><label>Empresa</label><select name="company_id" <?= user_restricts_company()?'disabled':'' ?>><?= contract_company_select($company ?: (can_manage_all_companies() ? '' : ($u['company_id'] ?? ''))) ?></select></div><div class="field"><label>Tipo</label><select name="tipo_documento"><?= option_list(contract_doc_types(),'Contrato prestación de servicios') ?></select></div><div class="field"><label>Nombre de plantilla</label><input name="nombre" value="Contrato tipo prestación de servicios" required></div><div class="field"><label>Descripción</label><textarea name="descripcion"></textarea></div><div class="field"><label>Archivo DOCX</label><input type="file" name="template_docx" accept=".docx" required></div><button class="btn" type="submit">Subir plantilla</button></form></div>
<div class="card"><h3>Generar documento</h3><form method="post"><?= csrf_field() ?><input type="hidden" name="action" value="generate"><div class="field"><label>Colaborador</label><select id="collaboratorSelectGenerate" class="combo-collaborator" name="collaborator_id" required><?= collaborator_options($company,$prefColl) ?></select></div><div class="field"><label>Plantilla</label><select name="template_id" required><?= contract_template_options($company,null,$tipo) ?></select></div><button class="btn ok" type="submit">Generar Word</button><p class="hint">El archivo se genera en Word conservando estructura, tablas, logos, márgenes y estilos de la plantilla cargada.</p></form></div>
</div>
<div class="card"><h3>Plantillas disponibles</h3><div class="table-wrap"><table class="sortable"><thead><tr><th>Empresa</th><th>Tipo</th><th>Nombre</th><th>Archivo</th><th>Estado</th><th>Fecha</th><th class="no-sort no-print">Acciones</th></tr></thead><tbody><?php foreach($templates as $t): ?><tr><td><?= e($t['company_name']) ?></td><td><?= e($t['tipo_documento']) ?></td><td><?= e($t['nombre']) ?></td><td><?= e($t['nombre_original']) ?></td><td><?= status_pill($t['estado']) ?></td><td><?= e(dt($t['created_at'])) ?></td><td class="no-print"><a class="btn danger mini" onclick="return confirm('¿Desactivar esta plantilla?')" href="<?= e(base_url('contracts.php?action=delete_template&id='.$t['id'])) ?>">Eliminar</a></td></tr><?php endforeach; ?></tbody></table></div></div>
<div class="card"><h3>Documentos generados</h3><div class="table-wrap"><table class="sortable"><thead><tr><th>Fecha</th><th>Empresa</th><th>Colaborador</th><th>Documento</th><th>Tipo</th><th>Reemplazos</th><th>Descargar</th><th class="no-sort no-print">Acciones</th></tr></thead><tbody><?php foreach($generated as $g): ?><tr><td><?= e(dt($g['created_at'])) ?></td><td><?= e($g['company_name']) ?></td><td><?= e($g['nombre_completo']) ?></td><td><?= e($g['numero_documento']) ?></td><td><?= e($g['tipo_documento']) ?></td><td><?= e($g['total_reemplazos']) ?></td><td><a href="<?= e(base_url('contracts.php?action=download&id='.$g['id'])) ?>">Descargar Word</a></td><td class="no-print"><a class="btn danger mini" onclick="return confirm('¿Eliminar este documento generado?')" href="<?= e(base_url('contracts.php?action=delete_generated&id='.$g['id'])) ?>">Eliminar</a></td></tr><?php endforeach; ?></tbody></table></div></div>
<div class="card"><h3>Marcadores disponibles</h3><p class="hint">Estos marcadores deben escribirse en la plantilla Word exactamente como aparecen.</p><div class="table-wrap"><table><thead><tr><th>Marcador</th><th>Dato que inserta</th></tr></thead><tbody>
<?php foreach(['{{F_INICIO}}'=>'Fecha de inicio del colaborador','{{EMPRESA_NOMBRE}}'=>'Nombre de la empresa contratante','{{EMPRESA_ID}}'=>'NIT / ID de la empresa','{{EMPRESA_DIR}}'=>'Dirección de la empresa','{{EMPRESA_TEL}}'=>'Teléfono de la empresa','{{EMPRESA_EMAIL}}'=>'Correo de la empresa','{{CONTRATISTA_NOMBRE}}'=>'Nombre completo del contratista / colaborador','{{CONTRATISTA_ID}}'=>'Tipo y número de documento','{{CONTRATISTA_DIR}}'=>'Dirección del contratista','{{CONTRATISTA_TEL}}'=>'Teléfono del contratista','{{CONTRATISTA_EMAIL}}'=>'Correo del contratista','{{CARGO}}'=>'Cargo','{{AREA}}'=>'Área','{{FECHA_GENERACION}}'=>'Fecha de generación del documento'] as $k=>$v): ?><tr><td><code><?= e($k) ?></code></td><td><?= e($v) ?></td></tr><?php endforeach; ?>
</tbody></table></div></div>
<?php footer_html();
