<?php
// modules/estudiante/vinculacion.php — Bitacoras + Informe + Calificaciones
require_once __DIR__.'/../../config/app.php';
require_once __DIR__.'/../../config/onedrive.php';
require_once __DIR__.'/../../includes/OneDriveStorage.php';
require_once __DIR__.'/../../includes/auth.php';
require_once __DIR__.'/../../includes/functions.php';
require_once __DIR__.'/../../includes/flash.php';
requireRol(ROL_ESTUDIANTE);

$user=currentUser();$db=getDB();$pageTitle='Bitacoras Vinculacion';

$est=$db->prepare("SELECT id_estudiante FROM estudiantes WHERE id_usuario=:u");
$est->execute([':u'=>$user['id']]);$est=$est->fetch();$idEst=$est?$est['id_estudiante']:0;

// ── Grupo activo (INCLUYE completado) ───────────────────────────────────────
$grupo=null;$esLider=false;
if($idEst){
  $qg=$db->prepare("SELECT g.*,COALESCE(ob.nombre,g.org_nueva_nombre) AS organizacion,
    COALESCE(ob.canton,g.org_nueva_canton) AS org_canton,
    pe.nombre AS periodo_nombre,
    CONCAT(ut.nombres,' ',ut.apellidos) AS tutor_nombre,
    CONCAT(ul.nombres,' ',ul.apellidos) AS lider_nombre,
    m.rol
    FROM miembros_grupo_vinculacion m
    JOIN grupos_vinculacion g ON g.id_grupo=m.id_grupo
    JOIN periodos_academicos pe ON pe.id_periodo=g.id_periodo
    LEFT JOIN organizaciones_beneficiarias ob ON ob.id_organizacion=g.id_organizacion
    LEFT JOIN tutores t ON t.id_tutor=g.id_tutor
    LEFT JOIN usuarios ut ON ut.id_usuario=t.id_usuario
    JOIN estudiantes el ON el.id_estudiante=g.id_lider
    JOIN usuarios ul ON ul.id_usuario=el.id_usuario
    WHERE m.id_estudiante=:e AND m.estado='activo'
      AND g.estado IN ('aprobado','en_progreso','completado')
    ORDER BY g.created_at DESC LIMIT 1");
  $qg->execute([':e'=>$idEst]);$grupo=$qg->fetch();
  $esLider=$grupo&&$grupo['id_lider']==$idEst;
}

$esCompletado=$grupo&&$grupo['estado']==='completado';
$puedeEditar=$grupo&&!$esCompletado;

// ── Instituto ────────────────────────────────────────────────────────────────
$idInst = instId();

// ── Configuración de pago vinculación ────────────────────────────────────────
$stCfgPago = $db->prepare("SELECT clave, valor FROM configuracion_institucional WHERE id_instituto=:id AND clave IN ('precio_vinculacion','email_facturacion')");
$stCfgPago->execute([':id' => $idInst]);
$cfgPago      = array_column($stCfgPago->fetchAll(), 'valor', 'clave');
$precioVinc   = number_format((float)($cfgPago['precio_vinculacion'] ?? '0.00'), 2);
$emailFacVinc = $cfgPago['email_facturacion'] ?? '';

// ── Directorio uploads comprobantes vinculación ──────────────────────────────
$uploadDirCompVinc = __DIR__ . '/../../assets/uploads/comprobantes_vinculacion/';
if (!is_dir($uploadDirCompVinc)) mkdir($uploadDirCompVinc, 0755, true);

// ── Validación segura de archivos (3 capas) ──────────────────────────────────
// Capa 1: extensión del nombre
// Capa 2: MIME type real con finfo (lee bytes internos, ignora el nombre)
// Capa 3: magic bytes — firma hexadecimal real al inicio del archivo
// Retorna '' si pasa todo, o mensaje de error si falla alguna capa.
if (!function_exists('validarArchivoSeguro')) {
    function validarArchivoSeguro(array $file, array $extsOk, array $mimesOk, array $magicOk): string
    {
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, $extsOk))
            return 'Extensión no permitida. Solo se aceptan: ' . strtoupper(implode(', ', $extsOk)) . '.';

        if (function_exists('finfo_open')) {
            $fi   = finfo_open(FILEINFO_MIME_TYPE);
            $mime = $fi ? finfo_file($fi, $file['tmp_name']) : '';
            if ($fi) finfo_close($fi);
            if ($mime && !in_array($mime, $mimesOk))
                return 'El contenido del archivo no corresponde al tipo permitido (MIME inválido).';
        }

        $fh = fopen($file['tmp_name'], 'rb');
        if ($fh === false) return 'No se pudo leer el archivo temporalmente.';
        $cabecera = fread($fh, max(array_column($magicOk, 'len')));
        fclose($fh);

        foreach ($magicOk as $firma)
            if (substr($cabecera, 0, $firma['len']) === $firma['bytes']) return '';

        return 'El archivo no tiene la firma interna correcta. Puede ser un archivo falso con extensión cambiada.';
    }
}

if (!defined('MAGIC_VINC2')) {
    define('MAGIC_VINC2', [
        'pdf'  => ['bytes' => '%PDF-',          'len' => 5],
        'jpg'  => ['bytes' => "\xFF\xD8\xFF",   'len' => 3],
        'jpeg' => ['bytes' => "\xFF\xD8\xFF",   'len' => 3],
        'png'  => ['bytes' => "\x89PNG",        'len' => 4],
        'doc'  => ['bytes' => "\xD0\xCF\x11\xE0", 'len' => 4],
        'docx' => ['bytes' => "PK\x03\x04",    'len' => 4],
    ]);
}

// ── POST: subir comprobante de pago vinculación ──────────────────────────────
// Solo el líder puede subir — y solo si estado_pago está en pendiente o rechazado
if ($_SERVER['REQUEST_METHOD'] === 'POST' && $grupo && $esLider) {
    $accionPagoVinc = $_POST['accion_pago_vinc'] ?? '';
    if ($accionPagoVinc === 'enviar_comprobante_vinc') {
        $estPagoActual = $grupo['estado_pago'] ?? 'pendiente';
        if (in_array($estPagoActual, ['pendiente','rechazado'])) {
            if (empty($_FILES['comprobante_pago_vinc']['name'])) {
                flashSet('err', 'Debes adjuntar el comprobante de pago o PDF de exoneración.');
            } else {
                $fv = $_FILES['comprobante_pago_vinc'];
                if ($fv['error'] !== UPLOAD_ERR_OK) {
                    flashSet('err', 'Error al recibir el archivo.');
                } elseif ($fv['size'] > 5 * 1024 * 1024) {
                    flashSet('err', 'El archivo no puede superar 5 MB.');
                } else {
                    // Validación 3 capas: extensión + MIME real + magic bytes
                    $errArch = validarArchivoSeguro(
                        $fv,
                        ['pdf','jpg','jpeg','png'],
                        ['application/pdf','image/jpeg','image/png'],
                        array_values(array_intersect_key(MAGIC_VINC2, array_flip(['pdf','jpg','jpeg','png'])))
                    );
                    if ($errArch) {
                        flashSet('err', $errArch);
                    } else {
                        $exv = strtolower(pathinfo($fv['name'], PATHINFO_EXTENSION));
                        $fnv = 'comp_vinc_' . $idEst . '_' . time() . '.' . $exv;
                        try {
                            $rutaOD = OneDriveStorage::upload($fv['tmp_name'], 'comprobantes_vinculacion', $fnv, null, $idInst);
                            $db->prepare("UPDATE grupos_vinculacion SET comprobante_pago=:c, estado_pago='enviada', updated_at=NOW() WHERE id_grupo=:g")
                               ->execute([':c' => $rutaOD, ':g' => $grupo['id_grupo']]);
                            $grupo['comprobante_pago'] = $rutaOD;
                            $grupo['estado_pago']      = 'enviada';
                            // Notificar a facturación
                            try {
                                $nombreLider = $user['nombre'] ?? 'Líder';
                                $stFac = $db->prepare("SELECT id_usuario FROM usuarios WHERE id_rol=9 AND activo=1 AND id_instituto=:inst");
                                $stFac->execute([':inst' => $idInst]);
                                $stN  = $db->prepare("INSERT INTO notificaciones (id_usuario,asunto,mensaje,leida,created_at) VALUES (:u,:a,:m,0,NOW())");
                                foreach ($stFac->fetchAll(\PDO::FETCH_COLUMN) as $idFac) {
                                    $stN->execute([':u'=>$idFac,':a'=>'💳 Nuevo comprobante de Vinculación',':m'=>"El líder {$nombreLider} subió el comprobante de pago del grupo «{$grupo['nombre_proyecto']}». Ingresa a Facturación para validarlo."]);
                                }
                            } catch (Exception $ex) {}
                            flashSet('ok', '✅ Comprobante enviado. Facturación validará y recibirás una notificación.');
                        } catch (Exception $eOD) {
                            flashSet('err', '❌ Error al subir a OneDrive: ' . $eOD->getMessage());
                        }
                    }
                }
            }
        }
        header('Location: vinculacion.php'); exit;
    }
}

// ── Miembros del grupo ───────────────────────────────────────────────────────
$miembros=[];
if($grupo){
  $qm=$db->prepare("SELECT m.*,CONCAT(u.apellidos,' ',u.nombres) AS nombre_completo,
    e.codigo_estudiante,c.nombre AS carrera
    FROM miembros_grupo_vinculacion m
    JOIN estudiantes e ON e.id_estudiante=m.id_estudiante
    JOIN usuarios u ON u.id_usuario=e.id_usuario
    JOIN carreras c ON c.id_carrera=e.id_carrera
    WHERE m.id_grupo=:g AND m.estado='activo'
    ORDER BY m.rol DESC,u.apellidos");
  $qm->execute([':g'=>$grupo['id_grupo']]);$miembros=$qm->fetchAll();
}

// ── Entrega informe ──────────────────────────────────────────────────────────
$entrega=null;
if($grupo){
  try{
    $qe=$db->prepare("SELECT * FROM entregas_informe_vinculacion WHERE id_grupo=:g ORDER BY created_at DESC LIMIT 1");
    $qe->execute([':g'=>$grupo['id_grupo']]);$entrega=$qe->fetch();
  }catch(Exception $e){$entrega=null;}
}

// ── Calificacion del estudiante (solo cuando completado) ────────────────────
$miCalificacion=null;
if($grupo&&$esCompletado&&$idEst){
  try{
    $qcal=$db->prepare("SELECT cv.*,
      CONCAT(ut.nombres,' ',ut.apellidos) AS tutor_nombre
      FROM calificaciones_vinculacion cv
      LEFT JOIN tutores t ON t.id_tutor=cv.id_tutor
      LEFT JOIN usuarios ut ON ut.id_usuario=t.id_usuario
      WHERE cv.id_grupo=:g AND cv.id_estudiante=:e LIMIT 1");
    $qcal->execute([':g'=>$grupo['id_grupo'],':e'=>$idEst]);
    $miCalificacion=$qcal->fetch();
  }catch(Exception $ex){$miCalificacion=null;}
}

// ── Certificado firmado del estudiante ──────────────────────────────────────
$miCertificado = null;
if ($grupo && $esCompletado && $idEst) {
    try {
        $qcert = $db->prepare("
            SELECT cv.*
            FROM certificados_vinculacion cv
            WHERE cv.id_grupo = :g
              AND cv.id_estudiante = :e
              AND cv.tipo = 'culminacion'
              AND cv.vigente = 1
            LIMIT 1
        ");
        $qcert->execute([':g' => $grupo['id_grupo'], ':e' => $idEst]);
        $miCertificado = $qcert->fetch();
    } catch (Exception $ex) { $miCertificado = null; }
}

// ── Filtros de bitácoras ────────────────────────────────────────────────────
$filEstadoBit = $_GET['estado_bit'] ?? '';
$perPageBit   = in_array((int)($_GET['pp'] ?? 10), [5,10,25,50]) ? (int)($_GET['pp'] ?? 10) : 10;
$pageBit      = max(1, (int)($_GET['page'] ?? 1));
$offsetBit    = ($pageBit - 1) * $perPageBit;

// ── POST actions (solo si no completado) ─────────────────────────────────────
if($_SERVER['REQUEST_METHOD']==='POST'&&$grupo&&$puedeEditar){
  $accion=$_POST['accion']??'';

  if($accion==='abrir_semana'&&$esLider){
    $s=(int)($_POST['semana_numero']??0);$fi=$_POST['fecha_inicio_semana']??'';$ff=$_POST['fecha_fin_semana']??'';
    if($s&&$fi&&$ff){
      $ex=$db->prepare("SELECT id_bitacora FROM bitacoras_grupo_vinculacion WHERE id_grupo=:g AND semana_numero=:s");
      $ex->execute([':g'=>$grupo['id_grupo'],':s'=>$s]);
      if($ex->fetch()){flashSet('warn','La semana '.$s.' ya existe.');}
      else{$db->prepare("INSERT INTO bitacoras_grupo_vinculacion (id_grupo,semana_numero,fecha_inicio_semana,fecha_fin_semana) VALUES(:g,:s,:fi,:ff)")->execute([':g'=>$grupo['id_grupo'],':s'=>$s,':fi'=>$fi,':ff'=>$ff]);flashSet('ok','Semana '.$s.' abierta. Cada integrante puede agregar su seccion.');}
    }
    header('Location: vinculacion.php');exit;
  }

  if($accion==='agregar_seccion'){
    $idBit=(int)($_POST['id_bitacora']??0);$fecha=$_POST['fecha']??'';$horas=(int)($_POST['horas']??0);
    $desc=trim($_POST['descripcion']??'');$logros=trim($_POST['logros']??'');$dif=trim($_POST['dificultades']??'');
    if($idBit&&$fecha&&$desc){
      $bit=$db->prepare("SELECT * FROM bitacoras_grupo_vinculacion WHERE id_bitacora=:id AND id_grupo=:g AND estado IN ('borrador','observada')");
      $bit->execute([':id'=>$idBit,':g'=>$grupo['id_grupo']]);$bit=$bit->fetch();
      if($bit){
        try{
          $db->prepare("INSERT INTO secciones_bitacora_vinculacion (id_bitacora,id_estudiante,fecha,horas,descripcion,logros,dificultades) VALUES(:b,:e,:f,:h,:d,:l,:dif) ON DUPLICATE KEY UPDATE horas=VALUES(horas),descripcion=VALUES(descripcion),logros=VALUES(logros),dificultades=VALUES(dificultades),updated_at=NOW()")
            ->execute([':b'=>$idBit,':e'=>$idEst,':f'=>$fecha,':h'=>$horas,':d'=>$desc,':l'=>$logros?:null,':dif'=>$dif?:null]);
          $db->prepare("UPDATE bitacoras_grupo_vinculacion SET horas_totales_grupo=(SELECT COALESCE(SUM(horas),0) FROM secciones_bitacora_vinculacion WHERE id_bitacora=:b) WHERE id_bitacora=:b2")->execute([':b'=>$idBit,':b2'=>$idBit]);
          flashSet('ok','Tu seccion fue guardada correctamente.');
        }catch(Exception $e){flashSet('warn','Ya tienes una seccion en esa fecha. Edita la existente.');}
      }
    }
    header('Location: vinculacion.php?bit='.$idBit);exit;
  }

  if($accion==='eliminar_seccion'){
    $idBit=(int)($_POST['id_bitacora']??0);$idSec=(int)($_POST['id_seccion']??0);
    $bit=$db->prepare("SELECT id_bitacora FROM bitacoras_grupo_vinculacion WHERE id_bitacora=:id AND id_grupo=:g AND estado='borrador'");
    $bit->execute([':id'=>$idBit,':g'=>$grupo['id_grupo']]);
    if($bit->fetch()){
      $db->prepare("DELETE FROM secciones_bitacora_vinculacion WHERE id_seccion=:s AND id_estudiante=:e")->execute([':s'=>$idSec,':e'=>$idEst]);
      $db->prepare("UPDATE bitacoras_grupo_vinculacion SET horas_totales_grupo=(SELECT COALESCE(SUM(horas),0) FROM secciones_bitacora_vinculacion WHERE id_bitacora=:b) WHERE id_bitacora=:b2")->execute([':b'=>$idBit,':b2'=>$idBit]);
      flashSet('ok','Seccion eliminada.');
    }
    header('Location: vinculacion.php?bit='.$idBit);exit;
  }

  if($accion==='enviar_tutor'&&$esLider){
    $idBit=(int)($_POST['id_bitacora']??0);
    $bit=$db->prepare("SELECT b.*,COUNT(s.id_seccion) AS total_sec FROM bitacoras_grupo_vinculacion b LEFT JOIN secciones_bitacora_vinculacion s ON s.id_bitacora=b.id_bitacora WHERE b.id_bitacora=:id AND b.id_grupo=:g AND b.estado IN ('borrador','observada') GROUP BY b.id_bitacora");
    $bit->execute([':id'=>$idBit,':g'=>$grupo['id_grupo']]);$bit=$bit->fetch();
    if($bit){
      if($bit['total_sec']==0){flashSet('warn','No hay secciones registradas aun.');}
      else{
        $db->prepare("UPDATE bitacoras_grupo_vinculacion SET estado='enviada' WHERE id_bitacora=:id")->execute([':id'=>$idBit]);
        $db->prepare("UPDATE grupos_vinculacion SET horas_cumplidas=(SELECT COALESCE(SUM(horas_totales_grupo),0) FROM bitacoras_grupo_vinculacion WHERE id_grupo=:g AND estado IN ('enviada','validada')),estado=CASE WHEN estado='aprobado' THEN 'en_progreso' ELSE estado END WHERE id_grupo=:g2")->execute([':g'=>$grupo['id_grupo'],':g2'=>$grupo['id_grupo']]);
        flashSet('ok','Bitacora enviada al tutor.');
      }
    }
    header('Location: vinculacion.php');exit;
  }

  if($accion==='subir_informe'&&$esLider){
    $bloqueado=$entrega&&$entrega['estado']==='aprobado';
    if($bloqueado){flashSet('warn','El informe ya fue aprobado. No se puede reemplazar.');header('Location: vinculacion.php');exit;}
    if(isset($_FILES['archivo_informe'])&&$_FILES['archivo_informe']['error']===0){
      $fInf = $_FILES['archivo_informe'];
      if($fInf['size'] > 20*1024*1024){
        flashSet('warn','El archivo no puede superar 20 MB.');
      } else {
        // Validación 3 capas: extensión + MIME real + magic bytes
        $errInf = validarArchivoSeguro(
          $fInf,
          ['pdf','doc','docx'],
          ['application/pdf','application/msword','application/vnd.openxmlformats-officedocument.wordprocessingml.document','application/zip'],
          array_values(array_intersect_key(MAGIC_VINC2, array_flip(['pdf','doc','docx'])))
        );
        if($errInf){
          flashSet('warn', $errInf);
        } else {
          $ext=strtolower(pathinfo($fInf['name'],PATHINFO_EXTENSION));
          $archivo='inf_vinc_'.$grupo['id_grupo'].'_'.time().'.'.$ext;
          try {
            $rutaInf = OneDriveStorage::upload($fInf['tmp_name'], 'informes_vinculacion', $archivo, (string)$grupo['id_grupo'], $idInst);
            if($entrega){
              $db->prepare("UPDATE entregas_informe_vinculacion SET archivo=:a,estado='pendiente_revision',observacion_tutor=NULL,updated_at=NOW() WHERE id_entrega=:id")->execute([':a'=>$rutaInf,':id'=>$entrega['id_entrega']]);
              flashSet('ok','Informe reemplazado y enviado al tutor.');
            }else{
              $db->prepare("INSERT INTO entregas_informe_vinculacion (id_grupo,id_estudiante_lider,archivo,estado) VALUES(:g,:e,:a,'pendiente_revision')")->execute([':g'=>$grupo['id_grupo'],':e'=>$idEst,':a'=>$rutaInf]);
              flashSet('ok','Informe enviado al tutor correctamente.');
            }
          } catch (Exception $eInf) {
            flashSet('warn','❌ Error al subir informe a OneDrive: '.$eInf->getMessage());
          }
        }
      }
    }else{flashSet('warn','Selecciona un archivo.');}
    header('Location: vinculacion.php');exit;
  }
}

// ── Ver bitacora especifica ──────────────────────────────────────────────────
$verBit=null;$secciones=[];
$idVer=(int)($_GET['bit']??0);
if($idVer&&$grupo){
  $qv=$db->prepare("SELECT * FROM bitacoras_grupo_vinculacion WHERE id_bitacora=:id AND id_grupo=:g");
  $qv->execute([':id'=>$idVer,':g'=>$grupo['id_grupo']]);$verBit=$qv->fetch();
  if($verBit){
    $qs=$db->prepare("SELECT s.*,CONCAT(u.apellidos,' ',u.nombres) AS nombre_est,e.codigo_estudiante FROM secciones_bitacora_vinculacion s JOIN estudiantes e ON e.id_estudiante=s.id_estudiante JOIN usuarios u ON u.id_usuario=e.id_usuario WHERE s.id_bitacora=:id ORDER BY u.apellidos,s.fecha");
    $qs->execute([':id'=>$idVer]);$secciones=$qs->fetchAll();
  }
}

// ── Lista bitacoras ──────────────────────────────────────────────────────────
$listaBit=[];
if($grupo){
  $qlb=$db->prepare("SELECT b.*,COUNT(s.id_seccion) AS total_sec FROM bitacoras_grupo_vinculacion b LEFT JOIN secciones_bitacora_vinculacion s ON s.id_bitacora=b.id_bitacora WHERE b.id_grupo=:g GROUP BY b.id_bitacora ORDER BY b.semana_numero DESC");
  $qlb->execute([':g'=>$grupo['id_grupo']]);$listaBit=$qlb->fetchAll();
}

// ── Secciones de cada integrante agrupadas por bitácora ────────────────────
// Para mostrar el trabajo individual de cada miembro en la vista principal
$seccionesPorMiembro=[];// [id_estudiante => [bitacora_info...]]
$seccionesPorBitacora=[];// [id_bitacora => [secciones...]]
if($grupo){
  $qsm=$db->prepare("
    SELECT s.*,
      CONCAT(u.apellidos,' ',u.nombres) AS nombre_est,
      e.codigo_estudiante,
      m.rol AS rol_miembro,
      b.semana_numero,
      b.fecha_inicio_semana,
      b.fecha_fin_semana,
      b.estado AS estado_bit
    FROM secciones_bitacora_vinculacion s
    JOIN bitacoras_grupo_vinculacion b ON b.id_bitacora=s.id_bitacora
    JOIN estudiantes e ON e.id_estudiante=s.id_estudiante
    JOIN usuarios u ON u.id_usuario=e.id_usuario
    JOIN miembros_grupo_vinculacion m ON m.id_estudiante=s.id_estudiante AND m.id_grupo=:g
    WHERE b.id_grupo=:g2
    ORDER BY s.id_estudiante, b.semana_numero");
  $qsm->execute([':g'=>$grupo['id_grupo'],':g2'=>$grupo['id_grupo']]);
  foreach($qsm->fetchAll() as $row){
    $seccionesPorMiembro[$row['id_estudiante']][]=$row;
    $seccionesPorBitacora[$row['id_bitacora']][]=$row;
  }
}

// ── Documentos de la Coordinadora ───────────────────────────────────────────
$docsVinc=[];
try{
  $docsVinc=$db->query("SELECT dv.*,CONCAT(u.nombres,' ',u.apellidos) AS subido_por_nombre FROM documentos_vinculacion dv JOIN usuarios u ON u.id_usuario=dv.subido_por ORDER BY dv.created_at DESC")->fetchAll();
}catch(Exception $e){$docsVinc=[];}

$nuevaSemana=$listaBit?max(array_column($listaBit,'semana_numero'))+1:1;
$hoy=new DateTime();$dow=(int)$hoy->format('N');
$lunes=$dow===1?clone $hoy:(clone $hoy)->modify('+'.(8-$dow).' days');
$viernes=(clone $lunes)->modify('+4 days');

$miSeccion=null;
if($verBit){foreach($secciones as $s){if($s['id_estudiante']==$idEst){$miSeccion=$s;break;}}}
$editable=$verBit&&in_array($verBit['estado'],['borrador','observada'])&&$puedeEditar;

// Helpers
function badgeEntrega($estado){
  return match($estado){
    'pendiente_revision'=>'<span style="font-size:11px;padding:2px 10px;border-radius:20px;background:#fffbeb;color:#d97706;font-weight:700;border:1px solid #fde68a"><i class="fa fa-clock me-1"></i>En revision</span>',
    'observado'         =>'<span style="font-size:11px;padding:2px 10px;border-radius:20px;background:#fffbeb;color:#d97706;font-weight:700;border:1px solid #d97706"><i class="fa fa-comment me-1"></i>Observado — corregir</span>',
    'aprobado'          =>'<span style="font-size:11px;padding:2px 10px;border-radius:20px;background:#f0fdf4;color:#16a34a;font-weight:700;border:1px solid #86efac"><i class="fa fa-check me-1"></i>Aprobado</span>',
    default             =>'<span style="font-size:11px;padding:2px 10px;border-radius:20px;background:#f1f5f9;color:#64748b;font-weight:700;border:1px solid #e2e8f0">Sin entregar</span>'
  };
}
function notaLabel($prom){
  if($prom===null) return '—';
  if($prom>=90) return 'Excelente';
  if($prom>=80) return 'Muy Bueno';
  if($prom>=70) return 'Bueno';
  return 'Reprobado';
}
?>
<?php $paginaActual = 'vinculacion'; ?>
<!DOCTYPE html><html lang="es"><head>
<?php include __DIR__.'/../../includes/head.php';?>
<link rel="stylesheet" href="<?= BASE_URL ?>/assets/css/sidebar.css">
<link rel="stylesheet" href="<?= BASE_URL ?>/assets/css/sidebar-estudiante.css">
<style>
/* ═══════════════════════════════════════════════════
   VINCULACION — TEMA CLARO MODERNO
   Paleta: blanco, grises suaves, azul institucional
═══════════════════════════════════════════════════ */
:root{
  --bg-page:#f0f4f8;
  --bg-card:#ffffff;
  --bg-card2:#f8fafc;
  --bg-card3:#eef2f7;
  --border:#dde3ec;
  --border-focus:#3b82f6;
  --text-primary:#1e293b;
  --text-secondary:#64748b;
  --text-muted:#94a3b8;
  --blue:#2563eb;
  --blue-light:#eff6ff;
  --blue-mid:#bfdbfe;
  --green:#16a34a;
  --green-light:#f0fdf4;
  --green-mid:#bbf7d0;
  --amber:#d97706;
  --amber-light:#fffbeb;
  --red:#dc2626;
  --red-light:#fef2f2;
  --purple:#7c3aed;
  --purple-light:#f5f3ff;
  --radius:12px;
  --shadow:0 1px 4px rgba(0,0,0,.07),0 4px 16px rgba(0,0,0,.06);
  --shadow-sm:0 1px 3px rgba(0,0,0,.08);
}

/* ── Secciones del detalle de semana ── */
.sec-card{
  background:var(--bg-card);
  border:1px solid var(--border);
  border-radius:var(--radius);
  padding:16px 18px;
  margin-bottom:12px;
  transition:box-shadow .18s,border-color .18s;
  box-shadow:var(--shadow-sm);
}
.sec-card:hover{border-color:var(--blue-mid);box-shadow:var(--shadow)}
.sec-card.mi-seccion{border-color:#86efac;background:var(--green-light)}
.sec-card .sec-autor{font-size:11px;color:var(--text-secondary);font-weight:700;text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px}
.sec-card .sec-horas{font-size:22px;font-weight:800;color:var(--blue)}

/* ── Tabla bitácoras ── */
.bit-row{cursor:pointer}
.bit-row:hover td{background:var(--blue-light)!important}

/* ── Documentos ── */
.doc-item{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  background:var(--bg-card2);border:1px solid var(--border);
  border-radius:10px;padding:10px 14px;transition:.15s;
}
.doc-item:hover{border-color:var(--blue-mid);background:var(--blue-light)}
.doc-item-info{display:flex;align-items:center;gap:10px;flex:1;min-width:0}
.doc-item-title{font-size:13px;font-weight:600;color:var(--text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.doc-item-meta{font-size:10px;color:var(--text-muted);margin-top:2px}
.doc-item-desc{font-size:11px;color:var(--text-secondary);margin-top:2px}

/* ── Informe box ── */
.inf-box{border-radius:var(--radius);padding:20px 22px;margin-top:20px}
.inf-box.pendiente{background:var(--amber-light);border:1px solid #fde68a}
.inf-box.observado{background:#fffbeb;border:2px solid var(--amber)}
.inf-box.aprobado{background:var(--green-light);border:1px solid var(--green-mid)}
.inf-box.sin{background:var(--blue-light);border:1px solid var(--blue-mid)}

/* ── Panel calificaciones ── */
.cal-panel{border-radius:14px;overflow:hidden;margin-bottom:20px;box-shadow:var(--shadow)}
.cal-header{padding:18px 22px;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px}
.cal-body{padding:20px 22px;background:var(--bg-card)}
.nota-card{border-radius:10px;padding:16px;text-align:center;box-shadow:var(--shadow-sm)}
.nota-num{font-size:38px;font-weight:800;line-height:1}
.nota-max{font-size:13px;color:var(--text-muted)}
.nota-label{font-size:11px;font-weight:700;margin-top:4px;text-transform:uppercase;letter-spacing:.5px}
.barra-bg{background:#e2e8f0;border-radius:20px;height:8px;margin-top:8px;overflow:hidden}
.barra-fill{height:100%;border-radius:20px;transition:width .6s ease}

/* ── Grid integrantes ── */
.members-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:10px;margin-bottom:20px}
.member-card{background:var(--bg-card);border:1px solid var(--border);border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:var(--shadow-sm)}
.member-card.me{border-color:#86efac;background:var(--green-light)}
.member-avatar{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;flex-shrink:0}
.member-name{font-size:12px;font-weight:600;line-height:1.3;color:var(--text-primary)}
.member-sub{font-size:10px;color:var(--text-muted);margin-top:2px}

/* ── Trabajo por integrante ── */
.miembro-trabajo{
  background:var(--bg-card);
  border:1px solid var(--border);
  border-radius:var(--radius);
  margin-bottom:12px;
  overflow:hidden;
  box-shadow:var(--shadow-sm);
  transition:box-shadow .18s;
}
.miembro-trabajo:hover{box-shadow:var(--shadow)}
.miembro-trabajo.yo{border-color:#86efac}
.miembro-trabajo-head{
  display:flex;align-items:center;gap:12px;
  padding:13px 16px;
  border-bottom:1px solid var(--border);
  cursor:pointer;user-select:none;transition:background .15s;
}
.miembro-trabajo-head:hover{background:var(--bg-card2)}
.miembro-trabajo.yo .miembro-trabajo-head{background:var(--green-light)}
.miembro-body{display:none}
.miembro-body.open{display:block}
.miembro-semana{padding:14px 18px;border-bottom:1px solid var(--border)}
.miembro-semana:last-child{border-bottom:none}
.sem-badge{font-size:10px;padding:2px 9px;border-radius:20px;background:var(--blue-light);color:var(--blue);font-weight:700;border:1px solid var(--blue-mid)}
.actividad-txt{font-size:13px;color:var(--text-primary);margin:6px 0 4px;white-space:pre-line;line-height:1.55}
.logro-txt{font-size:12px;color:var(--green);margin-top:4px;font-weight:500}
.dif-txt{font-size:12px;color:var(--amber);margin-top:4px;font-weight:500}
.horas-chip{font-size:22px;font-weight:800;color:var(--blue);white-space:nowrap}
.total-chip{font-size:11px;padding:3px 11px;border-radius:20px;background:var(--blue-light);color:var(--blue);font-weight:700;border:1px solid var(--blue-mid);white-space:nowrap}

/* ── Informe aprobado banner ── */
.inf-aprobado-banner{
  background:linear-gradient(135deg,#f0fdf4,#dcfce7);
  border:2px solid #86efac;
  border-radius:var(--radius);
  padding:18px 22px;
  margin-bottom:20px;
  display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;
  box-shadow:0 2px 12px rgba(22,163,74,.12);
}

/* ── Overrides globales para tema claro ── */
.main-area{background:var(--bg-page)!important}
.tbl-wrap{background:var(--bg-card)!important;border:1px solid var(--border)!important;box-shadow:var(--shadow-sm)!important;border-radius:var(--radius)!important}
.table{color:var(--text-primary)!important}
.table thead th{background:var(--bg-card2)!important;color:var(--text-secondary)!important;border-bottom:2px solid var(--border)!important;font-size:11px!important;font-weight:700!important;text-transform:uppercase!important;letter-spacing:.04em!important}
.table td{border-bottom:1px solid var(--border)!important;vertical-align:middle!important;color:var(--text-primary)!important}
.page-header{background:var(--bg-card)!important;border-bottom:1px solid var(--border)!important;padding:20px 24px!important}
.page-header h4{color:var(--text-primary)!important}
.modal-content{background:var(--bg-card)!important;border:1px solid var(--border)!important;color:var(--text-primary)!important}
.modal-header{border-bottom:1px solid var(--border)!important;background:var(--bg-card2)!important}
.modal-footer{border-top:1px solid var(--border)!important;background:var(--bg-card2)!important}
.form-control,.form-select{background:var(--bg-card)!important;border-color:var(--border)!important;color:var(--text-primary)!important}
.form-control:focus,.form-select:focus{border-color:var(--blue-focus)!important;box-shadow:0 0 0 3px rgba(37,99,235,.12)!important}
.form-label{color:var(--text-secondary)!important;font-size:12px!important;font-weight:600!important}
.alert-dark-info{background:var(--blue-light)!important;border:1px solid var(--blue-mid)!important;border-radius:10px!important;color:var(--blue)!important}
.alert-dark-warn{background:var(--amber-light)!important;border:1px solid #fde68a!important;border-radius:10px!important;color:var(--amber)!important}
.btn-outline-secondary{color:var(--text-secondary)!important;border-color:var(--border)!important}
.btn-outline-secondary:hover{background:var(--bg-card3)!important;color:var(--text-primary)!important}
.btn-close{filter:none!important}

/* ── Sección de labels de estado ── */
.section-label-head{
  font-size:11px;font-weight:700;text-transform:uppercase;
  letter-spacing:.07em;color:var(--text-muted);
  margin-bottom:12px;margin-top:6px;
  display:flex;align-items:center;gap:6px;
}

/* ── Bloque de pago vinculación (igual a mi_practica) ── */
.seccion-pago-vinc{
  background:var(--bg-card);
  border:1px solid var(--border);
  border-left:4px solid #f97316;
  border-radius:14px;
  padding:1.5rem 1.75rem;
  margin-bottom:1.25rem;
  box-shadow:var(--shadow);
}
.sec-step-pago  {font-size:10px;font-weight:700;letter-spacing:1px;text-transform:uppercase;color:#ea580c;margin-bottom:2px;}
.sec-title-pago {font-size:15px;font-weight:700;color:var(--text-primary);margin:0 0 2px;}
.sec-sub-pago   {font-size:12px;color:var(--text-secondary);margin:0 0 1.1rem;}
.upload-zone-vinc{border:2px dashed var(--border);border-radius:var(--radius);padding:1.5rem 1rem;text-align:center;cursor:pointer;transition:border-color .18s,background .18s;background:var(--bg-card2);}
.upload-zone-vinc:hover {border-color:#f97316;background:#fff7ed;}
.upload-zone-vinc.loaded{border-color:var(--green);background:var(--green-light);}
.upload-zone-vinc input[type=file]{display:none;}
.caja-pago-info  {background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px;padding:12px 16px;color:#1e40af;font-size:13px;}
.caja-pago-ok    {background:var(--green-light);border:1px solid var(--green-mid);border-radius:10px;padding:12px 16px;color:#15803d;font-size:13px;}
.caja-pago-warn  {background:var(--amber-light);border:1px solid #fde68a;border-radius:10px;padding:12px 16px;color:#92400e;font-size:13px;}
.caja-pago-error {background:var(--red-light);border:1px solid #fecaca;border-radius:10px;padding:12px 16px;color:#991b1b;font-size:13px;}
.comp-preview-vinc{display:flex;align-items:center;gap:14px;background:var(--green-light);border:1px solid var(--green-mid);border-radius:10px;padding:14px 16px;margin-bottom:14px;}
.exon-badge-vinc{display:inline-flex;align-items:center;gap:4px;background:#fef3c7;color:#92400e;border:1px solid #fde68a;border-radius:6px;padding:3px 10px;font-size:11px;font-weight:700;}
.sec-arrow-vinc{display:flex;align-items:center;justify-content:center;padding:.4rem 0 .2rem;color:#f97316;font-size:18px;}
</style>
</head><body>
<?php include __DIR__.'/../../includes/navbar.php';?>
<div class="app-shell">
<?php include __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'sidebar-estudiante.php'; ?>
<main class="main-area">

<?php if(!$grupo):?>
<!-- ═══ SIN GRUPO ═══ -->
  <div class="page-header"><h4><i class="fa fa-book-open me-2" style="color:#2563eb"></i>Bitacoras de Vinculacion</h4></div>
  <?=flashHtml()?>
  <div class="tbl-wrap p-4 text-center" style="color:#64748b">
    <div style="font-size:32px;margin-bottom:12px">📋</div>
    <div style="font-size:14px;margin-bottom:8px">Aun no tienes un grupo de vinculacion.</div>
    <a href="mi_vinculacion.php" class="btn btn-primary btn-sm mt-2"><i class="fa fa-handshake me-1"></i>Ir a Mi Vinculacion</a>
  </div>

<?php elseif($verBit):?>
<!-- ═══ DETALLE DE SEMANA ═══ -->
  <div class="page-header d-flex justify-content-between align-items-center flex-wrap gap-2">
    <div>
      <a href="vinculacion.php" style="font-size:12px;color:#64748b;text-decoration:none"><i class="fa fa-arrow-left me-1"></i>Volver</a>
      <h4 class="mt-1">Semana <?=$verBit['semana_numero']?> <span style="font-size:14px;font-weight:400;color:#64748b">· <?=formatFecha($verBit['fecha_inicio_semana'])?> - <?=formatFecha($verBit['fecha_fin_semana'])?></span></h4>
      <p><?=$verBit['horas_totales_grupo']?>h grupales · <?=count($secciones)?>/<?=count($miembros)?> integrantes aportaron · <?=badgeEstado($verBit['estado'])?></p>
    </div>
    <?php if($editable):?>
    <div class="d-flex gap-2 flex-wrap">
      <?php if(!$miSeccion):?>
      <button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#modalSeccion"><i class="fa fa-plus me-1"></i>Agregar mi aporte</button>
      <?php else:?>
      <button class="btn btn-outline-secondary btn-sm" data-bs-toggle="modal" data-bs-target="#modalSeccion"><i class="fa fa-pen-to-square me-1"></i>Editar mi aporte</button>
      <?php endif;?>
      <?php if($esLider):?>
      <form method="POST" onsubmit="return confirm('Enviar al tutor? Ya no podras editar.')">
        <input type="hidden" name="accion" value="enviar_tutor">
        <input type="hidden" name="id_bitacora" value="<?=$verBit['id_bitacora']?>">
        <button type="submit" class="btn btn-success btn-sm" <?=count($secciones)==0?'disabled':''?>><i class="fa fa-paper-plane me-1"></i>Enviar al tutor</button>
      </form>
      <?php endif;?>
    </div>
    <?php endif;?>
  </div>
  <?=flashHtml()?>
  <?php if($verBit['comentario_tutor']):?>
  <div class="alert-dark-warn p-3 mb-3"><i class="fa fa-comment me-1"></i><strong>Comentario del tutor:</strong> <?=htmlspecialchars($verBit['comentario_tutor'])?></div>
  <?php endif;?>

  <?php if(empty($secciones)):?>
  <div class="alert-dark-info p-3">Aun no hay secciones.<?=$editable?' Haz clic en <strong>Agregar mi aporte</strong> para registrar tus actividades.':' Esta semana esta vacia.'?></div>
  <?php else:?>
  <?php foreach($secciones as $s):$esMia=$s['id_estudiante']==$idEst;?>
  <div class="sec-card <?=$esMia?'mi-seccion':''?>">
    <div class="sec-autor">
      <?php if($esMia):?><i class="fa fa-user me-1" style="color:#15803d"></i><span style="color:#15803d">TU APORTE</span><?php else:?><i class="fa fa-user me-1"></i><?=htmlspecialchars($s['nombre_est'])?> (<?=htmlspecialchars($s['codigo_estudiante'])?>)<?php endif;?>
    </div>
    <div class="d-flex justify-content-between align-items-start flex-wrap gap-2">
      <div style="flex:1">
        <div style="font-size:12px;color:#94a3b8;margin-bottom:4px"><?=date('d/m/Y',strtotime($s['fecha']))?></div>
        <div style="font-size:14px;margin-bottom:8px;color:#1e293b"><?=nl2br(htmlspecialchars($s['descripcion']))?></div>
        <?php if($s['logros']):?><div style="font-size:12px;color:#16a34a;margin-bottom:4px;font-weight:500"><strong>Logros:</strong> <?=htmlspecialchars($s['logros'])?></div><?php endif;?>
        <?php if($s['dificultades']):?><div style="font-size:12px;color:#d97706;font-weight:500"><strong>Dificultades:</strong> <?=htmlspecialchars($s['dificultades'])?></div><?php endif;?>
      </div>
      <div class="text-end" style="flex-shrink:0">
        <div class="sec-horas"><?=$s['horas']?><span style="font-size:13px;color:#94a3b8;font-weight:400">h</span></div>
        <?php if($esMia&&$editable):?>
        <form method="POST" class="mt-2" onsubmit="return confirm('Eliminar tu seccion?')">
          <input type="hidden" name="accion" value="eliminar_seccion">
          <input type="hidden" name="id_bitacora" value="<?=$verBit['id_bitacora']?>">
          <input type="hidden" name="id_seccion" value="<?=$s['id_seccion']?>">
          <button type="submit" class="btn btn-sm btn-outline-secondary"><i class="fa fa-trash"></i></button>
        </form>
        <?php endif;?>
      </div>
    </div>
  </div>
  <?php endforeach;?>
  <div style="background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px;padding:12px 16px;margin-top:8px;display:flex;justify-content:space-between;align-items:center">
    <span style="font-size:13px;color:#64748b;font-weight:600">TOTAL GRUPO SEMANA <?=$verBit['semana_numero']?></span>
    <span style="font-size:24px;font-weight:800;color:#2563eb"><?=$verBit['horas_totales_grupo']?>h</span>
  </div>
  <?php endif;?>

  <?php if($editable):?>
  <div class="modal fade" id="modalSeccion" tabindex="-1"><div class="modal-dialog modal-lg"><div class="modal-content">
    <div class="modal-header"><h5 class="modal-title"><i class="fa fa-pen-to-square me-2"></i><?=$miSeccion?'Editar mi aporte':'Agregar mi aporte'?></h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
    <form method="POST"><input type="hidden" name="accion" value="agregar_seccion"><input type="hidden" name="id_bitacora" value="<?=$verBit['id_bitacora']?>">
      <div class="modal-body"><div class="row g-3">
        <div class="col-sm-6"><label class="form-label">Fecha de actividad</label>
          <input type="date" name="fecha" class="form-control" required min="<?=$verBit['fecha_inicio_semana']?>" max="<?=$verBit['fecha_fin_semana']?>" value="<?=$miSeccion?$miSeccion['fecha']:date('Y-m-d')?>"></div>
        <div class="col-sm-6"><label class="form-label">Horas trabajadas</label>
          <input type="number" name="horas" class="form-control" required min="0" max="12" value="<?=$miSeccion?$miSeccion['horas']:'8'?>"></div>
        <div class="col-12"><label class="form-label">Actividades realizadas <span class="text-danger">*</span></label>
          <textarea name="descripcion" class="form-control" rows="4" required><?=$miSeccion?htmlspecialchars($miSeccion['descripcion']):''?></textarea></div>
        <div class="col-sm-6"><label class="form-label">Logros</label>
          <textarea name="logros" class="form-control" rows="2"><?=$miSeccion?htmlspecialchars($miSeccion['logros']??''):''?></textarea></div>
        <div class="col-sm-6"><label class="form-label">Dificultades</label>
          <textarea name="dificultades" class="form-control" rows="2"><?=$miSeccion?htmlspecialchars($miSeccion['dificultades']??''):''?></textarea></div>
      </div></div>
      <div class="modal-footer"><button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancelar</button><button type="submit" class="btn btn-primary"><i class="fa fa-save me-1"></i>Guardar mi aporte</button></div>
    </form>
  </div></div></div>
  <?php endif;?>

<?php else:?>
<!-- ═══ VISTA PRINCIPAL ═══ -->
  <div class="page-header d-flex justify-content-between align-items-center flex-wrap gap-2">
    <div>
      <h4><i class="fa fa-book-open me-2" style="color:#2563eb"></i>Vinculacion — <?=htmlspecialchars($grupo['nombre_proyecto']??'')?></h4>
      <p style="font-size:13px;color:#64748b">
        <i class="fa fa-building me-1"></i><?=htmlspecialchars($grupo['organizacion']??'')?>
        &nbsp;·&nbsp; <i class="fa fa-calendar me-1"></i><?=htmlspecialchars($grupo['periodo_nombre']??'')?>
        &nbsp;·&nbsp; Tutor: <?=htmlspecialchars($grupo['tutor_nombre']??'Sin asignar')?>
        &nbsp;·&nbsp;
        <?php
          $ec=['pendiente'=>'#f59e0b','aprobado'=>'#16a34a','en_progreso'=>'#3b82f6','completado'=>'#8b5cf6'];
          $col=$ec[$grupo['estado']]??'#64748b';
        ?>
        <span style="color:<?=$col?>;font-weight:700">&#9679; <?=ucfirst($grupo['estado'])?></span>
      </p>
    </div>
    <?php if($esLider&&$puedeEditar):?>
    <button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#modalSemana"><i class="fa fa-plus me-1"></i>Abrir semana</button>
    <?php endif;?>
  </div>
  <?=flashHtml()?>

  <!-- ══ INFORME APROBADO — visible para TODOS siempre que exista ══ -->
  <?php if($entrega&&$entrega['estado']==='aprobado'):?>
  <div class="inf-aprobado-banner">
    <div style="display:flex;align-items:center;gap:12px">
      <i class="fa fa-file-circle-check fa-2x" style="color:#15803d;flex-shrink:0"></i>
      <div>
        <div style="font-size:13px;font-weight:700;color:#15803d"><i class="fa fa-circle-check me-1"></i>Informe Final de Vinculacion — APROBADO</div>
        <div style="font-size:11px;color:#64748b;margin-top:3px">Aprobado el <?=date('d/m/Y',strtotime($entrega['updated_at']))?> &nbsp;·&nbsp; Disponible para descarga de todos los integrantes</div>
      </div>
    </div>
    <a href="<?=BASE_URL?>/uploads/informes_vinculacion/<?=urlencode($entrega['archivo'])?>"
       target="_blank"
       class="btn btn-success btn-sm" style="white-space:nowrap">
      <i class="fa fa-download me-1"></i>Descargar informe aprobado
    </a>
  </div>
  <?php endif;?>

  <!-- ── Integrantes + su trabajo ── -->
  <div class="section-label-head"><i class="fa fa-users me-1"></i>Integrantes del grupo y su trabajo</div>
  <?php
    $avatarColors=['#dbeafe','#dcfce7','#f3e8ff','#fef3c7','#e0e7ff','#fee2e2'];
    $textColors=['#1d4ed8','#15803d','#6d28d9','#d97706','#4338ca','#dc2626'];
    foreach($miembros as $idx=>$m):
      $esMio=$m['id_estudiante']==$idEst;
      $ci=$idx%count($avatarColors);
      $iniciales=implode('',array_map(fn($w)=>strtoupper($w[0]),array_slice(explode(' ',$m['nombre_completo']),0,2)));
      $secsM=$seccionesPorMiembro[$m['id_estudiante']]??[];
      $totalHorasM=array_sum(array_column($secsM,'horas'));
      $divId='trabajo_'.$m['id_estudiante'];
  ?>
  <div class="miembro-trabajo <?=$esMio?'yo':''?>" id="card_<?=$m['id_estudiante']?>">
    <!-- cabecera clickeable -->
    <div class="miembro-trabajo-head" onclick="toggleMiembro('<?=$divId?>')">
      <div class="member-avatar" style="width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:13px;flex-shrink:0;background:<?=$avatarColors[$ci]?>;color:<?=$textColors[$ci]?>"><?=$iniciales?></div>
      <div style="flex:1;min-width:0">
        <div style="font-size:13px;font-weight:600;color:<?=$esMio?'#15803d':'#1e293b'?>">
          <?=htmlspecialchars($m['nombre_completo'])?>
          <?=$esMio?'<span style="font-size:9px;color:#15803d;margin-left:4px">(tú)</span>':''?>
          <?php if($m['rol']==='lider'):?>
          <span style="font-size:9px;padding:1px 6px;border-radius:4px;background:#fef3c7;color:#d97706;font-weight:700;margin-left:6px;border:1px solid #fde68a">LIDER</span>
          <?php endif;?>
        </div>
        <div style="font-size:10px;color:#94a3b8;margin-top:2px"><?=htmlspecialchars($m['codigo_estudiante'])?> &nbsp;·&nbsp; <?=htmlspecialchars($m['carrera'])?></div>
      </div>
      <div style="display:flex;align-items:center;gap:10px;flex-shrink:0">
        <?php if($totalHorasM>0):?>
        <span class="total-chip"><?=$totalHorasM?>h total</span>
        <?php elseif(empty($secsM)):?>
        <span style="font-size:10px;color:#94a3b8">Sin aportes</span>
        <?php endif;?>
        <i class="fa fa-chevron-down" id="ico_<?=$divId?>" style="font-size:10px;color:#94a3b8;transition:transform .25s"></i>
      </div>
    </div>
    <!-- cuerpo: semanas del miembro -->
    <div class="miembro-body <?=$esMio?'open':''?>" id="<?=$divId?>">
      <?php if(empty($secsM)):?>
      <div style="padding:16px 20px;color:#94a3b8;font-size:13px;text-align:center"><i class="fa fa-circle-info me-1"></i>Este integrante no ha registrado aportes aun.</div>
      <?php else:
        // Agrupar por semana
        $semanas=[];
        foreach($secsM as $s){ $semanas[$s['semana_numero']][]=$s; }
        ksort($semanas);
        foreach($semanas as $numSem=>$rows):
          $r=$rows[0];
          $horasSem=array_sum(array_column($rows,'horas'));
      ?>
      <div class="miembro-semana">
        <div style="display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap">
          <div style="flex:1;min-width:0">
            <div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px">
              <span class="sem-badge">Semana <?=$numSem?></span>
              <span style="font-size:10px;color:#94a3b8"><?=formatFecha($r['fecha_inicio_semana'])?> – <?=formatFecha($r['fecha_fin_semana'])?></span>
              <?=badgeEstado($r['estado_bit'])?>
            </div>
            <?php foreach($rows as $s):?>
            <div style="margin-bottom:8px">
              <div style="font-size:10px;color:#94a3b8;margin-bottom:2px"><i class="fa fa-calendar me-1"></i><?=date('d/m/Y',strtotime($s['fecha']))?></div>
              <div class="actividad-txt"><?=nl2br(htmlspecialchars($s['descripcion']))?></div>
              <?php if($s['logros']):?><div class="logro-txt"><i class="fa fa-circle-check me-1"></i><?=htmlspecialchars($s['logros'])?></div><?php endif;?>
              <?php if($s['dificultades']):?><div class="dif-txt"><i class="fa fa-triangle-exclamation me-1"></i><?=htmlspecialchars($s['dificultades'])?></div><?php endif;?>
            </div>
            <?php endforeach;?>
          </div>
          <div style="text-align:right;flex-shrink:0">
            <div class="horas-chip"><?=$horasSem?><span style="font-size:12px;font-weight:400;color:#94a3b8">h</span></div>
            <div style="font-size:9px;color:#94a3b8;margin-top:2px">esta semana</div>
          </div>
        </div>
      </div>
      <?php endforeach;endif;?>
    </div>
  </div>
  <?php endforeach;?>

  <!-- ── Stats rápidas del grupo ── -->
  <?php
    $totalHorasGrupo = array_sum(array_column($listaBit, 'horas_totales_grupo'));
    $totalSemanas    = count($listaBit);
    $semEnviadas     = count(array_filter($listaBit, fn($b) => in_array($b['estado'], ['enviada','validada'])));
    $horasReq        = (int)($grupo['horas_requeridas'] ?? 160);
    $pctHoras        = $horasReq > 0 ? min(100, round(($totalHorasGrupo / $horasReq) * 100)) : 0;
  ?>
  <div class="row g-3 mb-3" style="margin-top:8px;">
    <div class="col-6 col-md-3">
      <div style="background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px;padding:14px 16px;text-align:center;">
        <div style="font-size:24px;font-weight:800;color:#2563eb;"><?= $totalHorasGrupo ?>h</div>
        <div style="font-size:11px;color:#64748b;margin-top:3px;">Horas registradas</div>
      </div>
    </div>
    <div class="col-6 col-md-3">
      <div style="background:#f0fdf4;border:1px solid #bbf7d0;border-radius:10px;padding:14px 16px;text-align:center;">
        <div style="font-size:24px;font-weight:800;color:#16a34a;"><?= $totalSemanas ?></div>
        <div style="font-size:11px;color:#64748b;margin-top:3px;">Semanas abiertas</div>
      </div>
    </div>
    <div class="col-6 col-md-3">
      <div style="background:#faf5ff;border:1px solid #e9d5ff;border-radius:10px;padding:14px 16px;text-align:center;">
        <div style="font-size:24px;font-weight:800;color:#7c3aed;"><?= $semEnviadas ?></div>
        <div style="font-size:11px;color:#64748b;margin-top:3px;">Enviadas al tutor</div>
      </div>
    </div>
    <div class="col-6 col-md-3">
      <div style="background:#fff7ed;border:1px solid #fed7aa;border-radius:10px;padding:14px 16px;text-align:center;">
        <div style="font-size:24px;font-weight:800;color:#ea580c;"><?= count($miembros) ?></div>
        <div style="font-size:11px;color:#64748b;margin-top:3px;">Integrantes activos</div>
      </div>
    </div>
  </div>

  <!-- Barra de progreso de horas -->
  <?php if($horasReq > 0): ?>
  <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:14px 18px;margin-bottom:16px;">
    <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
      <span style="font-size:12px;font-weight:700;color:#475569;">
        <i class="fa fa-clock me-1" style="color:#2563eb;"></i>Progreso de horas del grupo
      </span>
      <span style="font-size:13px;font-weight:700;color:<?= $pctHoras>=100?'#16a34a':'#2563eb' ?>;">
        <?= $totalHorasGrupo ?>h / <?= $horasReq ?>h requeridas (<?= $pctHoras ?>%)
      </span>
    </div>
    <div style="background:#e2e8f0;border-radius:999px;height:10px;overflow:hidden;">
      <div style="height:100%;width:<?= $pctHoras ?>%;background:<?= $pctHoras>=100?'linear-gradient(90deg,#16a34a,#4ade80)':'linear-gradient(90deg,#2563eb,#60a5fa)' ?>;border-radius:999px;transition:width .4s;"></div>
    </div>
  </div>
  <?php endif; ?>

  <!-- ══════════════════════════════════════════════════════
       BLOQUE PAGO — igual a mi_practica y convalidacion
  ══════════════════════════════════════════════════════ -->
  <?php
  $estPagoVinc   = $grupo['estado_pago']     ?? 'pendiente';
  $compVinc      = $grupo['comprobante_pago'] ?? null;
  $obsPagoVinc   = $grupo['obs_pago']         ?? null;
  $esExonVinc    = (int)($grupo['exonerado']  ?? 0);
  $puedeSubirVinc = $esLider && in_array($estPagoVinc, ['pendiente','rechazado']);
  ?>

  <div class="sec-arrow-vinc"><i class="fa fa-arrow-down"></i></div>

  <div class="seccion-pago-vinc">
    <p class="sec-step-pago">Comprobante de Pago</p>
    <p class="sec-title-pago"><i class="fa fa-file-invoice-dollar me-2" style="color:#f97316;"></i>Pago del Trámite de Vinculación</p>
    <p class="sec-sub-pago">
      <?php if ((float)$precioVinc > 0): ?>
        Adjunta el comprobante del pago de <strong style="color:var(--text-primary);">$<?= $precioVinc ?></strong> para que Facturación lo valide y el grupo pueda continuar.
        <?php if ($emailFacVinc): ?>
          También puedes enviarlo a <a href="mailto:<?= htmlspecialchars($emailFacVinc) ?>" style="color:#ea580c;font-weight:600;"><?= htmlspecialchars($emailFacVinc) ?></a>.
        <?php endif; ?>
      <?php else: ?>
        Sube el comprobante o, si el grupo es exonerado, el PDF que lo acredita ($0.00).
      <?php endif; ?>
      <?php if (!$esLider): ?>
        <span style="font-size:11px;color:var(--text-muted);display:block;margin-top:4px;"><i class="fa fa-info-circle me-1"></i>Solo el líder del grupo puede subir el comprobante.</span>
      <?php endif; ?>
    </p>

    <?php if ($estPagoVinc === 'enviada'): ?>
      <!-- Enviado — en revisión -->
      <div class="comp-preview-vinc">
        <div style="width:44px;height:44px;background:var(--green-mid);border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0;">
          <i class="fa fa-file-invoice-dollar" style="color:#15803d;font-size:20px;"></i>
        </div>
        <div>
          <div style="font-weight:700;color:#15803d;font-size:.9rem;">Comprobante enviado</div>
          <div style="font-size:12px;color:#16a34a;margin-top:2px;"><?= htmlspecialchars($compVinc) ?></div>
        </div>
      </div>
      <div class="caja-pago-info">
        <i class="fa fa-hourglass-half me-2"></i>
        Facturación está validando tu comprobante. El líder recibirá una notificación cuando sea procesado.
      </div>

    <?php elseif ($estPagoVinc === 'aprobado'): ?>
      <!-- Aprobado -->
      <div class="caja-pago-ok">
        <i class="fa fa-circle-check me-2"></i>
        <strong>Pago validado.</strong>
        <?php if ($esExonVinc): ?>
          <span class="exon-badge-vinc ms-2"><i class="fa fa-star"></i>Exonerado — $0.00</span>
        <?php else: ?>
          Monto: <strong>$<?= $precioVinc ?></strong>
        <?php endif; ?>
        &nbsp;·&nbsp;El grupo puede continuar con las bitácoras.
      </div>

    <?php elseif ($estPagoVinc === 'rechazado'): ?>
      <!-- Rechazado -->
      <div class="caja-pago-error mb-3">
        <i class="fa fa-circle-xmark me-2"></i>
        <strong>Comprobante rechazado.</strong>
        <?php if ($obsPagoVinc): ?> Motivo: <?= htmlspecialchars($obsPagoVinc) ?><?php endif; ?>
      </div>

    <?php else: ?>
      <!-- Pendiente — instrucción -->
      <div class="caja-pago-warn mb-3" style="font-size:12px;">
        <i class="fa fa-circle-info me-2"></i>
        <?php if ((float)$precioVinc > 0): ?>
          El líder del grupo debe realizar el depósito de <strong>$<?= $precioVinc ?></strong> y adjuntar el comprobante.
        <?php endif; ?>
        Si el grupo es exonerado, sube el PDF que lo acredita y Facturación lo marcará como $0.00.
      </div>
    <?php endif; ?>

    <!-- Formulario upload (solo líder, solo si pendiente o rechazado) -->
    <?php if ($puedeSubirVinc): ?>
    <form method="POST" action="vinculacion.php" enctype="multipart/form-data" id="form-comp-vinc"
          onsubmit="return validarEnvioVinc(this);">
      <input type="hidden" name="accion_pago_vinc" value="enviar_comprobante_vinc">

      <!-- Zona drag & drop igual a mi_practica -->
      <div class="upload-zone-vinc mb-3" id="upzone-vinc"
           onclick="document.getElementById('input-comp-vinc').click()">
        <input type="file" name="comprobante_pago_vinc" id="input-comp-vinc"
               accept=".pdf,.jpg,.jpeg,.png"
               onchange="previewCompVinc(this)">
        <div id="ph-vinc">
          <i class="fa fa-cloud-arrow-up" style="font-size:28px;color:var(--text-muted);margin-bottom:8px;display:block;"></i>
          <div style="font-weight:600;color:var(--text-secondary);font-size:13px;">Haz clic o arrastra el archivo aquí</div>
          <div style="font-size:11px;color:var(--text-muted);margin-top:4px;">PDF, JPG o PNG · Máximo 5 MB</div>
        </div>
        <div id="pv-vinc" style="display:none;">
          <i class="fa fa-file-check" style="font-size:26px;color:var(--green);margin-bottom:6px;display:block;"></i>
          <div id="fn-vinc" style="font-weight:600;color:#15803d;font-size:13px;"></div>
          <div style="font-size:11px;color:var(--green);margin-top:2px;">Listo para enviar</div>
        </div>
      </div>

      <div class="d-flex gap-3 flex-wrap align-items-center">
        <button type="submit" class="btn btn-primary px-4" id="btn-env-vinc">
          <i class="fa fa-paper-plane me-2"></i>
          <?= $estPagoVinc === 'rechazado' ? 'Reenviar Comprobante' : 'Enviar Comprobante' ?>
        </button>
        <span style="font-size:12px;color:var(--text-muted);">
          <i class="fa fa-lock me-1"></i>Tu comprobante irá a Facturación para validación
        </span>
      </div>
    </form>
    <?php endif; ?>
  </div><!-- /seccion-pago-vinc -->

  <div class="sec-arrow-vinc"><i class="fa fa-arrow-down"></i></div>

  <!-- ── Tabla resumen de semanas ── -->
  <div class="section-label-head" style="margin-top:4px;">
    <i class="fa fa-book-open me-1"></i>Resumen de bitácoras
  </div>

  <!-- Filtro estado + paginación -->
  <div class="d-flex gap-2 mb-3 flex-wrap align-items-center"
       style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:10px;padding:10px 14px;">
    <div class="d-flex gap-1 flex-wrap">
      <?php foreach([''=> 'Todas','borrador'=>'Borrador','enviada'=>'Enviada','validada'=>'Validada','observada'=>'Observada'] as $est=>$lbl): ?>
      <a href="?estado_bit=<?= $est ?>&pp=<?= $perPageBit ?>&page=1"
         class="btn btn-sm <?= $filEstadoBit===$est?'btn-primary':'btn-outline-secondary' ?>"
         style="font-size:12px;"><?= $lbl ?></a>
      <?php endforeach; ?>
    </div>
    <div class="ms-auto d-flex align-items-center gap-2">
      <span style="font-size:12px;color:#64748b;">Mostrar</span>
      <?php foreach([5,10,25,50] as $pp): ?>
      <a href="?estado_bit=<?= $filEstadoBit ?>&pp=<?= $pp ?>&page=1"
         class="btn btn-sm <?= $perPageBit==$pp?'btn-primary':'btn-outline-secondary' ?>"
         style="font-size:12px;min-width:32px;"><?= $pp ?></a>
      <?php endforeach; ?>
    </div>
  </div>

  <?php
    // Aplicar filtro de estado
    $listaBitFiltrada = $filEstadoBit
        ? array_values(array_filter($listaBit, fn($b) => $b['estado'] === $filEstadoBit))
        : $listaBit;
    $totalBitRows  = count($listaBitFiltrada);
    $totalBitPages = $perPageBit > 0 && $totalBitRows > 0 ? max(1, (int)ceil($totalBitRows / $perPageBit)) : 1;
    $listaBitPag   = array_slice($listaBitFiltrada, $offsetBit, $perPageBit);
  ?>
  <div style="font-size:12px;color:#64748b;margin-bottom:8px;">
    Mostrando <?= $totalBitRows>0 ? min($offsetBit+1,$totalBitRows) : 0 ?>–<?= min($offsetBit+$perPageBit,$totalBitRows) ?> de <?= $totalBitRows ?> bitácoras
  </div>

  <div class="tbl-wrap" style="margin-bottom:20px">
    <table class="table table-borderless mb-0">
      <thead><tr><th>#</th><th>Semana</th><th>Período</th><th class="text-center">Secciones</th><th class="text-center">Horas</th><th>Estado</th><th class="text-center">Ver</th></tr></thead>
      <tbody>
        <?php if(empty($listaBitPag)):?>
        <tr><td colspan="7" class="text-center text-muted py-4">No hay bitácoras<?= $filEstadoBit ? ' con estado "'.$filEstadoBit.'"' : '' ?>.</td></tr>
        <?php else:foreach($listaBitPag as $idx=>$b):$ed=in_array($b['estado'],['borrador','observada'])&&$puedeEditar;?>
        <tr class="bit-row" onclick="location='vinculacion.php?bit=<?=$b['id_bitacora']?>'">
          <td style="font-size:11px;color:#94a3b8;"><?= $offsetBit+$idx+1 ?></td>
          <td><strong>Semana <?=$b['semana_numero']?></strong><?php if($ed&&$b['total_sec']<count($miembros)):?> <span style="font-size:9px;padding:1px 6px;border-radius:4px;background:#fef3c7;color:#d97706;font-weight:700;border:1px solid #fde68a">FALTAN APORTES</span><?php endif;?></td>
          <td style="font-size:12px;color:#64748b"><?=formatFecha($b['fecha_inicio_semana'])?> – <?=formatFecha($b['fecha_fin_semana'])?></td>
          <td class="text-center" style="font-weight:600;color:#2563eb"><?=$b['total_sec']?>/<?=count($miembros)?></td>
          <td class="text-center" style="font-weight:700"><?=$b['horas_totales_grupo']?>h</td>
          <td><?=badgeEstado($b['estado'])?></td>
          <td class="text-center" onclick="event.stopPropagation()"><a href="vinculacion.php?bit=<?=$b['id_bitacora']?>" class="btn btn-sm btn-outline-secondary"><i class="fa fa-eye"></i></a></td>
        </tr>
        <?php endforeach;endif;?>

        <!-- Paginación -->
        <?php if($totalBitPages > 1): ?>
        <tr><td colspan="7" style="padding:10px 0;">
          <div class="d-flex justify-content-center gap-1 flex-wrap">
            <?php if($pageBit>1): ?>
            <a href="?estado_bit=<?=$filEstadoBit?>&pp=<?=$perPageBit?>&page=<?=$pageBit-1?>"
               class="btn btn-sm btn-outline-secondary" style="font-size:12px;"><i class="fa fa-chevron-left"></i></a>
            <?php endif; ?>
            <?php for($pg=max(1,$pageBit-2);$pg<=min($totalBitPages,$pageBit+2);$pg++): ?>
            <a href="?estado_bit=<?=$filEstadoBit?>&pp=<?=$perPageBit?>&page=<?=$pg?>"
               class="btn btn-sm <?=$pg==$pageBit?'btn-primary':'btn-outline-secondary'?>" style="font-size:12px;min-width:34px;"><?=$pg?></a>
            <?php endfor; ?>
            <?php if($pageBit<$totalBitPages): ?>
            <a href="?estado_bit=<?=$filEstadoBit?>&pp=<?=$perPageBit?>&page=<?=$pageBit+1?>"
               class="btn btn-sm btn-outline-secondary" style="font-size:12px;"><i class="fa fa-chevron-right"></i></a>
            <?php endif; ?>
          </div>
        </td></tr>
        <?php endif; ?>
      </tbody>
    </table>
  </div>

  <!-- ══════════════════════════════════════════════
       PANEL CALIFICACIONES — solo cuando completado
  ══════════════════════════════════════════════ -->
  <?php if($esCompletado):?>
  <div class="section-label-head"><i class="fa fa-graduation-cap me-1"></i>Mis calificaciones de vinculacion</div>

  <?php if(!$miCalificacion||$miCalificacion['estado']!=='calificado'):?>
  <!-- Aun sin calificar -->
  <div style="background:#f5f3ff;border:2px dashed #c4b5fd;border-radius:14px;padding:32px;text-align:center;margin-bottom:20px">
    <div style="font-size:28px;margin-bottom:10px">🎓</div>
    <div style="font-size:14px;font-weight:600;color:#7c3aed;margin-bottom:6px">Tu calificacion esta pendiente</div>
    <div style="font-size:13px;color:#64748b">El tutor aun no ha ingresado tus notas. Vuelve pronto.</div>
  </div>

  <?php else:
    $n1=(float)$miCalificacion['nota_informe_pdf'];
    $n2=(float)$miCalificacion['nota_trabajo_individual'];
    $prom=(float)$miCalificacion['nota_promedio'];
    $aprobado=$prom>=70;
    $label=notaLabel($prom);
    $colorProm=$aprobado?'#15803d':'#dc2626';
    $colorHeader=$aprobado?'linear-gradient(135deg,#f0fdf4,#dcfce7)':'linear-gradient(135deg,#fef2f2,#fee2e2)';
    $borderColor=$aprobado?'#86efac':'#fca5a5';
  ?>
  <!-- Calificado -->
  <div class="cal-panel" style="border:2px solid <?=$borderColor?>">
    <!-- Header resultado -->
    <div class="cal-header" style="background:<?=$colorHeader?>">
      <div>
        <div style="font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:<?=$colorProm?>;margin-bottom:4px">
          <?=$aprobado?'APROBADO':'REPROBADO'?> — <?=$label?>
        </div>
        <div style="font-size:11px;color:#64748b">
          Calificado por <?=htmlspecialchars($miCalificacion['tutor_nombre']??'Tutor')?>
          &nbsp;·&nbsp; <?=$miCalificacion['fecha_calificacion']?date('d/m/Y H:i',strtotime($miCalificacion['fecha_calificacion'])):'—'?>
        </div>
      </div>
      <div style="display:flex;gap:6px;flex-wrap:wrap">
        <span style="font-size:10px;padding:3px 10px;border-radius:20px;background:#f5f3ff;color:#7c3aed;border:1px solid #ddd6fe;font-weight:600">CES 2022</span>
        <span style="font-size:10px;padding:3px 10px;border-radius:20px;background:#f5f3ff;color:#7c3aed;border:1px solid #ddd6fe;font-weight:600">CACES</span>
      </div>
    </div>

    <div class="cal-body">
      <!-- 3 tarjetas de notas -->
      <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-bottom:18px">
        <!-- N1 -->
        <div class="nota-card" style="background:#eff6ff;border:1px solid #bfdbfe">
          <div style="font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#64748b;margin-bottom:8px">N1 — Informe PDF</div>
          <div class="nota-num" style="color:#2563eb"><?=number_format($n1,1)?></div>
          <div class="nota-max">/ 100</div>
          <div class="barra-bg"><div class="barra-fill" style="width:<?=$n1?>%;background:#2563eb"></div></div>
        </div>
        <!-- N2 -->
        <div class="nota-card" style="background:#f5f3ff;border:1px solid #ddd6fe">
          <div style="font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#64748b;margin-bottom:8px">N2 — Trabajo Individual</div>
          <div class="nota-num" style="color:#7c3aed"><?=number_format($n2,1)?></div>
          <div class="nota-max">/ 100</div>
          <div class="barra-bg"><div class="barra-fill" style="width:<?=$n2?>%;background:#7c3aed"></div></div>
        </div>
        <!-- Promedio -->
        <div class="nota-card" style="background:<?=$aprobado?'#f0fdf4':'#fef2f2'?>;border:2px solid <?=$colorProm?>55">
          <div style="font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;color:#64748b;margin-bottom:8px">Promedio Final</div>
          <div class="nota-num" style="color:<?=$colorProm?>"><?=number_format($prom,1)?></div>
          <div class="nota-max">/ 100</div>
          <div class="barra-bg"><div class="barra-fill" style="width:<?=$prom?>%;background:<?=$colorProm?>"></div></div>
          <div class="nota-label" style="color:<?=$colorProm?>"><?=$label?></div>
        </div>
      </div>

      <!-- Escala referencia -->
      <div style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:12px">
        <span style="font-size:10px;padding:2px 8px;border-radius:20px;background:#f0fdf4;color:#15803d;border:1px solid #86efac;font-weight:600">90–100 Excelente</span>
        <span style="font-size:10px;padding:2px 8px;border-radius:20px;background:#dcfce7;color:#16a34a;border:1px solid #bbf7d0;font-weight:600">80–89 Muy Bueno</span>
        <span style="font-size:10px;padding:2px 8px;border-radius:20px;background:#eff6ff;color:#2563eb;border:1px solid #bfdbfe;font-weight:600">70–79 Bueno</span>
        <span style="font-size:10px;padding:2px 8px;border-radius:20px;background:#fef2f2;color:#dc2626;border:1px solid #fca5a5;font-weight:600">0–69 Reprobado</span>
        <span style="font-size:10px;padding:2px 8px;border-radius:20px;background:#f1f5f9;color:#64748b;border:1px solid #e2e8f0;font-weight:600">Min. aprobatorio: 70/100</span>
      </div>

      <?php if($miCalificacion['observaciones']):?>
      <div style="background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:12px 14px">
        <div style="font-size:11px;font-weight:700;color:#64748b;margin-bottom:6px"><i class="fa fa-comment-dots me-1"></i>Observacion del tutor:</div>
        <div style="font-size:13px;color:#1e293b"><?=nl2br(htmlspecialchars($miCalificacion['observaciones']))?></div>
      </div>
      <?php endif;?>

      <div style="font-size:10px;color:#94a3b8;margin-top:12px;text-align:right">
        Normativa: Reglamento Régimen Académico CES 2022 · CACES · LOES Art. 87
      </div>
    </div>
  </div>
  <?php endif;?>
  <?php endif;?>
  <!-- ══ FIN CALIFICACIONES ══ -->

  <!-- ══ CERTIFICADO DE VINCULACIÓN ══ -->
  <?php if($esCompletado && $miCertificado): ?>
  <div style="background:#ffffff;border:1px solid #bbf7d0;border-radius:14px;
              padding:20px 22px;margin-bottom:16px;box-shadow:0 1px 6px rgba(16,185,129,.08);">
    <div style="display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:space-between;">
      <div style="display:flex;align-items:center;gap:12px;">
        <div style="width:44px;height:44px;background:#f0fdf4;border:1px solid #86efac;
                    border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;">
          <i class="fa fa-award" style="color:#16a34a;font-size:20px;"></i>
        </div>
        <div>
          <div style="font-size:14px;font-weight:700;color:#0f172a;">
            Certificado de Vinculación con la Comunidad
          </div>
          <div style="font-size:12px;color:#64748b;margin-top:2px;">
            <i class="fa fa-calendar me-1"></i>
            Emitido el <?= date('d/m/Y', strtotime($miCertificado['fecha_emision'])) ?>
            &nbsp;·&nbsp;
            <span style="font-family:monospace;font-size:11px;color:#94a3b8;">
              <?= htmlspecialchars($miCertificado['codigo_qr']) ?>
            </span>
          </div>
          <?php if($miCertificado['firmado'] && $miCertificado['fecha_firma']): ?>
          <div style="font-size:11px;color:#16a34a;margin-top:3px;">
            <i class="fa fa-circle-check me-1"></i>
            Firmado el <?= date('d/m/Y', strtotime($miCertificado['fecha_firma'])) ?>
          </div>
          <?php endif; ?>
        </div>
      </div>
      <div style="display:flex;gap:8px;flex-wrap:wrap;">
        <?php if($miCertificado['firmado'] && $miCertificado['archivo_pdf_firmado']): ?>
        <!-- Certificado firmado disponible -->
        <a href="<?= BASE_URL ?>/assets/uploads/<?= htmlspecialchars($miCertificado['archivo_pdf_firmado']) ?>"
           target="_blank"
           style="display:inline-flex;align-items:center;gap:7px;background:#16a34a;color:#fff;
                  border-radius:8px;padding:9px 18px;font-size:13px;font-weight:600;text-decoration:none;
                  box-shadow:0 2px 6px rgba(16,163,74,.25);transition:background .2s;"
           onmouseover="this.style.background='#15803d'" onmouseout="this.style.background='#16a34a'">
          <i class="fa fa-file-pdf fa-sm"></i> Descargar certificado firmado
        </a>
        <?php else: ?>
        <!-- Emitido pero aún sin firma -->
        <div style="display:inline-flex;align-items:center;gap:7px;background:#fefce8;
                    border:1px solid #fde68a;border-radius:8px;padding:9px 16px;
                    font-size:12px;color:#92400e;">
          <i class="fa fa-clock fa-sm"></i> Pendiente de firma por secretaría
        </div>
        <?php endif; ?>
      </div>
    </div>

    <?php if(!$miCertificado['firmado']): ?>
    <div style="background:#fffbeb;border:1px solid #fde68a;border-radius:8px;
                padding:10px 14px;margin-top:12px;font-size:12px;color:#92400e;">
      <i class="fa fa-info-circle me-1"></i>
      Tu certificado ya fue emitido. La secretaría académica lo firmará y lo encontrarás disponible aquí para descargarlo.
    </div>
    <?php endif; ?>
  </div>
  <?php elseif($esCompletado && !$miCertificado): ?>
  <!-- Grupo completado pero aún no se emitió el certificado -->
  <div style="background:#f8fafc;border:1px dashed #cbd5e1;border-radius:12px;
              padding:18px 20px;margin-bottom:16px;text-align:center;">
    <i class="fa fa-award" style="color:#cbd5e1;font-size:28px;display:block;margin-bottom:8px;"></i>
    <div style="font-size:13px;font-weight:600;color:#64748b;">Certificado de vinculación</div>
    <div style="font-size:12px;color:#94a3b8;margin-top:4px;">
      Aún no ha sido emitido por secretaría. Estará disponible aquí cuando esté listo.
    </div>
  </div>
  <?php endif; ?>
  <!-- ══ FIN CERTIFICADO ══ -->

  <!-- Documentos + Entrega Informe (visible en todos los estados) -->
  <?php if(!empty($docsVinc)):?>
  <?php foreach($docsVinc as $dv):
    $ext=strtolower(pathinfo($dv['archivo'],PATHINFO_EXTENSION));
    $ico=match($ext){'pdf'=>'fa-file-pdf','doc','docx'=>'fa-file-word','xlsx'=>'fa-file-excel',default=>'fa-file'};
    $colorIco=match($ext){'pdf'=>'#dc2626','doc','docx'=>'#2563eb',default=>'#64748b'};
    $estInf=$entrega?$entrega['estado']:'sin';
    $clsBox=match($estInf){'pendiente_revision'=>'pendiente','observado'=>'observado','aprobado'=>'aprobado',default=>'sin'};
  ?>
  <div style="background:#ffffff;border:1px solid #bfdbfe;border-radius:12px;padding:18px 20px;margin-bottom:16px;box-shadow:0 1px 4px rgba(37,99,235,.06)">
    <div style="font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:#2563eb;margin-bottom:14px">
      <i class="fa fa-folder-open me-1"></i>Documento de apoyo — descarga, llena y envia
    </div>
    <div class="doc-item mb-3">
      <div class="doc-item-info">
        <i class="fa <?=$ico?> fa-lg" style="color:<?=$colorIco?>;flex-shrink:0"></i>
        <div style="min-width:0">
          <div class="doc-item-title"><?=htmlspecialchars($dv['nombre'])?></div>
          <?php if($dv['descripcion']):?><div class="doc-item-desc"><?=htmlspecialchars($dv['descripcion'])?></div><?php endif;?>
          <div class="doc-item-meta">Subido por <?=htmlspecialchars($dv['subido_por_nombre'])?> · <?=date('d/m/Y',strtotime($dv['created_at']))?></div>
        </div>
      </div>
      <a href="<?=BASE_URL?>/uploads/documentos_vinculacion/<?=urlencode($dv['archivo'])?>" target="_blank" class="btn btn-sm btn-primary" style="flex-shrink:0"><i class="fa fa-download me-1"></i>Descargar</a>
    </div>

    <div class="inf-box <?=$clsBox?>">
      <div class="d-flex justify-content-between align-items-start flex-wrap gap-2 mb-2">
        <div>
          <div style="font-size:12px;font-weight:700;text-transform:uppercase;color:#64748b;margin-bottom:6px"><i class="fa fa-file-arrow-up me-1"></i>Tu entrega del informe llenado</div>
          <?=badgeEntrega($estInf)?>
        </div>
        <?php if($entrega&&$entrega['archivo']):?>
        <a href="<?=BASE_URL?>/uploads/informes_vinculacion/<?=urlencode($entrega['archivo'])?>" target="_blank" class="btn btn-sm btn-outline-<?=$estInf==='aprobado'?'success':'secondary'?>">
          <i class="fa fa-<?=$estInf==='aprobado'?'file-circle-check':'eye'?> me-1"></i>Ver <?=$estInf==='aprobado'?'informe aprobado':'entrega actual'?>
        </a>
        <?php endif;?>
      </div>

      <?php if($estInf==='observado'&&$entrega['observacion_tutor']):?>
      <div style="background:#fffbeb;border:1px solid #fde68a;border-radius:8px;padding:10px 14px;margin-bottom:12px">
        <div style="font-size:11px;font-weight:700;color:#d97706;margin-bottom:4px"><i class="fa fa-comment-dots me-1"></i>OBSERVACION DEL TUTOR:</div>
        <div style="font-size:13px;color:#92400e"><?=nl2br(htmlspecialchars($entrega['observacion_tutor']))?></div>
      </div>
      <?php endif;?>

      <?php if($estInf==='aprobado'):?>
      <div style="font-size:13px;color:#16a34a;margin-top:4px"><i class="fa fa-circle-check me-1"></i>Informe aprobado. El proceso de vinculacion esta completado.</div>
      <?php elseif($esLider):?>
      <div style="font-size:12px;color:#64748b;margin-bottom:10px">
        <?php if($estInf==='sin'):?><i class="fa fa-circle-info me-1"></i>Descarga, completa con tu grupo y sube aqui.
        <?php elseif($estInf==='pendiente_revision'):?><i class="fa fa-clock me-1"></i>Esperando revision del tutor.
        <?php else:?><i class="fa fa-rotate-right me-1"></i>Corrige y vuelve a subir.<?php endif;?>
      </div>
      <form method="POST" enctype="multipart/form-data" class="d-flex gap-2 align-items-center flex-wrap">
        <input type="hidden" name="accion" value="subir_informe">
        <input type="file" name="archivo_informe" class="form-control form-control-sm" style="max-width:320px" required accept=".pdf,.doc,.docx">
        <button type="submit" class="btn btn-sm <?=$estInf==='observado'?'btn-warning':'btn-success'?>" onclick="return confirm('<?=$estInf==='sin'?'Enviar informe?':'Reemplazar y reenviar?'?>')">
          <i class="fa fa-paper-plane me-1"></i><?=$estInf==='sin'?'Enviar':($estInf==='observado'?'Reenviar corregido':'Reemplazar')?>
        </button>
      </form>
      <div style="font-size:10px;color:#94a3b8;margin-top:6px">PDF, DOC, DOCX · Max 20 MB</div>
      <?php else:?>
      <div style="font-size:12px;color:#64748b;margin-top:4px"><i class="fa fa-info-circle me-1"></i>Solo el lider puede subir el informe.</div>
      <?php endif;?>
    </div>
  </div>
  <?php endforeach;endif;?>

  <?php if($esLider&&$puedeEditar):?>
  <div class="modal fade" id="modalSemana" tabindex="-1"><div class="modal-dialog"><div class="modal-content">
    <div class="modal-header"><h5 class="modal-title"><i class="fa fa-calendar-week me-2"></i>Abrir semana <?=$nuevaSemana?></h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
    <form method="POST"><input type="hidden" name="accion" value="abrir_semana"><input type="hidden" name="id_grupo" value="<?=$grupo['id_grupo']?>">
      <div class="modal-body"><div class="row g-3">
        <div class="col-12"><label class="form-label">Numero de semana</label><input type="number" name="semana_numero" class="form-control" value="<?=$nuevaSemana?>" required min="1"></div>
        <div class="col-sm-6"><label class="form-label">Inicio (Lunes)</label><input type="date" name="fecha_inicio_semana" class="form-control" required value="<?=$lunes->format('Y-m-d')?>"></div>
        <div class="col-sm-6"><label class="form-label">Fin (Viernes)</label><input type="date" name="fecha_fin_semana" class="form-control" required value="<?=$viernes->format('Y-m-d')?>"></div>
      </div></div>
      <div class="modal-footer"><button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancelar</button><button type="submit" class="btn btn-primary"><i class="fa fa-calendar-plus me-1"></i>Abrir</button></div>
    </form>
  </div></div></div>
  <?php endif;?>

<?php endif;?>
</main></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js"></script>
<script>
/* ── Validar y enviar comprobante vinculación ── */
function validarEnvioVinc(form) {
  var input = document.getElementById('input-comp-vinc');
  if (!input || !input.files || input.files.length === 0) {
    alert('Debes seleccionar un archivo antes de enviar.');
    return false;
  }
  var btn = document.getElementById('btn-env-vinc');
  if (btn) {
    btn.disabled = true;
    btn.innerHTML = '<i class="fa fa-spinner fa-spin me-2"></i>Enviando...';
  }
  return true;
}

/* ── Preview upload comprobante vinculación ── */
function previewCompVinc(input) {
  if (input.files && input.files[0]) {
    document.getElementById('fn-vinc').textContent = input.files[0].name;
    document.getElementById('ph-vinc').style.display = 'none';
    document.getElementById('pv-vinc').style.display = 'block';
    document.getElementById('upzone-vinc').classList.add('loaded');
  }
}

/* ── Drag & drop vinculación ── */
var zoneVinc = document.getElementById('upzone-vinc');
if (zoneVinc) {
  zoneVinc.addEventListener('dragover', function(e){ e.preventDefault(); zoneVinc.style.borderColor='#f97316'; });
  zoneVinc.addEventListener('dragleave', function(){ zoneVinc.style.borderColor=''; });
  zoneVinc.addEventListener('drop', function(e){
    e.preventDefault(); zoneVinc.style.borderColor='';
    var input = document.getElementById('input-comp-vinc');
    if (e.dataTransfer.files.length) {
      try { var dt=new DataTransfer(); dt.items.add(e.dataTransfer.files[0]); input.files=dt.files; } catch(ex){}
      previewCompVinc(input);
    }
  });
}

function toggleMiembro(divId){
  var body=document.getElementById(divId);
  var ico=document.getElementById('ico_'+divId);
  if(body.classList.contains('open')){
    body.classList.remove('open');
    ico.style.transform='rotate(0deg)';
  }else{
    body.classList.add('open');
    ico.style.transform='rotate(180deg)';
  }
}
// Rotar icono de los que están abiertos por defecto
document.querySelectorAll('.miembro-body.open').forEach(function(el){
  var ico=document.getElementById('ico_'+el.id);
  if(ico) ico.style.transform='rotate(180deg)';
});
</script>
</body></html>