<?php
require_once dirname(__DIR__) . '/includes/optimizador_multimedia.php';

include("config.php");

/* =========================================
   DASHBOARD_EDITOR.PHP
   INTERFAZ TIPO ARCHIVOS / BIBLIOTECA
========================================= */

if (!isset($_SESSION['usuario_id']) || $_SESSION['rol_id'] != 3) {
    header("Location: index.php");
    exit();
}

$usuario_id = intval($_SESSION['usuario_id']);
$nombre = htmlspecialchars($_SESSION['nombre'] ?? 'Editor', ENT_QUOTES, 'UTF-8');

$mensaje = "";
$mensaje_soporte = "";


/* =========================================
   AJAX EDITAR INFORMACIÓN DE ARCHIVO
========================================= */
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['ajax_update_file'])) {

    header('Content-Type: application/json; charset=utf-8');

    $id = isset($_POST['id']) ? intval($_POST['id']) : 0;
    $titulo = isset($_POST['titulo']) ? limpiarDato($_POST['titulo']) : "";
    $descripcion = isset($_POST['descripcion']) ? limpiarDato($_POST['descripcion']) : "";
    $fecha_nota = isset($_POST['fecha_nota']) ? limpiarDato($_POST['fecha_nota']) : "";

    if ($id <= 0 || $titulo === "" || $fecha_nota === "") {
        echo json_encode(array("ok" => false, "mensaje" => "Datos incompletos."));
        exit();
    }

    $verificar = $conn->query("SELECT id FROM notas WHERE id='$id' AND usuario_id='$usuario_id' LIMIT 1");

    if (!$verificar || $verificar->num_rows == 0) {
        echo json_encode(array("ok" => false, "mensaje" => "Archivo no encontrado."));
        exit();
    }

    $sql_update = "UPDATE notas
                   SET titulo='$titulo', descripcion='$descripcion', fecha_nota='$fecha_nota'
                   WHERE id='$id' AND usuario_id='$usuario_id'
                   LIMIT 1";

    if ($conn->query($sql_update) === TRUE) {
        $conn->query("INSERT INTO bitacora (usuario_id, accion, nota_id)
                      VALUES ('$usuario_id', 'Editó información de archivo', '$id')");

        echo json_encode(array("ok" => true, "mensaje" => "Información actualizada."));
    } else {
        echo json_encode(array("ok" => false, "mensaje" => "No se pudo actualizar."));
    }

    exit();
}

/* =========================================
   AJAX ELIMINAR ARCHIVO INDIVIDUAL
========================================= */
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['ajax_delete_file'])) {

    header('Content-Type: application/json; charset=utf-8');

    $id = isset($_POST['id']) ? intval($_POST['id']) : 0;

    if ($id <= 0) {
        echo json_encode(array("ok" => false, "mensaje" => "ID inválido."));
        exit();
    }

    $buscar = $conn->query("SELECT id, archivo FROM notas WHERE id='$id' AND usuario_id='$usuario_id' LIMIT 1");

    if (!$buscar || $buscar->num_rows == 0) {
        echo json_encode(array("ok" => false, "mensaje" => "Archivo no encontrado."));
        exit();
    }

    $row_delete = $buscar->fetch_assoc();

    if (!empty($row_delete['archivo'])) {
        $ruta_archivo = __DIR__ . "/uploads/" . basename($row_delete['archivo']);
        if (file_exists($ruta_archivo)) {
            unlink($ruta_archivo);
        }
    }

    $conn->query("DELETE FROM notas WHERE id='$id' AND usuario_id='$usuario_id' LIMIT 1");
    $conn->query("INSERT INTO bitacora (usuario_id, accion, nota_id)
                  VALUES ('$usuario_id', 'Eliminó archivo', '$id')");

    echo json_encode(array("ok" => true, "mensaje" => "Archivo eliminado."));
    exit();
}

/* =========================================
   AJAX ELIMINAR ARCHIVOS SELECCIONADOS
========================================= */
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['ajax_bulk_delete'])) {

    header('Content-Type: application/json; charset=utf-8');

    $ids_raw = isset($_POST['ids']) ? $_POST['ids'] : "";
    $ids_array = array_filter(array_map('intval', explode(',', $ids_raw)));

    if (count($ids_array) == 0) {
        echo json_encode(array("ok" => false, "mensaje" => "No hay archivos seleccionados."));
        exit();
    }

    $eliminados = 0;

    foreach ($ids_array as $id_delete) {

        if ($id_delete <= 0) {
            continue;
        }

        $buscar = $conn->query("SELECT id, archivo FROM notas WHERE id='$id_delete' AND usuario_id='$usuario_id' LIMIT 1");

        if ($buscar && $buscar->num_rows > 0) {
            $row_delete = $buscar->fetch_assoc();

            if (!empty($row_delete['archivo'])) {
                $ruta_archivo = __DIR__ . "/uploads/" . basename($row_delete['archivo']);
                if (file_exists($ruta_archivo)) {
                    unlink($ruta_archivo);
                }
            }

            $conn->query("DELETE FROM notas WHERE id='$id_delete' AND usuario_id='$usuario_id' LIMIT 1");
            $conn->query("INSERT INTO bitacora (usuario_id, accion, nota_id)
                          VALUES ('$usuario_id', 'Eliminó archivo seleccionado', '$id_delete')");
            $eliminados++;
        }
    }

    echo json_encode(array("ok" => true, "mensaje" => "Archivos eliminados.", "total" => $eliminados));
    exit();
}

/* =========================================
   AJAX GUARDAR RECORTE DE IMAGEN
========================================= */
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['ajax_save_crop'])) {

    header('Content-Type: application/json; charset=utf-8');

    $id_origen = isset($_POST['id']) ? intval($_POST['id']) : 0;
    $imagen_base64 = isset($_POST['imagen']) ? $_POST['imagen'] : "";

    if ($id_origen <= 0 || $imagen_base64 === "") {
        echo json_encode(array("ok" => false, "mensaje" => "Datos incompletos para guardar el recorte."));
        exit();
    }

    $buscar = $conn->query("SELECT * FROM notas WHERE id='$id_origen' AND usuario_id='$usuario_id' LIMIT 1");

    if (!$buscar || $buscar->num_rows == 0) {
        echo json_encode(array("ok" => false, "mensaje" => "Imagen original no encontrada."));
        exit();
    }

    $nota_origen = $buscar->fetch_assoc();
    $extension_origen = strtolower(pathinfo($nota_origen['archivo'], PATHINFO_EXTENSION));

    if (!in_array($extension_origen, array('jpg','jpeg','png','gif','webp'))) {
        echo json_encode(array("ok" => false, "mensaje" => "Solo se pueden recortar imágenes."));
        exit();
    }

    if (strpos($imagen_base64, 'base64,') !== false) {
        $partes = explode('base64,', $imagen_base64);
        $imagen_base64 = $partes[1];
    }

    $imagen_decodificada = base64_decode($imagen_base64);

    if ($imagen_decodificada === false) {
        echo json_encode(array("ok" => false, "mensaje" => "No se pudo procesar el recorte."));
        exit();
    }

    $carpeta = __DIR__ . "/uploads/";

    if (!is_dir($carpeta)) {
        mkdir($carpeta, 0755, true);
    }

    $titulo_base = limpiarDato($nota_origen['titulo']);
    $nombre_limpio = preg_replace("/[^A-Za-z0-9_\.-]/", "_", $titulo_base);
    $archivo_nombre = time() . "_" . uniqid() . "_recorte_" . $nombre_limpio . ".png";
    $ruta_guardado = $carpeta . $archivo_nombre;

    if (file_put_contents($ruta_guardado, $imagen_decodificada) === false) {
        echo json_encode(array("ok" => false, "mensaje" => "No se pudo guardar el recorte en el servidor."));
        exit();
    }

    $fecha_nota = date("Y-m-d");
    $tipo_medio = "Archivo";
    $subtipo_medio = "Recorte de imagen";
    $tipo_nota = "neutral";
    $caracter = "NOTA";
    $titulo = limpiarDato("Recorte - " . $nota_origen['titulo']);
    $descripcion = limpiarDato("Recorte generado desde la imagen: " . $nota_origen['titulo']);

    $sql = "INSERT INTO notas (
                usuario_id,
                fecha_nota,
                tipo_medio,
                subtipo_medio,
                tipo_nota,
                caracter,
                titulo,
                descripcion,
                archivo,
                estado,
                correcciones
            ) VALUES (
                '$usuario_id',
                '$fecha_nota',
                '$tipo_medio',
                '$subtipo_medio',
                '$tipo_nota',
                '$caracter',
                '$titulo',
                '$descripcion',
                '$archivo_nombre',
                'aprobada',
                0
            )";

    if ($conn->query($sql) === TRUE) {
        $nota_id = $conn->insert_id;
        $link_publico = "https://app.emisorascruz.pe/nota.php?id=" . $nota_id;

        $conn->query("UPDATE notas SET link_publico='$link_publico' WHERE id='$nota_id'");
        $conn->query("INSERT INTO bitacora (usuario_id, accion, nota_id)
                      VALUES ('$usuario_id', 'Generó recorte de imagen desde archivo ID: $id_origen', '$nota_id')");

        echo json_encode(array(
            "ok" => true,
            "mensaje" => "Recorte guardado correctamente.",
            "id" => $nota_id,
            "archivo" => $archivo_nombre
        ));
    } else {
        if (file_exists($ruta_guardado)) {
            unlink($ruta_guardado);
        }
        echo json_encode(array("ok" => false, "mensaje" => "El recorte se creó, pero no se registró en la base de datos."));
    }

    exit();
}

/* =========================================
   CARGA MASIVA AJAX DE ARCHIVOS
========================================= */
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['ajax_upload_file'])) {

    header('Content-Type: application/json; charset=utf-8');

    $respuesta = array(
        "ok" => false,
        "mensaje" => "No se recibió archivo."
    );

    if (isset($_FILES['archivo']) && !empty($_FILES['archivo']['name'])) {

        $carpeta = __DIR__ . "/uploads/";

        if (!is_dir($carpeta)) {
            mkdir($carpeta, 0755, true);
        }

        $archivo_original = basename($_FILES["archivo"]["name"]);
        $extension = strtolower(pathinfo($archivo_original, PATHINFO_EXTENSION));
        $nombre_limpio = preg_replace("/[^A-Za-z0-9_\.\-]/", "_", $archivo_original);
        $archivo_nombre = time() . "_" . uniqid() . "_" . $nombre_limpio;
        $ruta = $carpeta . $archivo_nombre;

        /* =========================
           EVITAR ARCHIVOS REPETIDOS
           Se compara nombre original limpio + tamaño.
        ========================= */
        $archivo_repetido = false;
        $tamano_archivo = intval($_FILES["archivo"]["size"]);
        $archivos_existentes = glob($carpeta . "*_" . $nombre_limpio);

        if ($archivos_existentes) {
            foreach ($archivos_existentes as $archivo_existente) {
                if (is_file($archivo_existente) && filesize($archivo_existente) == $tamano_archivo) {
                    $archivo_repetido = true;
                    break;
                }
            }
        }

        if ($archivo_repetido) {
            $respuesta = array(
                "ok" => false,
                "duplicado" => true,
                "mensaje" => "Archivo repetido. No se subió para ahorrar espacio."
            );
            echo json_encode($respuesta);
            exit();
        }

        if (move_uploaded_file($_FILES["archivo"]["tmp_name"], $ruta)) {
            ec_optimizar_archivo_subido($ruta, $archivo_original);

            $fecha_nota = date("Y-m-d");
            $tipo_medio = "Archivo";
            $subtipo_medio = "Carga masiva";
            $tipo_nota = "neutral";
            $caracter = "NOTA";
            $titulo = limpiarDato(pathinfo($archivo_original, PATHINFO_FILENAME));
            $descripcion = limpiarDato("Archivo cargado automáticamente desde la biblioteca de archivos.");

            $sql = "INSERT INTO notas (
                        usuario_id,
                        fecha_nota,
                        tipo_medio,
                        subtipo_medio,
                        tipo_nota,
                        caracter,
                        titulo,
                        descripcion,
                        archivo,
                        estado,
                        correcciones
                    ) VALUES (
                        '$usuario_id',
                        '$fecha_nota',
                        '$tipo_medio',
                        '$subtipo_medio',
                        '$tipo_nota',
                        '$caracter',
                        '$titulo',
                        '$descripcion',
                        '$archivo_nombre',
                        'aprobada',
                        0
                    )";

            if ($conn->query($sql) === TRUE) {

                $nota_id = $conn->insert_id;
                $link_publico = "https://app.emisorascruz.pe/nota.php?id=" . $nota_id;

                $conn->query("UPDATE notas SET link_publico='$link_publico' WHERE id='$nota_id'");

                $conn->query("INSERT INTO bitacora (usuario_id, accion, nota_id)
                              VALUES ('$usuario_id', 'Cargó archivo masivo: $archivo_original', '$nota_id')");

                $respuesta = array(
                    "ok" => true,
                    "mensaje" => "Archivo cargado correctamente.",
                    "id" => $nota_id,
                    "archivo" => $archivo_nombre
                );

            } else {

                $respuesta = array(
                    "ok" => false,
                    "mensaje" => "El archivo subió, pero no se registró en la base de datos."
                );
            }

        } else {

            $respuesta = array(
                "ok" => false,
                "mensaje" => "No se pudo mover el archivo al servidor."
            );
        }
    }

    echo json_encode($respuesta);
    exit();
}


/* =========================================
   REGISTRAR NOTICIA DESDE MENÚ LATERAL
========================================= */
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['guardar_noticia'])) {

    $fecha_nota = isset($_POST['fecha_nota']) ? limpiarDato($_POST['fecha_nota']) : "";
    $tipo_medio = isset($_POST['tipo_medio']) ? limpiarDato($_POST['tipo_medio']) : "";
    $subtipo_medio = isset($_POST['subtipo_medio']) ? limpiarDato($_POST['subtipo_medio']) : "";
    $medio_id = isset($_POST['medio_id']) ? intval($_POST['medio_id']) : 0;
    $tono_id = isset($_POST['tono_id']) ? intval($_POST['tono_id']) : 0;
    $programa = isset($_POST['programa']) ? limpiarDato($_POST['programa']) : "";
    $titulo = isset($_POST['titulo']) ? limpiarDato($_POST['titulo']) : "";
    $descripcion = isset($_POST['descripcion']) ? limpiarDato($_POST['descripcion']) : "";
    $caracter = "NOTICIA";

    $region = "";
    $tarifa = 0;
    $tipo_nota = "neutral";

    if (
        $fecha_nota === "" ||
        $tipo_medio === "" ||
        $subtipo_medio === "" ||
        $medio_id <= 0 ||
        $tono_id <= 0 ||
        $titulo === "" ||
        $descripcion === ""
    ) {

        $mensaje = "Completa todos los campos obligatorios para registrar la noticia.";

    } else {

        $resultado_medio = $conn->query("
            SELECT id, region, valor
            FROM medios
            WHERE id='$medio_id' AND estado='activo'
            LIMIT 1
        ");

        if (!$resultado_medio || $resultado_medio->num_rows === 0) {

            $mensaje = "El medio seleccionado no existe o está inactivo.";

        } else {

            $datos_medio = $resultado_medio->fetch_assoc();
            $region = limpiarDato($datos_medio['region'] ?? '');
            $tarifa = isset($datos_medio['valor']) && is_numeric($datos_medio['valor'])
                ? (float)$datos_medio['valor']
                : 0;

            $resultado_tono = $conn->query("
                SELECT id, nombre
                FROM tonos
                WHERE id='$tono_id' AND estado='activo'
                LIMIT 1
            ");

            if (!$resultado_tono || $resultado_tono->num_rows === 0) {

                $mensaje = "El tono seleccionado no existe o está archivado.";

            } else {

                $datos_tono = $resultado_tono->fetch_assoc();
                $tipo_nota = strtolower(limpiarDato($datos_tono['nombre'] ?? 'neutral'));

                $sql_noticia = "INSERT INTO notas (
                                    usuario_id,
                                    medio_id,
                                    tono_id,
                                    programa,
                                    tarifa,
                                    region,
                                    fecha_nota,
                                    tipo_medio,
                                    subtipo_medio,
                                    tipo_nota,
                                    caracter,
                                    titulo,
                                    descripcion,
                                    archivo,
                                    estado,
                                    correcciones
                                ) VALUES (
                                    '$usuario_id',
                                    '$medio_id',
                                    '$tono_id',
                                    '$programa',
                                    '$tarifa',
                                    '$region',
                                    '$fecha_nota',
                                    '$tipo_medio',
                                    '$subtipo_medio',
                                    '$tipo_nota',
                                    '$caracter',
                                    '$titulo',
                                    '$descripcion',
                                    '',
                                    'aprobada',
                                    0
                                )";

                if ($conn->query($sql_noticia) === TRUE) {

                    $nota_id = $conn->insert_id;
                    $link_publico = "https://app.emisorascruz.pe/nota.php?id=" . $nota_id;

                    $conn->query("UPDATE notas SET link_publico='$link_publico' WHERE id='$nota_id'");

                    $conn->query("INSERT INTO bitacora (usuario_id, accion, nota_id)
                                  VALUES ('$usuario_id', 'Registró noticia desde panel editor', '$nota_id')");

                    $formulario_siguiente = 'redes_web';

                    if ($tipo_medio === 'Diario' || $tipo_medio === 'Prensa') {
                        $formulario_siguiente = 'prensa';
                    } elseif ($tipo_medio === 'Radio' || $tipo_medio === 'Televisión' || $tipo_medio === 'Television') {
                        $formulario_siguiente = 'radio_tv';
                    }

                    echo "<script>
                            window.location.href='dashboard_editor.php?modulo=noticias&form=".$formulario_siguiente."';
                          </script>";
                    exit();

                } else {

                    $mensaje = "No se pudo registrar la noticia.";
                }
            }
        }
    }
}

/* =========================================
   SOPORTE
========================================= */
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['enviar_soporte'])) {

    $mensaje_editor = trim($_POST['mensaje_soporte'] ?? '');

    if ($mensaje_editor === "") {

        $mensaje_soporte = "Debes escribir un mensaje.";

    } else {

        $mensaje_editor = limpiarDato($mensaje_editor);
        $numero_soporte = "51997525318";

        $texto_whatsapp = urlencode(
            "🛠️ REPORTE DE PLATAFORMA\n\n" .
            "Editor ID: " . $usuario_id . "\n" .
            "Editor: " . $_SESSION['nombre'] . "\n" .
            "Mensaje: " . $mensaje_editor
        );

        echo "<script>
                window.open('https://wa.me/".$numero_soporte."?text=".$texto_whatsapp."', '_blank');
                window.location.href='dashboard_editor.php';
              </script>";
        exit();
    }
}

/* =========================================
   MEDIOS ACTIVOS
========================================= */
$medios_array = [];

$sql_medios = "SELECT id, region, provincia, ciudad, tipo_medio, nombre_medio, valor
               FROM medios
               WHERE estado='activo'
               ORDER BY region ASC, provincia ASC, ciudad ASC, nombre_medio ASC";

$resultado_medios = $conn->query($sql_medios);

if ($resultado_medios && $resultado_medios->num_rows > 0) {
    while ($medio = $resultado_medios->fetch_assoc()) {
        $medios_array[] = $medio;
    }
}

/* =========================================
   TONOS ACTIVOS
========================================= */
$tonos_array = [];

$resultado_tonos = $conn->query("
    SELECT id, nombre, color
    FROM tonos
    WHERE estado='activo'
    ORDER BY nombre ASC
");

if ($resultado_tonos && $resultado_tonos->num_rows > 0) {
    while ($tono = $resultado_tonos->fetch_assoc()) {
        $tonos_array[] = $tono;
    }
}

/* =========================================
   ARCHIVOS DEL EDITOR
========================================= */
$archivos = [];

$sql_notas = "SELECT *
              FROM notas
              WHERE usuario_id='$usuario_id'
              ORDER BY id DESC";

$resultado_notas = $conn->query($sql_notas);

$total_archivos = 0;
$total_audio = 0;
$total_imagen = 0;
$total_video = 0;

if ($resultado_notas && $resultado_notas->num_rows > 0) {

    while ($row = $resultado_notas->fetch_assoc()) {

        $categoria = "documento";
        $icono = "▦";
        $thumb = "";

        if (!empty($row['archivo'])) {

            $ext = strtolower(pathinfo($row['archivo'], PATHINFO_EXTENSION));

            if (in_array($ext, ['mp3','wav'])) {
                $categoria = "audio";
                $icono = "🎧";
            } elseif (in_array($ext, ['jpg','jpeg','png','gif','webp'])) {
                $categoria = "imagen";
                $icono = "🖼";
                $thumb = "uploads/" . basename($row['archivo']);
            } elseif (in_array($ext, ['mp4','webm','mov','avi','mkv'])) {
                $categoria = "video";
                $icono = "🎬";
                $thumb = "uploads/" . basename($row['archivo']);
            } else {
                $categoria = "documento";
                $icono = "▦";
            }

        } else {
            $categoria = "documento";
            $icono = "▦";
        }

        if ($categoria == "audio") {
            $total_audio++;
        }

        if ($categoria == "imagen") {
            $total_imagen++;
        }

        if ($categoria == "video") {
            $total_video++;
        }

        $total_archivos++;

        $row['categoria_archivo'] = $categoria;
        $row['icono_archivo'] = $icono;
        $row['thumb_archivo'] = $thumb;

        $archivos[] = $row;
    }
}
?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Archivos</title>

<style>
*{
    margin:0;
    padding:0;
    box-sizing:border-box;
    font-family:Arial, sans-serif;
}

body{
    background:#faf7f5;
    color:#303030;
    overflow-x:hidden;
}

.app{
    display:flex;
    min-height:100vh;
}

/* =========================
   BARRA LATERAL OSCURA
========================= */
.sidebar{
    width:86px;
    background:#1e2942;
    color:white;
    position:fixed;
    top:0;
    left:0;
    bottom:0;
    display:flex;
    flex-direction:column;
    align-items:center;
    padding:18px 10px;
    z-index:50;
}

.logo{
    width:56px;
    height:56px;
    border-radius:14px;
    background:white;
    display:flex;
    align-items:center;
    justify-content:center;
    margin-bottom:30px;
    overflow:hidden;
}

.logo-text{
    color:#1e2942;
    font-size:14px;
    font-weight:bold;
    text-align:center;
    line-height:1.05;
}

.nav-icon{
    width:58px;
    height:58px;
    border-radius:14px;
    display:flex;
    flex-direction:column;
    justify-content:center;
    align-items:center;
    color:white;
    text-decoration:none;
    margin-bottom:14px;
    font-size:11px;
    cursor:pointer;
}

.nav-icon span{
    font-size:22px;
    margin-bottom:3px;
}

.nav-icon.active,
.nav-icon:hover{
    background:#f05a28;
}

.sidebar-bottom{
    margin-top:auto;
}

/* =========================
   PRINCIPAL
========================= */
.main{
    margin-left:86px;
    width:calc(100% - 86px);
    padding:22px 28px;
}

.header{
    display:flex;
    justify-content:space-between;
    align-items:center;
    margin-bottom:22px;
}

.header h1{
    font-size:30px;
    color:#1e2942;
    font-weight:800;
}

.btn-upload{
    background:#ef5124;
    color:white;
    border:none;
    padding:12px 18px;
    border-radius:8px;
    font-size:13px;
    font-weight:bold;
    cursor:pointer;
    text-transform:uppercase;
    box-shadow:0 3px 8px rgba(239,81,36,0.28);
}

.btn-upload:hover{
    background:#d9431b;
}

.header-actions{
    display:flex;
    align-items:center;
    gap:10px;
    flex-wrap:wrap;
}

.btn-mass-action{
    background:#1e2942;
    color:white;
    border:none;
    padding:12px 18px;
    border-radius:8px;
    font-size:13px;
    font-weight:bold;
    cursor:pointer;
    text-transform:uppercase;
    opacity:.45;
    pointer-events:none;
}

.btn-mass-action.active{
    opacity:1;
    pointer-events:auto;
}

.btn-mass-action.delete{
    background:#dc3545;
}

.btn-mass-action.download{
    background:#1e2942;
}

/* =========================
   CUERPO
========================= */
.workspace{
    display:grid;
    grid-template-columns:245px 1fr;
    gap:24px;
}

/* =========================
   FILTROS IZQUIERDA
========================= */
.filters{
    background:#fff;
    border-radius:14px;
    padding:18px;
    min-height:calc(100vh - 115px);
    box-shadow:0 4px 18px rgba(0,0,0,0.05);
}

.filter-list button{
    width:100%;
    border:none;
    background:transparent;
    text-align:left;
    padding:12px 10px;
    border-radius:9px;
    color:#5e5e5e;
    cursor:pointer;
    font-size:14px;
    margin-bottom:5px;
}

.filter-list button.active,
.filter-list button:hover{
    background:#fde9e2;
    color:#ef5124;
    font-weight:bold;
}

.filter-section{
    margin-top:25px;
    border-top:1px solid #eee;
    padding-top:18px;
}

.filter-section h3{
    font-size:14px;
    color:#1f2a44;
    margin-bottom:8px;
    font-weight:bold;
}

/* =========================
   FILTRO DE FECHAS PERSONALIZADO
========================= */
.custom-date-box{
    position:relative;
}

.date-display{
    border:1px solid #d9dce8;
    border-radius:8px;
    padding:14px 12px;
    background:white;
    cursor:pointer;
    display:flex;
    align-items:center;
    gap:9px;
    color:#6f7480;
    font-size:14px;
    margin-bottom:24px;
    min-height:50px;
}

.date-display.active{
    border:2px solid #b6b8c4;
    box-shadow:0 0 0 2px #d4d5dd;
}

.date-display .calendar-icon{
    font-size:17px;
}

.date-display em{
    font-style:italic;
}

.calendar-popup{
    display:none;
    position:absolute;
    top:62px;
    left:0;
    width:230px;
    background:white;
    border-radius:5px;
    box-shadow:0 4px 15px rgba(0,0,0,0.14);
    border:1px solid #eee;
    padding:10px;
    z-index:20;
}

.calendar-popup.show{
    display:block;
}

.calendar-head{
    display:flex;
    align-items:center;
    justify-content:space-between;
    margin-bottom:8px;
}

.calendar-head button{
    border:none;
    background:white;
    font-size:20px;
    color:#777;
    cursor:pointer;
    width:24px;
    height:24px;
}

.calendar-title{
    font-size:16px;
    color:#333;
    display:flex;
    align-items:center;
    gap:8px;
}

.calendar-title select{
    border:none;
    background:white;
    font-size:15px;
    color:#333;
    cursor:pointer;
}

.week-days{
    display:grid;
    grid-template-columns:repeat(7,1fr);
    text-align:center;
    font-size:10px;
    color:#999;
    margin-bottom:6px;
}

.days-grid{
    display:grid;
    grid-template-columns:repeat(7,1fr);
    gap:2px;
}

.day-cell{
    height:29px;
    display:flex;
    justify-content:center;
    align-items:center;
    font-size:11px;
    color:#555;
    cursor:pointer;
    position:relative;
    user-select:none;
    border-radius:0;
}

.day-cell.empty-day{
    cursor:default;
}

.day-cell:hover{
    background:#eaf3ff;
}

.day-cell.selected-start,
.day-cell.selected-end{
    background:#5aa2f2;
    color:white;
    border-radius:50%;
    z-index:2;
}

.day-cell.in-range{
    background:#d5d5d5;
    color:#555;
    border-radius:0;
}

.day-cell.preview-range{
    background:#e3eefc;
    color:#555;
    border-radius:0;
}

.day-cell.same-day{
    background:#5aa2f2;
    color:white;
    border-radius:50%;
}

.btn-filter{
    width:100%;
    border:none;
    background:#efeff7;
    color:#9ca3b5;
    padding:15px;
    border-radius:8px;
    font-weight:bold;
    cursor:not-allowed;
    text-transform:uppercase;
    font-size:12px;
}

.btn-filter.active{
    background:#ef5124;
    color:white;
    cursor:pointer;
}

.btn-filter.active:hover{
    background:#d9431b;
}

.btn-clear-filter{
    width:100%;
    border:none;
    background:#ffffff;
    color:#ef5124;
    padding:13px;
    border-radius:8px;
    font-weight:bold;
    cursor:pointer;
    text-transform:uppercase;
    font-size:12px;
    border:1px solid #ef5124;
    margin-top:10px;
}

.btn-clear-filter:hover{
    background:#fde9e2;
}

.user-block{
    margin-top:25px;
    background:#f7f7f7;
    border-radius:10px;
    padding:12px;
    font-size:12px;
    color:#555;
}

.user-block strong{
    display:block;
    color:#1e2942;
    margin-bottom:4px;
}

/* =========================
   GRILLA DE ARCHIVOS
========================= */
.files-grid{
    display:grid;
    grid-template-columns:repeat(auto-fill,minmax(235px,1fr));
    gap:22px;
    align-items:start;
}

.file-card{
    background:white;
    border-radius:13px;
    min-height:250px;
    position:relative;
    box-shadow:0 4px 18px rgba(0,0,0,0.06);
    overflow:hidden;
    transition:.2s;
    cursor:pointer;
}

.file-card:hover{
    transform:translateY(-3px);
    box-shadow:0 8px 24px rgba(0,0,0,0.12);
}

.file-preview{
    height:145px;
    background:#fbebe4;
    display:flex;
    align-items:center;
    justify-content:center;
    color:#ef5124;
    font-size:46px;
    position:relative;
    cursor:pointer;
}

.file-preview img,
.file-preview video{
    width:100%;
    height:100%;
    object-fit:cover;
}

.file-preview video{
    background:#000;
}

.file-check{
    position:absolute;
    top:12px;
    left:12px;
    z-index:12;
    width:20px;
    height:20px;
    cursor:pointer;
    accent-color:#ef5124;
}

.file-menu-btn{
    position:absolute;
    top:10px;
    right:10px;
    border:none;
    background:transparent;
    width:28px;
    height:34px;
    cursor:pointer;
    color:#ef5124;
    font-size:24px;
    line-height:24px;
    font-weight:bold;
    z-index:13;
}

.file-menu-btn:hover{
    color:#d9431b;
}

.file-dropdown{
    display:none;
    position:absolute;
    top:36px;
    right:22px;
    background:#1e2942;
    border-radius:7px;
    min-width:158px;
    box-shadow:0 8px 20px rgba(0,0,0,0.25);
    z-index:40;
    overflow:hidden;
    padding:10px 0;
}

.file-dropdown a,
.file-dropdown button{
    display:block;
    width:100%;
    padding:9px 14px;
    text-decoration:none;
    color:white;
    background:transparent;
    border:none;
    font-size:13px;
    text-align:left;
    cursor:pointer;
}

.file-dropdown a:hover,
.file-dropdown button:hover{
    background:#ef5124;
    color:white;
}

.file-body{
    padding:14px 15px;
}

.file-title{
    color:#222;
    font-size:14px;
    font-weight:bold;
    line-height:1.35;
    margin-bottom:8px;
    min-height:36px;
}

.file-meta{
    font-size:12px;
    color:#777;
    margin-bottom:4px;
}

.file-status{
    display:inline-block;
    margin-top:8px;
    font-size:11px;
    padding:5px 9px;
    border-radius:20px;
    font-weight:bold;
}

.pendiente{
    background:#fff4d5;
    color:#9a6a00;
}

.aprobada{
    background:#dff7e7;
    color:#087b31;
}

.rechazada{
    background:#fde0e0;
    color:#9e1f1f;
}

.empty{
    background:white;
    padding:45px;
    border-radius:14px;
    color:#777;
    text-align:center;
    box-shadow:0 4px 18px rgba(0,0,0,0.05);
}

/* =========================
   PANEL DERECHO DE CARGA
========================= */
.overlay{
    display:none;
    position:fixed;
    inset:0;
    background:rgba(0,0,0,0.35);
    z-index:90;
}

.overlay.show{
    display:block;
}

.drawer{
    position:fixed;
    top:0;
    right:-470px;
    width:470px;
    height:100vh;
    background:white;
    z-index:100;
    box-shadow:-8px 0 28px rgba(0,0,0,0.25);
    transition:.25s;
    overflow-y:auto;
}

.drawer.open{
    right:0;
}

.drawer-head{
    padding:18px 20px;
    display:flex;
    justify-content:space-between;
    align-items:center;
    border-bottom:1px solid #eee;
}

.drawer-head h2{
    font-size:18px;
    color:#222;
}

.drawer-close{
    border:none;
    background:transparent;
    font-size:26px;
    cursor:pointer;
    color:#555;
}

.drawer-body{
    padding:20px;
}

.upload-zone{
    border:2px dashed #ef5124;
    border-radius:14px;
    padding:28px 15px;
    text-align:center;
    background:#fff6f2;
    color:#ef5124;
    cursor:pointer;
    margin-bottom:20px;
}

.upload-zone strong{
    display:block;
    margin-bottom:8px;
}

.upload-zone small{
    color:#777;
}

.upload-zone input{
    display:none;
}

.file-selected{
    display:none;
    background:#f4f4f4;
    padding:10px;
    border-radius:8px;
    margin-bottom:16px;
    font-size:13px;
    color:#444;
}

.drawer-body label{
    display:block;
    margin-bottom:7px;
    font-size:13px;
    color:#333;
    font-weight:bold;
}

.drawer-body input,
.drawer-body select,
.drawer-body textarea{
    width:100%;
    padding:11px;
    border:1px solid #ddd;
    border-radius:8px;
    margin-bottom:14px;
    font-size:14px;
}

.drawer-body textarea{
    min-height:110px;
    resize:vertical;
}

.form-help{
    font-size:12px;
    color:#777;
    margin-top:-6px;
    margin-bottom:12px;
}

.medios-box{
    border:1px solid #ddd;
    border-radius:10px;
    padding:10px;
    background:#fafafa;
    margin-bottom:14px;
}

.medio-seleccionado{
    background:#e8f5e9;
    border:1px solid #2f9e44;
    color:#1e2942;
    padding:9px;
    border-radius:8px;
    margin-bottom:9px;
    font-size:12px;
    font-weight:bold;
}

.medios-lista{
    max-height:210px;
    overflow:auto;
    border:1px solid #ddd;
    border-radius:8px;
    background:white;
    padding:8px;
    white-space:nowrap;
}

.region-title{
    background:#1e2942;
    color:white;
    padding:7px;
    border-radius:6px;
    font-size:12px;
    font-weight:bold;
}

.provincia-title{
    background:#5a657a;
    color:white;
    padding:6px;
    border-radius:6px;
    margin:6px 0 4px 12px;
    font-size:12px;
    font-weight:bold;
}

.ciudad-title{
    color:#ef5124;
    margin:6px 0 4px 25px;
    font-size:12px;
    font-weight:bold;
}

.medio-item{
    margin-left:38px;
    padding:7px;
    background:#f4f4f4;
    border-radius:6px;
    margin-bottom:4px;
    cursor:pointer;
    min-width:480px;
    font-size:12px;
}

.medio-item:hover{
    background:#ef5124;
    color:white;
}

.btn-save{
    width:100%;
    background:#ef5124;
    border:none;
    color:white;
    padding:13px;
    border-radius:8px;
    font-weight:bold;
    cursor:pointer;
    text-transform:uppercase;
}


/* =========================
   NUEVA CARGA MASIVA
========================= */
.upload-drawer{
    display:flex;
    flex-direction:column;
}

.upload-body{
    min-height:calc(100vh - 65px);
    display:flex;
    flex-direction:column;
}

.upload-main-icon{
    width:74px;
    height:74px;
    border-radius:22px;
    background:#fff0ea;
    color:#ef5124;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:36px;
    font-weight:bold;
    margin:5px auto 14px;
}

.upload-title{
    text-align:center;
    color:#1e2942;
    font-size:20px;
    margin-bottom:8px;
}

.upload-subtitle{
    text-align:center;
    color:#777;
    font-size:13px;
    line-height:1.5;
    margin-bottom:16px;
}

.btn-select-more{
    width:100%;
    background:#ef5124;
    color:white;
    border:none;
    padding:13px;
    border-radius:9px;
    font-weight:bold;
    cursor:pointer;
    margin-bottom:15px;
}

.btn-select-more:hover{
    background:#d9431b;
}

.upload-summary{
    background:#f7f7f7;
    color:#333;
    border-radius:10px;
    padding:12px;
    font-size:13px;
    font-weight:bold;
    margin-bottom:14px;
}

.upload-list{
    flex:1;
    overflow-y:auto;
    padding-right:4px;
    max-height:calc(100vh - 330px);
}

.upload-item{
    border:1px solid #e5e5e5;
    background:white;
    border-radius:12px;
    padding:12px;
    margin-bottom:10px;
    box-shadow:0 2px 8px rgba(0,0,0,0.04);
}

.upload-item.upload-ok{
    border-color:#28a745;
    background:#f4fff7;
}

.upload-item.upload-error{
    border-color:#dc3545;
    background:#fff5f5;
}

.upload-file-top{
    display:flex;
    align-items:center;
    gap:10px;
    margin-bottom:9px;
}

.upload-file-icon{
    width:38px;
    height:38px;
    border-radius:10px;
    background:#fff0ea;
    color:#ef5124;
    display:flex;
    align-items:center;
    justify-content:center;
    font-size:20px;
    flex-shrink:0;
}

.upload-file-info{
    flex:1;
    min-width:0;
}

.upload-file-name{
    font-size:13px;
    font-weight:bold;
    color:#1e2942;
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
}

.upload-file-size{
    font-size:11px;
    color:#777;
    margin-top:3px;
}

.upload-file-status{
    min-width:45px;
    text-align:right;
    font-size:12px;
    font-weight:bold;
    color:#ef5124;
}

.upload-progress-track{
    height:8px;
    background:#eee;
    border-radius:20px;
    overflow:hidden;
    margin-bottom:7px;
}

.upload-progress-bar{
    height:100%;
    background:#ef5124;
    border-radius:20px;
    transition:width .2s ease;
}

.upload-message{
    font-size:11px;
    color:#777;
}

.btn-continue{
    width:100%;
    background:#ef5124;
    color:white;
    border:none;
    padding:15px;
    border-radius:10px;
    font-weight:bold;
    cursor:pointer;
    margin-top:15px;
    text-transform:uppercase;
    font-size:14px;
}

.btn-continue:hover{
    background:#d9431b;
}


/* =========================
   POPUP PREVISUALIZACIÓN DE ARCHIVOS
========================= */
.preview-modal{
    display:none;
    position:fixed;
    inset:0;
    background:rgba(0,0,0,0.78);
    z-index:300;
    padding:28px;
}

.preview-modal.show{
    display:flex;
    align-items:center;
    justify-content:center;
}

.preview-box{
    width:92%;
    max-width:1050px;
    max-height:92vh;
    background:#111827;
    border-radius:16px;
    overflow:hidden;
    box-shadow:0 15px 45px rgba(0,0,0,0.45);
    display:flex;
    flex-direction:column;
}

.preview-head{
    background:#1e2942;
    color:white;
    padding:14px 18px;
    display:flex;
    justify-content:space-between;
    align-items:center;
    gap:15px;
}

.preview-title{
    font-size:15px;
    font-weight:bold;
    overflow:hidden;
    text-overflow:ellipsis;
    white-space:nowrap;
}

.preview-close{
    border:none;
    background:#ef5124;
    color:white;
    width:34px;
    height:34px;
    border-radius:50%;
    cursor:pointer;
    font-size:22px;
    line-height:1;
    display:flex;
    align-items:center;
    justify-content:center;
    flex-shrink:0;
}

.preview-content{
    background:#0b1220;
    min-height:420px;
    max-height:78vh;
    overflow:auto;
    display:flex;
    align-items:center;
    justify-content:center;
    padding:18px;
}

.preview-content img{
    max-width:100%;
    max-height:72vh;
    object-fit:contain;
    border-radius:8px;
}

.preview-content video{
    width:100%;
    max-height:72vh;
    border-radius:8px;
    background:black;
}

.preview-content audio{
    width:90%;
}

.preview-content iframe{
    width:100%;
    height:72vh;
    border:none;
    background:white;
    border-radius:8px;
}

.preview-message{
    color:white;
    text-align:center;
    line-height:1.7;
}

.preview-message a{
    color:white;
    background:#ef5124;
    padding:11px 16px;
    border-radius:8px;
    display:inline-block;
    margin-top:14px;
    text-decoration:none;
    font-weight:bold;
}


/* =========================
   PANEL EDITAR INFORMACIÓN
========================= */
.edit-overlay{
    display:none;
    position:fixed;
    inset:0;
    background:rgba(0,0,0,0.55);
    z-index:350;
}

.edit-overlay.show{
    display:block;
}

.edit-drawer{
    position:fixed;
    top:0;
    right:-460px;
    width:440px;
    height:100vh;
    background:white;
    z-index:360;
    box-shadow:-8px 0 28px rgba(0,0,0,0.25);
    transition:.25s;
    overflow-y:auto;
}

.edit-drawer.open{
    right:0;
}

.edit-head{
    padding:24px 32px 16px;
    border-bottom:1px solid #e3e5ef;
    display:flex;
    justify-content:space-between;
    align-items:flex-start;
    gap:15px;
}

.edit-small-title{
    font-size:11px;
    font-weight:bold;
    color:#9aa0b5;
    text-transform:uppercase;
    margin-bottom:6px;
}

.edit-head h2{
    color:#1e2942;
    font-size:18px;
    line-height:1.3;
}

.edit-close{
    border:none;
    background:transparent;
    color:#1e2942;
    font-size:38px;
    cursor:pointer;
    line-height:1;
}

.edit-body{
    padding:24px 32px;
}

.edit-preview-box{
    margin-bottom:24px;
}

.edit-preview-box audio,
.edit-preview-box video,
.edit-preview-box img{
    width:100%;
    max-height:190px;
    object-fit:contain;
    border-radius:12px;
}

.edit-body label{
    display:block;
    font-size:14px;
    color:#1e2942;
    margin-bottom:8px;
}

.edit-body input,
.edit-body textarea{
    width:100%;
    padding:13px 15px;
    border:1px solid #d9dce8;
    border-radius:7px;
    font-size:14px;
    margin-bottom:18px;
    color:#1e2942;
}

.edit-body textarea{
    min-height:90px;
    resize:vertical;
}

.edit-info-grid{
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:18px;
    margin:12px 0 25px;
    color:#1e2942;
    font-size:13px;
}

.edit-info-grid strong{
    display:block;
    margin-bottom:5px;
}

.btn-edit-save{
    width:100%;
    background:#1e2942;
    color:white;
    border:none;
    padding:16px;
    border-radius:6px;
    font-weight:bold;
    cursor:pointer;
    text-transform:uppercase;
}

.btn-edit-save:hover{
    background:#ef5124;
}


/* =========================
   HERRAMIENTA DE RECORTE DE IMAGEN
========================= */
.crop-screen{
    display:none;
    position:fixed;
    inset:0;
    background:white;
    z-index:500;
}

.crop-screen.show{
    display:flex;
}

.crop-sidebar{
    width:275px;
    background:white;
    border-right:1px solid #dfe2ec;
    padding:20px 22px;
    flex-shrink:0;
}

.crop-sidebar small{
    display:block;
    color:#8a90a3;
    font-size:11px;
    text-transform:uppercase;
    margin-bottom:3px;
}

.crop-sidebar h2{
    color:#1e2942;
    font-size:26px;
    line-height:1.1;
    margin-bottom:28px;
}

.crop-help{
    font-size:13px;
    color:#555;
    line-height:1.5;
    margin-bottom:18px;
}

.crop-btn{
    background:#ef5124;
    color:white;
    border:none;
    padding:15px 22px;
    border-radius:7px;
    font-weight:bold;
    cursor:pointer;
    text-transform:uppercase;
    margin-right:8px;
    margin-bottom:10px;
}

.crop-btn:hover{
    background:#d9431b;
}

.crop-btn.secondary{
    background:#1e2942;
}

.crop-stage-wrap{
    flex:1;
    display:flex;
    flex-direction:column;
    min-width:0;
}

.crop-toolbar{
    height:64px;
    display:flex;
    align-items:center;
    justify-content:space-between;
    padding:0 28px;
    border-bottom:1px solid #e6e8f0;
    color:#1e2942;
    font-weight:bold;
}

.crop-close{
    border:none;
    background:transparent;
    color:#1e2942;
    font-size:34px;
    cursor:pointer;
}

.crop-stage{
    flex:1;
    background-color:#999;
    background-image:
        linear-gradient(45deg, #777 25%, transparent 25%),
        linear-gradient(-45deg, #777 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #777 75%),
        linear-gradient(-45deg, transparent 75%, #777 75%);
    background-size:18px 18px;
    background-position:0 0, 0 9px, 9px -9px, -9px 0px;
    display:flex;
    align-items:center;
    justify-content:center;
    overflow:auto;
    padding:25px;
}

.crop-canvas-box{
    position:relative;
    display:inline-block;
    line-height:0;
    box-shadow:0 8px 25px rgba(0,0,0,0.35);
}

#crop_canvas{
    max-width:100%;
    max-height:calc(100vh - 130px);
    display:block;
    cursor:crosshair;
}

.crop-selection{
    display:none;
    position:absolute;
    border:2px solid #1e90ff;
    background:rgba(30,144,255,0.18);
    box-shadow:0 0 0 9999px rgba(0,0,0,0.42);
    pointer-events:none;
}

.crop-selection::before,
.crop-selection::after{
    content:"";
    position:absolute;
    background:rgba(255,255,255,0.45);
}

.crop-selection::before{
    left:0;
    right:0;
    top:50%;
    height:1px;
}

.crop-selection::after{
    top:0;
    bottom:0;
    left:50%;
    width:1px;
}

.crop-message{
    color:#1e2942;
    font-size:13px;
    margin-top:12px;
    line-height:1.4;
}

@media(max-width:900px){
    .crop-screen.show{
        flex-direction:column;
    }

    .crop-sidebar{
        width:100%;
        border-right:none;
        border-bottom:1px solid #dfe2ec;
    }
}



/* =========================
   PANEL REGISTRAR NOTICIA
========================= */
.news-drawer{
    position:fixed;
    top:0;
    right:-520px;
    width:520px;
    height:100vh;
    background:white;
    z-index:180;
    box-shadow:-8px 0 28px rgba(0,0,0,0.25);
    transition:.25s;
    overflow-y:auto;
}

.news-drawer.open{
    right:0;
}

.news-overlay{
    display:none;
    position:fixed;
    inset:0;
    background:rgba(0,0,0,0.35);
    z-index:170;
}

.news-overlay.show{
    display:block;
}

.news-head{
    padding:20px 24px;
    border-bottom:1px solid #e3e5ef;
    display:flex;
    align-items:flex-start;
    justify-content:space-between;
    gap:15px;
}

.news-small-title{
    font-size:11px;
    font-weight:bold;
    color:#9aa0b5;
    text-transform:uppercase;
    margin-bottom:6px;
}

.news-head h2{
    color:#1e2942;
    font-size:21px;
    line-height:1.25;
}

.news-close{
    border:none;
    background:transparent;
    color:#1e2942;
    font-size:34px;
    cursor:pointer;
    line-height:1;
}

.news-body{
    padding:22px 24px;
}

.news-help{
    background:#fff6f2;
    border:1px solid #ffd7c8;
    color:#6d3a27;
    padding:12px;
    border-radius:10px;
    font-size:13px;
    line-height:1.45;
    margin-bottom:18px;
}

.news-body label{
    display:block;
    font-size:13px;
    color:#1e2942;
    margin-bottom:7px;
    font-weight:bold;
}

.news-body input,
.news-body select,
.news-body textarea{
    width:100%;
    padding:12px;
    border:1px solid #d9dce8;
    border-radius:8px;
    margin-bottom:14px;
    font-size:14px;
    color:#1e2942;
}

.news-body textarea{
    min-height:120px;
    resize:vertical;
}

.news-body .medios-box input{
    margin-bottom:10px;
}

.news-save{
    width:100%;
    background:#ef5124;
    color:white;
    border:none;
    padding:15px;
    border-radius:9px;
    font-weight:bold;
    cursor:pointer;
    text-transform:uppercase;
    margin-top:8px;
}

.news-save:hover{
    background:#d9431b;
}

/* =========================
   SOPORTE
========================= */
.modal{
    display:none;
    position:fixed;
    inset:0;
    background:rgba(0,0,0,0.55);
    z-index:200;
}

.modal-box{
    background:white;
    width:90%;
    max-width:480px;
    margin:8% auto;
    padding:24px;
    border-radius:14px;
    position:relative;
}

.modal-close{
    position:absolute;
    top:10px;
    right:14px;
    font-size:26px;
    cursor:pointer;
}

.modal-box h2{
    color:#1e2942;
    margin-bottom:15px;
    text-align:center;
}

.modal-box textarea{
    width:100%;
    min-height:145px;
    padding:12px;
    border:1px solid #ddd;
    border-radius:8px;
}

.modal-box button{
    width:100%;
    background:#25D366;
    color:white;
    border:none;
    padding:13px;
    border-radius:8px;
    margin-top:12px;
    font-weight:bold;
}

.alert-msg{
    background:#fff3cd;
    color:#856404;
    padding:12px;
    border-radius:8px;
    margin-bottom:15px;
    font-weight:bold;
}

/* =========================
   RESPONSIVE
========================= */
@media(max-width:900px){
    .sidebar{
        width:70px;
    }

    .main{
        margin-left:70px;
        width:calc(100% - 70px);
        padding:18px;
    }

    .workspace{
        grid-template-columns:1fr;
    }

    .filters{
        min-height:auto;
    }

    .drawer{
        width:100%;
        right:-100%;
    }

    .news-drawer{
        width:100%;
        right:-100%;
    }
}

@media(max-width:600px){
    .header{
        flex-direction:column;
        align-items:flex-start;
        gap:12px;
    }

    .files-grid{
        grid-template-columns:1fr;
    }
}
</style>

<script>
const medios = <?php echo json_encode($medios_array, JSON_UNESCAPED_UNICODE); ?>;

let rangoInicio = null;
let rangoFin = null;
let rangoHover = null;
let calendarioAbierto = false;

let fechaSistema = new Date();
let mesActual = fechaSistema.getMonth();
let anioActual = fechaSistema.getFullYear();

function abrirCarga(){
    let input = document.getElementById("input_carga_masiva");
    input.value = "";
    input.click();
}

function abrirPanelCarga(){
    document.getElementById("overlay").classList.add("show");
    document.getElementById("drawerCarga").classList.add("open");
}

function cerrarCarga(){
    document.getElementById("overlay").classList.remove("show");
    document.getElementById("drawerCarga").classList.remove("open");
}

function abrirSoporte(){
    document.getElementById("modalSoporte").style.display = "block";
}

function cerrarSoporte(){
    document.getElementById("modalSoporte").style.display = "none";
}


function abrirNoticias(){
    document.getElementById("newsOverlay").classList.add("show");
    document.getElementById("newsDrawer").classList.add("open");
}

function cerrarNoticias(){
    document.getElementById("newsOverlay").classList.remove("show");
    document.getElementById("newsDrawer").classList.remove("open");
}

function cambiarCategoria(cat, boton){
    document.getElementById("categoria_filtro").value = cat;

    document.querySelectorAll(".filter-list button").forEach(btn => {
        btn.classList.remove("active");
    });

    boton.classList.add("active");

    filtrarArchivos();
}

function abrirCalendario(event){
    if(event){ event.stopPropagation(); }
    calendarioAbierto = true;
    document.getElementById("calendar_popup").classList.add("show");
    document.getElementById("date_display").classList.add("active");
    renderCalendario();
}

function cerrarCalendario(){
    calendarioAbierto = false;
    document.getElementById("calendar_popup").classList.remove("show");
    document.getElementById("date_display").classList.remove("active");
}

function mesAnterior(){
    mesActual--;

    if(mesActual < 0){
        mesActual = 11;
        anioActual--;
    }

    renderCalendario();
}

function mesSiguiente(){
    mesActual++;

    if(mesActual > 11){
        mesActual = 0;
        anioActual++;
    }

    renderCalendario();
}

function cambiarMes(){
    mesActual = parseInt(document.getElementById("select_mes").value);
    renderCalendario();
}

function cambiarAnio(){
    anioActual = parseInt(document.getElementById("select_anio").value);
    renderCalendario();
}

function fechaTexto(fecha){
    return fecha;
}

function renderCalendario(){

    const meses = [
        "Enero","Febrero","Marzo","Abril","Mayo","Junio",
        "Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"
    ];

    let opcionesMes = "";

    for(let i=0; i<12; i++){
        opcionesMes += "<option value='" + i + "' " + (i === mesActual ? "selected" : "") + ">" + meses[i] + "</option>";
    }

    let opcionesAnio = "";

    for(let y=anioActual-5; y<=anioActual+5; y++){
        opcionesAnio += "<option value='" + y + "' " + (y === anioActual ? "selected" : "") + ">" + y + "</option>";
    }

    document.getElementById("calendar_title").innerHTML =
        "<select id='select_mes' onchange='cambiarMes()'>" + opcionesMes + "</select>" +
        "<select id='select_anio' onchange='cambiarAnio()'>" + opcionesAnio + "</select>";

    let contenedor = document.getElementById("calendar_days");
    contenedor.innerHTML = "";

    let primerDia = new Date(anioActual, mesActual, 1).getDay();
    primerDia = primerDia === 0 ? 6 : primerDia - 1;

    let totalDias = new Date(anioActual, mesActual + 1, 0).getDate();

    for(let i=0; i<primerDia; i++){
        contenedor.innerHTML += "<div class='day-cell empty-day'></div>";
    }

    for(let d=1; d<=totalDias; d++){

        let fecha =
            anioActual + "-" +
            String(mesActual + 1).padStart(2, "0") + "-" +
            String(d).padStart(2, "0");

        let clase = "day-cell";

        if(rangoInicio && rangoFin){

            if(fecha === rangoInicio && fecha === rangoFin){
                clase += " same-day";
            } else if(fecha === rangoInicio){
                clase += " selected-start";
            } else if(fecha === rangoFin){
                clase += " selected-end";
            } else if(fecha > rangoInicio && fecha < rangoFin){
                clase += " in-range";
            }

        } else if(rangoInicio && rangoHover){

            let inicioTmp = rangoInicio;
            let finTmp = rangoHover;

            if(finTmp < inicioTmp){
                let temp = inicioTmp;
                inicioTmp = finTmp;
                finTmp = temp;
            }

            if(fecha === rangoInicio){
                clase += " selected-start";
            } else if(fecha > inicioTmp && fecha <= finTmp){
                clase += " preview-range";
            }

        } else if(rangoInicio && fecha === rangoInicio){
            clase += " selected-start";
        }

        contenedor.innerHTML +=
            "<div class='" + clase + "' onmousedown=\"event.stopPropagation(); seleccionarFechaRango('" + fecha + "'); return false;\" onmouseover=\"previsualizarRango('" + fecha + "')\">" +
                d +
            "</div>";
    }
}

function previsualizarRango(fecha){

    if(rangoInicio && !rangoFin){

        if(rangoHover === fecha){
            return;
        }

        rangoHover = fecha;
        renderCalendario();
    }
}

function seleccionarFechaRango(fecha){

    if(!rangoInicio || (rangoInicio && rangoFin)){

        rangoInicio = fecha;
        rangoFin = null;
        rangoHover = null;

        document.getElementById("date_text").innerHTML = "<em>" + fecha + "</em>";
        document.getElementById("btn_aplicar_fecha").classList.add("active");
        document.getElementById("btn_aplicar_fecha").disabled = false;

        renderCalendario();
        return;
    }

    if(rangoInicio && !rangoFin){

        rangoFin = fecha;

        if(rangoFin < rangoInicio){
            let temp = rangoInicio;
            rangoInicio = rangoFin;
            rangoFin = temp;
        }

        if(rangoInicio === rangoFin){
            document.getElementById("date_text").innerHTML = "<em>" + rangoInicio + "</em>";
        } else {
            document.getElementById("date_text").innerHTML = "<em>" + rangoInicio + " al " + rangoFin + "</em>";
        }

        document.getElementById("btn_aplicar_fecha").classList.add("active");
        document.getElementById("btn_aplicar_fecha").disabled = false;

        renderCalendario();

        setTimeout(function(){
            cerrarCalendario();
            aplicarFiltroFechas();
        }, 180);
    }
}

function aplicarFiltroFechas(){

    if(!rangoInicio){
        return;
    }

    if(!rangoFin){
        rangoFin = rangoInicio;
    }

    filtrarArchivos();
}

function filtrarArchivos(){
    let categoria = document.getElementById("categoria_filtro").value;
    let cards = document.querySelectorAll(".file-card");

    cards.forEach(card => {

        let catCard = card.dataset.categoria;
        let fechaCard = card.dataset.fecha;

        let mostrar = true;

        if(categoria !== "" && categoria !== catCard){
            mostrar = false;
        }

        if(rangoInicio && rangoFin){

            if(fechaCard < rangoInicio || fechaCard > rangoFin){
                mostrar = false;
            }
        }

        card.style.display = mostrar ? "block" : "none";
    });
}

let totalArchivosSeleccionados = 0;
let totalArchivosTerminados = 0;

function prepararCargaMasiva(input){

    let archivosOriginales = Array.from(input.files);

    if(archivosOriginales.length === 0){
        return;
    }

    abrirPanelCarga();

    document.getElementById("upload_list").innerHTML = "";
    document.getElementById("btn_continuar_carga").style.display = "none";

    let archivos = [];
    let firmas = new Set();
    let duplicadosSeleccion = 0;

    archivosOriginales.forEach(archivo => {
        let firma = archivo.name.toLowerCase() + "__" + archivo.size;

        if(firmas.has(firma)){
            duplicadosSeleccion++;
        }else{
            firmas.add(firma);
            archivos.push(archivo);
        }
    });

    if(archivos.length === 0){
        totalArchivosSeleccionados = 0;
        totalArchivosTerminados = 0;
        document.getElementById("upload_summary").innerHTML = "Todos los archivos seleccionados estaban repetidos.";
        document.getElementById("btn_continuar_carga").style.display = "block";
        return;
    }

    totalArchivosSeleccionados = archivos.length;
    totalArchivosTerminados = 0;

    if(duplicadosSeleccion > 0){
        document.getElementById("upload_summary").innerHTML =
            "Preparando " + archivos.length + " archivo(s). Repetidos en la selección omitidos: " + duplicadosSeleccion + ".";
    }else{
        document.getElementById("upload_summary").innerHTML = "Preparando " + archivos.length + " archivo(s)...";
    }

    archivos.forEach((archivo, index) => {
        crearFilaCarga(archivo, index);
        subirArchivoMasivo(archivo, index);
    });
}

function crearFilaCarga(archivo, index){

    let lista = document.getElementById("upload_list");

    let item = document.createElement("div");
    item.className = "upload-item";
    item.id = "upload_item_" + index;

    item.innerHTML = `
        <div class="upload-file-top">
            <div class="upload-file-icon">${obtenerIconoArchivo(archivo.name)}</div>
            <div class="upload-file-info">
                <div class="upload-file-name">${escaparTexto(archivo.name)}</div>
                <div class="upload-file-size">${formatearPeso(archivo.size)}</div>
            </div>
            <div class="upload-file-status" id="upload_status_${index}">0%</div>
        </div>
        <div class="upload-progress-track">
            <div class="upload-progress-bar" id="upload_bar_${index}" style="width:0%;"></div>
        </div>
        <div class="upload-message" id="upload_msg_${index}">Esperando carga...</div>
    `;

    lista.appendChild(item);
}

function subirArchivoMasivo(archivo, index){

    let formData = new FormData();
    formData.append("ajax_upload_file", "1");
    formData.append("archivo", archivo);

    let xhr = new XMLHttpRequest();
    xhr.open("POST", "dashboard_editor.php", true);

    xhr.upload.onprogress = function(e){
        if(e.lengthComputable){
            let porcentaje = Math.round((e.loaded / e.total) * 100);
            document.getElementById("upload_bar_" + index).style.width = porcentaje + "%";
            document.getElementById("upload_status_" + index).innerHTML = porcentaje + "%";
            document.getElementById("upload_msg_" + index).innerHTML = "Cargando...";
        }
    };

    xhr.onload = function(){

        let ok = false;
        let mensaje = "Archivo cargado.";

        try{
            let respuesta = JSON.parse(xhr.responseText);
            ok = respuesta.ok === true;
            mensaje = respuesta.mensaje || mensaje;
        }catch(e){
            ok = false;
            mensaje = "Respuesta no válida del servidor.";
        }

        if(xhr.status === 200 && ok){
            document.getElementById("upload_bar_" + index).style.width = "100%";
            document.getElementById("upload_status_" + index).innerHTML = "✓";
            document.getElementById("upload_msg_" + index).innerHTML = "Carga completada";
            document.getElementById("upload_item_" + index).classList.add("upload-ok");
        }else{
            document.getElementById("upload_status_" + index).innerHTML = "Error";
            document.getElementById("upload_msg_" + index).innerHTML = mensaje;
            document.getElementById("upload_item_" + index).classList.add("upload-error");
        }

        terminarCargaArchivo();
    };

    xhr.onerror = function(){
        document.getElementById("upload_status_" + index).innerHTML = "Error";
        document.getElementById("upload_msg_" + index).innerHTML = "No se pudo conectar con el servidor.";
        document.getElementById("upload_item_" + index).classList.add("upload-error");
        terminarCargaArchivo();
    };

    xhr.send(formData);
}

function terminarCargaArchivo(){

    totalArchivosTerminados++;

    document.getElementById("upload_summary").innerHTML =
        "Archivos procesados: " + totalArchivosTerminados + " de " + totalArchivosSeleccionados;

    if(totalArchivosTerminados >= totalArchivosSeleccionados){
        document.getElementById("upload_summary").innerHTML = "Carga finalizada.";
        document.getElementById("btn_continuar_carga").style.display = "block";
    }
}

function continuarDespuesDeCarga(){
    window.location.href = "dashboard_editor.php";
}

function obtenerIconoArchivo(nombre){
    let ext = nombre.split('.').pop().toLowerCase();

    if(["jpg","jpeg","png","gif","webp"].includes(ext)){
        return "🖼";
    }

    if(["mp4","webm","mov","avi","mkv"].includes(ext)){
        return "🎬";
    }

    if(["mp3","wav","aac","ogg","m4a"].includes(ext)){
        return "🎧";
    }

    if(["pdf"].includes(ext)){
        return "📕";
    }

    return "📄";
}

function formatearPeso(bytes){
    if(bytes === 0){ return "0 B"; }

    let k = 1024;
    let sizes = ["B","KB","MB","GB","TB"];
    let i = Math.floor(Math.log(bytes) / Math.log(k));

    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
}

function escaparTexto(texto){
    return texto
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
}

function limpiarFiltros(){

    document.getElementById("categoria_filtro").value = "";

    document.querySelectorAll(".filter-list button").forEach((btn, index) => {
        btn.classList.remove("active");
        if(index === 0){
            btn.classList.add("active");
        }
    });

    rangoInicio = null;
    rangoFin = null;
    rangoHover = null;

    let dateText = document.getElementById("date_text");
    if(dateText){
        dateText.innerHTML = "<em>Seleccionar fecha</em>";
    }

    let btnFecha = document.getElementById("btn_aplicar_fecha");
    if(btnFecha){
        btnFecha.classList.remove("active");
        btnFecha.disabled = true;
    }

    cerrarCalendario();

    document.querySelectorAll(".file-card").forEach(card => {
        card.style.display = "block";
    });
}

function toggleMenu(id){
    document.querySelectorAll(".file-dropdown").forEach(menu => {
        if(menu.id !== id){
            menu.style.display = "none";
        }
    });

    let menu = document.getElementById(id);

    if(menu.style.display === "block"){
        menu.style.display = "none";
    }else{
        menu.style.display = "block";
    }
}

function filtrarMedios(){

    let tipo = document.getElementById("tipo_medio").value;
    let busqueda = document.getElementById("buscar_medio").value.toLowerCase();
    let lista = document.getElementById("lista_medios");

    document.getElementById("subtipo_medio").value = "";
    document.getElementById("medio_id").value = "";
    document.getElementById("medio_seleccionado").innerHTML = "Ningún medio seleccionado";

    lista.innerHTML = "";

    if(tipo === ""){
        lista.innerHTML = "<p>Primero selecciona un tipo de medio.</p>";
        return;
    }

    let filtrados = medios.filter(m =>
        m.tipo_medio === tipo &&
        (
            m.region.toLowerCase().includes(busqueda) ||
            m.provincia.toLowerCase().includes(busqueda) ||
            m.ciudad.toLowerCase().includes(busqueda) ||
            m.nombre_medio.toLowerCase().includes(busqueda)
        )
    );

    if(filtrados.length === 0){
        lista.innerHTML = "<p>No se encontraron medios.</p>";
        return;
    }

    let html = "";
    let regionActual = "";
    let provinciaActual = "";
    let ciudadActual = "";

    filtrados.forEach(m => {

        if(m.region !== regionActual){
            regionActual = m.region;
            provinciaActual = "";
            ciudadActual = "";
            html += "<div class='region-title'>" + m.region + "</div>";
        }

        if(m.provincia !== provinciaActual){
            provinciaActual = m.provincia;
            ciudadActual = "";
            html += "<div class='provincia-title'>" + m.provincia + "</div>";
        }

        if(m.ciudad !== ciudadActual){
            ciudadActual = m.ciudad;
            html += "<div class='ciudad-title'>" + m.ciudad + "</div>";
        }

        const texto =
            m.region + " / " +
            m.provincia + " / " +
            m.ciudad + " / " +
            m.nombre_medio;

        html += "<div class='medio-item' onclick=\"seleccionarMedio(" + m.id + ", '" + texto.replace(/'/g, "\\'") + "')\">" +
                m.nombre_medio +
                "</div>";
    });

    lista.innerHTML = html;
}

function seleccionarMedio(id, texto){
    document.getElementById("medio_id").value = id;
    document.getElementById("subtipo_medio").value = texto;
    document.getElementById("medio_seleccionado").innerHTML = "Medio seleccionado: " + texto;
}


function abrirPreviewArchivo(src, categoria, titulo, ext){

    if(!src){
        return;
    }

    let modal = document.getElementById("previewModal");
    let title = document.getElementById("previewTitle");
    let content = document.getElementById("previewContent");

    title.innerHTML = escaparTexto(titulo || "Archivo");
    content.innerHTML = "";

    let extension = (ext || "").toLowerCase();

    if(categoria === "imagen"){
        content.innerHTML = "<img src='" + src + "' alt='Vista previa'>";
    }else if(categoria === "video"){
        content.innerHTML = "<video controls autoplay><source src='" + src + "'></video>";
    }else if(categoria === "audio"){
        content.innerHTML = "<audio controls autoplay><source src='" + src + "'></audio>";
    }else if(extension === "pdf"){
        content.innerHTML = "<iframe src='" + src + "'></iframe>";
    }else{
        content.innerHTML =
            "<div class='preview-message'>" +
                "<h3>Vista previa no disponible para este tipo de archivo</h3>" +
                "<p>Puedes abrirlo o descargarlo en una nueva pestaña.</p>" +
                "<a href='" + src + "' target='_blank'>ABRIR ARCHIVO</a>" +
            "</div>";
    }

    modal.classList.add("show");
}

function cerrarPreviewArchivo(){

    let modal = document.getElementById("previewModal");
    let content = document.getElementById("previewContent");

    content.innerHTML = "";
    modal.classList.remove("show");
}


function actualizarBotonesSeleccion(){

    let seleccionados = document.querySelectorAll(".file-check:checked");
    let btnDescargar = document.getElementById("btn_descargar_seleccionados");
    let btnEliminar = document.getElementById("btn_eliminar_seleccionados");

    if(seleccionados.length > 0){
        btnDescargar.disabled = false;
        btnEliminar.disabled = false;
        btnDescargar.classList.add("active");
        btnEliminar.classList.add("active");
    }else{
        btnDescargar.disabled = true;
        btnEliminar.disabled = true;
        btnDescargar.classList.remove("active");
        btnEliminar.classList.remove("active");
    }
}

function obtenerSeleccionados(){
    return Array.from(document.querySelectorAll(".file-check:checked"));
}

function descargarSeleccionados(){

    let seleccionados = obtenerSeleccionados();

    seleccionados.forEach((check, index) => {
        let url = check.dataset.url;

        if(url){
            setTimeout(() => {
                let a = document.createElement("a");
                a.href = url;
                a.download = "";
                a.target = "_blank";
                document.body.appendChild(a);
                a.click();
                document.body.removeChild(a);
            }, index * 250);
        }
    });
}

function eliminarSeleccionados(){

    let seleccionados = obtenerSeleccionados();

    if(seleccionados.length === 0){
        return;
    }

    let ids = seleccionados.map(check => check.value).join(",");
    let formData = new FormData();
    formData.append("ajax_bulk_delete", "1");
    formData.append("ids", ids);

    fetch("dashboard_editor.php", {
        method:"POST",
        body:formData
    })
    .then(response => response.json())
    .then(data => {
        if(data.ok){
            seleccionados.forEach(check => {
                let card = document.getElementById("file_card_" + check.value);
                if(card){ card.remove(); }
            });
            actualizarBotonesSeleccion();
        }else{
            alert(data.mensaje || "No se pudieron eliminar los archivos.");
        }
    })
    .catch(() => {
        alert("No se pudo conectar con el servidor.");
    });
}

function eliminarArchivoIndividual(id){

    let formData = new FormData();
    formData.append("ajax_delete_file", "1");
    formData.append("id", id);

    fetch("dashboard_editor.php", {
        method:"POST",
        body:formData
    })
    .then(response => response.json())
    .then(data => {
        if(data.ok){
            let card = document.getElementById("file_card_" + id);
            if(card){ card.remove(); }
            actualizarBotonesSeleccion();
        }else{
            alert(data.mensaje || "No se pudo eliminar el archivo.");
        }
    })
    .catch(() => {
        alert("No se pudo conectar con el servidor.");
    });
}

function abrirEditarArchivo(id, titulo, descripcion, fecha, src, categoria, ext){

    document.getElementById("edit_id").value = id;
    document.getElementById("edit_titulo").value = decodificarHtml(titulo || "");
    document.getElementById("edit_descripcion").value = decodificarHtml(descripcion || "");
    document.getElementById("edit_fecha").value = fecha || "";
    document.getElementById("editTituloCabecera").innerHTML = escaparTexto(decodificarHtml(titulo || "Archivo"));

    let campoDuracion = document.getElementById("edit_duracion");
    let campoFechaRegistro = document.getElementById("edit_fecha_registro");

    if(campoDuracion){
        campoDuracion.innerHTML = "--";
    }

    if(campoFechaRegistro){
        campoFechaRegistro.innerHTML = formatearFechaVista(fecha || "");
    }

    let preview = document.getElementById("edit_preview");
    preview.innerHTML = "";

    if(src){
        if(categoria === "imagen"){
            preview.innerHTML = "<img src='" + src + "' alt='Vista previa'>";
        }else if(categoria === "video"){
            preview.innerHTML = "<video id='edit_media_player' controls><source src='" + src + "'></video>";
        }else if(categoria === "audio"){
            preview.innerHTML = "<audio id='edit_media_player' controls><source src='" + src + "'></audio>";
        }else if((ext || '').toLowerCase() === "pdf"){
            preview.innerHTML = "<iframe src='" + src + "' style='width:100%; height:220px; border:none; border-radius:10px; background:white;'></iframe>";
        }else{
            preview.innerHTML = "<div style='font-size:13px; color:#777; padding:12px; background:#f7f7f7; border-radius:10px;'>Vista previa no disponible para este tipo de archivo.</div>";
        }
    }

    let mediaPlayer = document.getElementById("edit_media_player");

    if(mediaPlayer && campoDuracion){
        mediaPlayer.onloadedmetadata = function(){
            campoDuracion.innerHTML = convertirSegundosDuracion(mediaPlayer.duration);
        };
    }

    document.getElementById("editOverlay").classList.add("show");
    document.getElementById("editDrawer").classList.add("open");
}

function cerrarEditarArchivo(){
    document.getElementById("editOverlay").classList.remove("show");
    document.getElementById("editDrawer").classList.remove("open");
}

function guardarEditarArchivo(){

    let id = document.getElementById("edit_id").value;
    let titulo = document.getElementById("edit_titulo").value;
    let descripcion = document.getElementById("edit_descripcion").value;
    let fecha = document.getElementById("edit_fecha").value;

    let formData = new FormData();
    formData.append("ajax_update_file", "1");
    formData.append("id", id);
    formData.append("titulo", titulo);
    formData.append("descripcion", descripcion);
    formData.append("fecha_nota", fecha);

    fetch("dashboard_editor.php", {
        method:"POST",
        body:formData
    })
    .then(response => response.json())
    .then(data => {
        if(data.ok){
            window.location.href = "dashboard_editor.php";
        }else{
            alert(data.mensaje || "No se pudo guardar la información.");
        }
    })
    .catch(() => {
        alert("No se pudo conectar con el servidor.");
    });
}

function convertirSegundosDuracion(segundos){

    if(!segundos || isNaN(segundos)){
        return "--";
    }

    segundos = Math.floor(segundos);

    let horas = Math.floor(segundos / 3600);
    let minutos = Math.floor((segundos % 3600) / 60);
    let seg = segundos % 60;

    if(horas > 0){
        return String(horas).padStart(2, "0") + ":" + String(minutos).padStart(2, "0") + ":" + String(seg).padStart(2, "0");
    }

    return String(minutos).padStart(2, "0") + ":" + String(seg).padStart(2, "0");
}

function formatearFechaVista(fecha){

    if(!fecha){
        return "--";
    }

    let partes = fecha.split("-");

    if(partes.length === 3){
        return partes[2] + "/" + partes[1] + "/" + partes[0];
    }

    return fecha;
}


let cropImage = null;
let cropImageId = 0;
let cropImageTitle = "";
let cropStartX = 0;
let cropStartY = 0;
let cropEndX = 0;
let cropEndY = 0;
let cropDragging = false;
let cropScaleX = 1;
let cropScaleY = 1;

function abrirRecorteImagen(id, titulo, src){

    if(!src){
        alert("No se encontró la imagen para recortar.");
        return;
    }

    cropImageId = id;
    cropImageTitle = decodificarHtml(titulo || "Imagen");

    document.getElementById("crop_titulo").innerHTML = escaparTexto(cropImageTitle);
    document.getElementById("crop_message").innerHTML = "Cargando imagen...";
    document.getElementById("crop_selection").style.display = "none";

    let pantalla = document.getElementById("cropScreen");
    pantalla.classList.add("show");

    let canvas = document.getElementById("crop_canvas");
    let ctx = canvas.getContext("2d");

    cropImage = new Image();
    cropImage.crossOrigin = "anonymous";

    cropImage.onload = function(){

        canvas.width = cropImage.naturalWidth;
        canvas.height = cropImage.naturalHeight;

        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(cropImage, 0, 0);

        actualizarEscalaCrop();
        document.getElementById("crop_message").innerHTML = "Arrastra con el mouse sobre la imagen para seleccionar el área que deseas recortar.";
    };

    cropImage.onerror = function(){
        document.getElementById("crop_message").innerHTML = "No se pudo cargar la imagen para recortar.";
    };

    cropImage.src = src + (src.includes("?") ? "&" : "?") + "t=" + new Date().getTime();
}

function cerrarRecorteImagen(){
    document.getElementById("cropScreen").classList.remove("show");
    document.getElementById("crop_selection").style.display = "none";
    cropImage = null;
    cropImageId = 0;
}

function actualizarEscalaCrop(){
    let canvas = document.getElementById("crop_canvas");
    let rect = canvas.getBoundingClientRect();

    cropScaleX = canvas.width / rect.width;
    cropScaleY = canvas.height / rect.height;
}

function obtenerPosicionCrop(event){
    let canvas = document.getElementById("crop_canvas");
    let rect = canvas.getBoundingClientRect();

    return {
        x: Math.max(0, Math.min(event.clientX - rect.left, rect.width)),
        y: Math.max(0, Math.min(event.clientY - rect.top, rect.height))
    };
}

function iniciarSeleccionCrop(event){
    if(!cropImage){ return; }

    actualizarEscalaCrop();

    let pos = obtenerPosicionCrop(event);
    cropStartX = pos.x;
    cropStartY = pos.y;
    cropEndX = pos.x;
    cropEndY = pos.y;
    cropDragging = true;

    dibujarSeleccionCrop();
}

function moverSeleccionCrop(event){
    if(!cropDragging){ return; }

    let pos = obtenerPosicionCrop(event);
    cropEndX = pos.x;
    cropEndY = pos.y;

    dibujarSeleccionCrop();
}

function finalizarSeleccionCrop(event){
    if(!cropDragging){ return; }

    let pos = obtenerPosicionCrop(event);
    cropEndX = pos.x;
    cropEndY = pos.y;
    cropDragging = false;

    dibujarSeleccionCrop();
}

function dibujarSeleccionCrop(){
    let seleccion = document.getElementById("crop_selection");
    let canvas = document.getElementById("crop_canvas");
    let canvasRect = canvas.getBoundingClientRect();
    let boxRect = document.getElementById("crop_canvas_box").getBoundingClientRect();

    let x = Math.min(cropStartX, cropEndX);
    let y = Math.min(cropStartY, cropEndY);
    let w = Math.abs(cropEndX - cropStartX);
    let h = Math.abs(cropEndY - cropStartY);

    seleccion.style.left = (canvasRect.left - boxRect.left + x) + "px";
    seleccion.style.top = (canvasRect.top - boxRect.top + y) + "px";
    seleccion.style.width = w + "px";
    seleccion.style.height = h + "px";
    seleccion.style.display = (w > 3 && h > 3) ? "block" : "none";
}

function guardarRecorteImagen(){

    if(!cropImage || cropImageId <= 0){
        alert("No hay imagen cargada para recortar.");
        return;
    }

    actualizarEscalaCrop();

    let x = Math.min(cropStartX, cropEndX) * cropScaleX;
    let y = Math.min(cropStartY, cropEndY) * cropScaleY;
    let w = Math.abs(cropEndX - cropStartX) * cropScaleX;
    let h = Math.abs(cropEndY - cropStartY) * cropScaleY;

    x = Math.round(x);
    y = Math.round(y);
    w = Math.round(w);
    h = Math.round(h);

    if(w < 10 || h < 10){
        alert("Selecciona un área más grande para recortar.");
        return;
    }

    let canvasRecorte = document.createElement("canvas");
    canvasRecorte.width = w;
    canvasRecorte.height = h;

    let ctx = canvasRecorte.getContext("2d");
    ctx.drawImage(cropImage, x, y, w, h, 0, 0, w, h);

    let imagenFinal = canvasRecorte.toDataURL("image/png");

    let formData = new FormData();
    formData.append("ajax_save_crop", "1");
    formData.append("id", cropImageId);
    formData.append("imagen", imagenFinal);

    document.getElementById("crop_message").innerHTML = "Guardando recorte...";

    fetch("dashboard_editor.php", {
        method:"POST",
        body:formData
    })
    .then(response => response.json())
    .then(data => {
        if(data.ok){
            window.location.href = "dashboard_editor.php";
        }else{
            alert(data.mensaje || "No se pudo guardar el recorte.");
            document.getElementById("crop_message").innerHTML = "No se pudo guardar el recorte.";
        }
    })
    .catch(() => {
        alert("No se pudo conectar con el servidor.");
        document.getElementById("crop_message").innerHTML = "Error de conexión.";
    });
}

function decodificarHtml(texto){
    let textarea = document.createElement("textarea");
    textarea.innerHTML = texto;
    return textarea.value;
}

window.onclick = function(event){

    if(event.target == document.getElementById("modalSoporte")){
        cerrarSoporte();
    }

    if(event.target == document.getElementById("newsOverlay")){
        cerrarNoticias();
    }

    if(!event.target.classList.contains("file-menu-btn")){
        document.querySelectorAll(".file-dropdown").forEach(menu => {
            menu.style.display = "none";
        });
    }

    let calendario = document.getElementById("calendar_popup");
    let selector = document.getElementById("date_display");

    if(
        calendario &&
        selector &&
        calendarioAbierto &&
        !calendario.contains(event.target) &&
        !selector.contains(event.target)
    ){
        cerrarCalendario();
    }
}
</script>
</head>

<body>

<div class="app">

    <aside class="sidebar">

        <div class="logo">
            <div class="logo-text">cruz<br>app</div>
        </div>

        <a class="nav-icon active" href="dashboard_editor.php">
            <span>📁</span>
            Archivos
        </a>

        <a class="nav-icon" href="noticias.php">
            <span>📰</span>
            Noticias
        </a>

        <a class="nav-icon" onclick="abrirSoporte()">
            <span>🛠</span>
            Soporte
        </a>

        <div class="sidebar-bottom">
            <a class="nav-icon" href="logout.php">
                <span>↩</span>
                Salir
            </a>
        </div>

    </aside>

    <main class="main">

        <div class="header">
            <h1>Archivos</h1>

            <div class="header-actions">
                <button id="btn_descargar_seleccionados" class="btn-mass-action download" onclick="descargarSeleccionados()" disabled>
                    DESCARGAR
                </button>

                <button id="btn_eliminar_seleccionados" class="btn-mass-action delete" onclick="eliminarSeleccionados()" disabled>
                    ELIMINAR
                </button>

                <button class="btn-upload" onclick="abrirCarga()">
                    CARGAR ARCHIVOS
                </button>
            </div>
        </div>

        <?php if($mensaje != ""){ ?>
            <div class="alert-msg">
                <?php echo htmlspecialchars($mensaje, ENT_QUOTES, 'UTF-8'); ?>
            </div>
        <?php } ?>

        <div class="workspace">

            <aside class="filters">

                <input type="hidden" id="categoria_filtro" value="">

                <div class="filter-list">
                    <button class="active" onclick="cambiarCategoria('', this)">
                        Todos los archivos (<?php echo $total_archivos; ?>)
                    </button>

                    <button onclick="cambiarCategoria('audio', this)">
                        Audio MP3 (<?php echo $total_audio; ?>)
                    </button>

                    <button onclick="cambiarCategoria('imagen', this)">
                        Imagen (<?php echo $total_imagen; ?>)
                    </button>

                    <button onclick="cambiarCategoria('video', this)">
                        Video MP4 (<?php echo $total_video; ?>)
                    </button>
                </div>

                <div class="filter-section">
                    <h3>Filtrar por fechas</h3>

                    <div class="custom-date-box">

                        <div id="date_display" class="date-display" onclick="abrirCalendario(event)">
                            <span class="calendar-icon">📅</span>
                            <span id="date_text"><em>Seleccionar fecha</em></span>
                        </div>

                        <div id="calendar_popup" class="calendar-popup" onclick="event.stopPropagation()">

                            <div class="calendar-head">
                                <button type="button" onclick="event.stopPropagation(); mesAnterior()">‹</button>

                                <div id="calendar_title" class="calendar-title"></div>

                                <button type="button" onclick="event.stopPropagation(); mesSiguiente()">›</button>
                            </div>

                            <div class="week-days">
                                <div>Lun</div>
                                <div>Mar</div>
                                <div>Mié</div>
                                <div>Jue</div>
                                <div>Vie</div>
                                <div>Sáb</div>
                                <div>Dom</div>
                            </div>

                            <div id="calendar_days" class="days-grid"></div>

                        </div>

                    </div>

                    <button id="btn_aplicar_fecha" class="btn-filter" type="button" onclick="aplicarFiltroFechas()" disabled>
                        APLICAR FILTROS
                    </button>

                    <button class="btn-clear-filter" type="button" onclick="limpiarFiltros()">
                        LIMPIAR FILTROS
                    </button>
                </div>

                <div class="user-block">
                    <strong><?php echo $nombre; ?></strong>
                    Editor conectado
                </div>

            </aside>

            <section>

                <?php if(count($archivos) > 0){ ?>

                    <div class="files-grid">

                        <?php foreach($archivos as $archivo){ ?>

                            <?php
                                $id = intval($archivo['id']);
                                $titulo = htmlspecialchars($archivo['titulo'], ENT_QUOTES, 'UTF-8');
                                $fecha = htmlspecialchars($archivo['fecha_nota'], ENT_QUOTES, 'UTF-8');
                                $medio = htmlspecialchars($archivo['subtipo_medio'], ENT_QUOTES, 'UTF-8');
                                $estado = strtolower($archivo['estado']);
                                $categoria = $archivo['categoria_archivo'];
                                $icono = $archivo['icono_archivo'];
                                $thumb = $archivo['thumb_archivo'];
                                $archivo_url = "";
                                $extension_archivo = "";

                                if(!empty($archivo['archivo'])){
                                    $nombre_archivo_seguro = basename($archivo['archivo']);
                                    $archivo_url = "uploads/" . $nombre_archivo_seguro;
                                    $extension_archivo = strtolower(pathinfo($nombre_archivo_seguro, PATHINFO_EXTENSION));
                                }

                                if($estado != "aprobada" && $estado != "rechazada"){
                                    $estado = "pendiente";
                                }
                            ?>

                            <article
                                id="file_card_<?php echo $id; ?>"
                                class="file-card"
                                data-id="<?php echo $id; ?>"
                                data-url="<?php echo htmlspecialchars($archivo_url, ENT_QUOTES, 'UTF-8'); ?>"
                                data-categoria="<?php echo $categoria; ?>"
                                data-fecha="<?php echo $fecha; ?>"
                                onclick="abrirPreviewArchivo('<?php echo htmlspecialchars($archivo_url, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($categoria, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($titulo, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($extension_archivo, ENT_QUOTES, 'UTF-8'); ?>')"
                            >

                                <input
                                    type="checkbox"
                                    class="file-check"
                                    value="<?php echo $id; ?>"
                                    data-url="<?php echo htmlspecialchars($archivo_url, ENT_QUOTES, 'UTF-8'); ?>"
                                    onclick="event.stopPropagation(); actualizarBotonesSeleccion()"
                                >

                                <button class="file-menu-btn" onclick="event.stopPropagation(); toggleMenu('menu_<?php echo $id; ?>')">
                                    ⋮
                                </button>

                                <div id="menu_<?php echo $id; ?>" class="file-dropdown" onclick="event.stopPropagation()">
                                    <button type="button" onclick="abrirEditarArchivo(<?php echo $id; ?>, '<?php echo htmlspecialchars($titulo, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($archivo['descripcion'] ?? '', ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($fecha, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($archivo_url, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($categoria, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($extension_archivo, ENT_QUOTES, 'UTF-8'); ?>')">
                                        Editar información
                                    </button>

                                    <?php if($categoria == "imagen") { ?>
                                        <button type="button" onclick="abrirRecorteImagen(<?php echo $id; ?>, '<?php echo htmlspecialchars($titulo, ENT_QUOTES, 'UTF-8'); ?>', '<?php echo htmlspecialchars($archivo_url, ENT_QUOTES, 'UTF-8'); ?>')">
                                            Generar recorte
                                        </button>
                                    <?php } ?>

                                    <button type="button" onclick="eliminarArchivoIndividual(<?php echo $id; ?>)">
                                        Eliminar archivo
                                    </button>

                                    <a href="<?php echo htmlspecialchars($archivo_url, ENT_QUOTES, 'UTF-8'); ?>" target="_blank">
                                        Abrir enlace externo
                                    </a>
                                </div>

                                <div class="file-preview">
                                    <?php if($categoria == "imagen" && $thumb != ""){ ?>

                                        <img src="<?php echo htmlspecialchars($thumb, ENT_QUOTES, 'UTF-8'); ?>" alt="archivo">

                                    <?php } elseif($categoria == "video" && $thumb != ""){ ?>

                                        <video
                                            src="<?php echo htmlspecialchars($thumb, ENT_QUOTES, 'UTF-8'); ?>#t=0.1"
                                            muted
                                            preload="metadata"
                                            playsinline
                                        ></video>

                                    <?php } else { ?>

                                        <?php echo $icono; ?>

                                    <?php } ?>
                                </div>

                                <div class="file-body">

                                    <div class="file-title">
                                        <?php echo $titulo; ?>
                                    </div>

                                    <div class="file-meta">
                                        <strong>Fecha:</strong> <?php echo $fecha; ?>
                                    </div>

                                    <div class="file-meta">
                                        <strong>Medio:</strong> <?php echo ($medio != "" ? $medio : "-"); ?>
                                    </div>
</div>

                            </article>

                        <?php } ?>

                    </div>

                <?php } else { ?>

                    <div class="empty">
                        No tienes archivos cargados.
                    </div>

                <?php } ?>

            </section>

        </div>

    </main>

</div>


<div id="newsOverlay" class="news-overlay" onclick="cerrarNoticias()"></div>

<div id="newsDrawer" class="news-drawer">

    <div class="news-head">
        <div>
            <div class="news-small-title">REGISTRO EDITORIAL</div>
            <h2>Registrar noticia</h2>
        </div>
        <button type="button" class="news-close" onclick="cerrarNoticias()">×</button>
    </div>

    <div class="news-body">

        <div class="news-help">
            Registra aquí la noticia que será enviada para revisión. Los archivos se siguen cargando desde el botón superior <strong>CARGAR ARCHIVOS</strong>.
        </div>

        <form method="POST">

            <label>Título <strong>*</strong></label>
            <input type="text" name="titulo" required>

            <label>Descripción / Contenido <strong>*</strong></label>
            <textarea name="descripcion" placeholder="Escribe aquí la información de la noticia..." required></textarea>

            <label>Fecha de Publicación <strong>*</strong></label>
            <input type="date" name="fecha_nota" required>

            <label>Tipo de Medio <strong>*</strong></label>
            <select name="tipo_medio" id="tipo_medio" onchange="filtrarMedios()" required>
                <option value="">Seleccione</option>
                <option value="TV">TV</option>
                <option value="Radio">Radio</option>
                <option value="Diario">Diario</option>
                <option value="Redes Sociales">Redes Sociales</option>
                <option value="Web">Web</option>
                <option value="Creador de contenido">Creador de contenido</option>
            </select>

            <label>Medio / Ruta del Medio <strong>*</strong></label>
            <div class="medios-box">

                <input
                    type="text"
                    id="buscar_medio"
                    placeholder="Buscar región, provincia, ciudad o medio..."
                    onkeyup="filtrarMedios()"
                >

                <div id="medio_seleccionado" class="medio-seleccionado">
                    Ningún medio seleccionado
                </div>

                <div id="lista_medios" class="medios-lista">
                    <p>Primero selecciona un tipo de medio.</p>
                </div>

            </div>

            <input type="hidden" name="medio_id" id="medio_id" required>
            <input type="hidden" name="subtipo_medio" id="subtipo_medio" required>

            <label>Nombre del programa</label>
            <input
                type="text"
                name="programa"
                placeholder="Ejemplo: Primera Edición"
            >

            <label>Tono <strong>*</strong></label>
            <select name="tono_id" required>
                <option value="">Seleccione</option>
                <?php foreach ($tonos_array as $tono_item): ?>
                    <option value="<?php echo intval($tono_item['id']); ?>">
                        <?php echo escaparHTML($tono_item['nombre']); ?>
                    </option>
                <?php endforeach; ?>
            </select>

            <button type="submit" name="guardar_noticia" class="news-save">
                REGISTRAR NOTICIA
            </button>

        </form>

    </div>

</div>

<input
    type="file"
    id="input_carga_masiva"
    multiple
    style="display:none;"
    onchange="prepararCargaMasiva(this)"
>

<div id="overlay" class="overlay" onclick="cerrarCarga()"></div>

<div id="drawerCarga" class="drawer upload-drawer">

    <div class="drawer-head">
        <h2>Cargando archivos</h2>
        <button class="drawer-close" onclick="cerrarCarga()">×</button>
    </div>

    <div class="drawer-body upload-body">

        <div class="upload-main-icon">⬆</div>

        <h3 class="upload-title">Carga masiva de archivos</h3>

        <p class="upload-subtitle">
            Los archivos seleccionados se cargan automáticamente. Puedes seleccionar todos los archivos que necesites.
        </p>

        <button type="button" class="btn-select-more" onclick="abrirCarga()">
            SELECCIONAR MÁS ARCHIVOS
        </button>

        <div id="upload_summary" class="upload-summary">
            Esperando selección de archivos...
        </div>

        <div id="upload_list" class="upload-list"></div>

        <button
            id="btn_continuar_carga"
            type="button"
            class="btn-continue"
            onclick="continuarDespuesDeCarga()"
            style="display:none;"
        >
            CONTINUAR
        </button>

    </div>

</div>


<div id="previewModal" class="preview-modal" onclick="cerrarPreviewArchivo()">

    <div class="preview-box" onclick="event.stopPropagation()">

        <div class="preview-head">
            <div id="previewTitle" class="preview-title">Archivo</div>
            <button type="button" class="preview-close" onclick="cerrarPreviewArchivo()">×</button>
        </div>

        <div id="previewContent" class="preview-content"></div>

    </div>

</div>



<div id="cropScreen" class="crop-screen">

    <aside class="crop-sidebar">
        <small>REPOSITORIO</small>
        <h2>Archivos</h2>

        <div class="crop-help">
            <strong id="crop_titulo">Imagen</strong><br><br>
            Selecciona con el mouse el área que quieres recortar. Luego presiona el botón <strong>RECORTAR</strong> para guardar el nuevo archivo en el repositorio.
        </div>

        <button type="button" class="crop-btn" onclick="guardarRecorteImagen()">
            RECORTAR
        </button>

        <button type="button" class="crop-btn secondary" onclick="cerrarRecorteImagen()">
            CANCELAR
        </button>

        <div id="crop_message" class="crop-message"></div>
    </aside>

    <section class="crop-stage-wrap">
        <div class="crop-toolbar">
            <span>Herramienta de recorte de imagen</span>
            <button type="button" class="crop-close" onclick="cerrarRecorteImagen()">×</button>
        </div>

        <div class="crop-stage">
            <div id="crop_canvas_box" class="crop-canvas-box">
                <canvas
                    id="crop_canvas"
                    onmousedown="iniciarSeleccionCrop(event)"
                    onmousemove="moverSeleccionCrop(event)"
                    onmouseup="finalizarSeleccionCrop(event)"
                    onmouseleave="finalizarSeleccionCrop(event)"
                ></canvas>
                <div id="crop_selection" class="crop-selection"></div>
            </div>
        </div>
    </section>

</div>

<div id="editOverlay" class="edit-overlay" onclick="cerrarEditarArchivo()"></div>

<div id="editDrawer" class="edit-drawer">

    <div class="edit-head">
        <div>
            <div class="edit-small-title">ACTUALIZACIÓN DE ARCHIVO</div>
            <h2 id="editTituloCabecera">Archivo</h2>
        </div>
        <button type="button" class="edit-close" onclick="cerrarEditarArchivo()">×</button>
    </div>

    <div class="edit-body">

        <div id="edit_preview" class="edit-preview-box"></div>

        <input type="hidden" id="edit_id">

        <label>Título <strong>*</strong></label>
        <input type="text" id="edit_titulo" required>

        <label>Descripción</label>
        <textarea id="edit_descripcion" placeholder="Describe aquí tu archivo."></textarea>

        <label>Fecha de Publicación</label>
        <input type="date" id="edit_fecha" required>

        <div class="edit-info-grid">
            <div>
                <strong>Duración</strong>
                <span id="edit_duracion">--</span>
            </div>

            <div>
                <strong>Fecha de Registro</strong>
                <span id="edit_fecha_registro">--</span>
            </div>
        </div>

        <button type="button" class="btn-edit-save" onclick="guardarEditarArchivo()">
            APLICAR CAMBIOS
        </button>

    </div>

</div>

<div id="modalSoporte" class="modal">

    <div class="modal-box">

        <span class="modal-close" onclick="cerrarSoporte()">×</span>

        <h2>Soporte</h2>

        <form method="POST">

            <textarea
                name="mensaje_soporte"
                placeholder="Describe el problema técnico o incidencia..."
                required
            ></textarea>

            <button type="submit" name="enviar_soporte">
                ENVIAR
            </button>

            <?php if($mensaje_soporte != ""){ ?>
                <div style="color:red; text-align:center; margin-top:10px; font-weight:bold;">
                    <?php echo htmlspecialchars($mensaje_soporte, ENT_QUOTES, 'UTF-8'); ?>
                </div>
            <?php } ?>

        </form>

    </div>

</div>

</body>
</html>