import { useHasPermission } from "@hooks/useHasPermission";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { highlightText } from "../../../helpers/highlightHelper";
import { Button, Col, Row, Accordion, Badge } from "react-bootstrap";
import DOMPurify from "dompurify";
import Swal from "sweetalert2";
import {
    OptionsFaqModuleTypes,
    OptionsFaqVisibility,
} from "../../../components/Options/OptionsFaqs";
import {
    CardContainer,
    IconApp,
    InputApp,
    SelectSearchApp,
} from "../../../components";
import { PaginationApp } from "../../../components/PaginationApp";
import { CrudApp } from "../../../components/Crud/CrudApp";
import ModalApp from "../../../components/ModalApp";
import { useForm } from "../../../hooks/useForm";
import {
    startClearActiveFaq,
    startCloseFaqModal,
    startCreateFaq,
    startCreateFaqManual,
    startDeleteFaq,
    startExportFaqs,
    startGetFaqReferences,
    startImportFaqs,
    startOpenFaqModal,
    startSetActiveFaq,
    startShowFaqs,
    startUpdateFaq,
} from "../../../redux/slices/users/Faqs";
import { useDispatch, useSelector } from "react-redux";
import { FaqsForm } from "./FaqsForm";

const defaultValues = {
    page: 1,
    query: "",
    number_rows: 10,
    module_type: "",
    module_id: "",
    visibility: "",
    filter_url: "",
    refresh: false,
    id: null,
    question: "",
    answer: "",
    url: "",
    sort_order: 0,
    is_public: false,
    module_ids: [],
    manual_id: "",
    name: "",
    manual: null,
    errors: {},
};

const getPlainHtmlPreview = (html = "") => {
    const temp = document.createElement("div");
    temp.innerHTML = html;

    return temp.textContent?.trim() || "";
};

const buildFaqExportPayload = (faqs = []) => {
    const items = Array.isArray(faqs) ? faqs : [];

    return {
        exported_at: new Date().toISOString(),
        total: items.length,
        faqs: items.map((faq) => ({
            question: faq.question || "",
            answer: faq.answer || "",
            url: faq.url || "",
            context_key: faq.context_key || "",
            sort_order: Number(faq.sort_order || 0),
            is_public: Boolean(faq.is_public),
            manual_id: faq.manual?.id || faq.manual_id || null,
            manual_name: faq.manual?.name || null,
            module_ids: (faq.modules || []).map((module) => module.id),
            modules: (faq.modules || []).map((module) => ({
                id: module.id,
                code: module.code,
                name: module.name,
                type: module.type,
                group: module.group,
            })),
        })),
    };
};

const downloadFaqExportFile = (faqs = [], filenamePrefix = "faqs") => {
    const payload = buildFaqExportPayload(faqs);
    const file = new Blob([JSON.stringify(payload, null, 2)], {
        type: "application/json",
    });
    const fileUrl = window.URL.createObjectURL(file);
    const link = document.createElement("a");
    const date = new Date().toISOString().slice(0, 10);

    link.href = fileUrl;
    link.download = `${filenamePrefix}-${date}.json`;
    document.body.appendChild(link);
    link.click();
    link.remove();
    window.URL.revokeObjectURL(fileUrl);
};

const isModalFaq = (contextKey = "") => /modal/i.test(contextKey);

const stripTrailingIdSegment = (url = "") =>
    url.replace(/\/:id(?=\/?$)/i, "").trim();

const hasTrailingIdSegment = (url = "") => /\/:id(?=\/?$)/i.test(url);

const hasDynamicRouteSegments = (url = "") => /\/:\w+/i.test(url);

const getFaqRouteHref = (url = "") => {
    const normalizedUrl = stripTrailingIdSegment(url);

    if (!normalizedUrl) {
        return "";
    }

    if (/^https?:\/\//i.test(normalizedUrl)) {
        return normalizedUrl;
    }

    return normalizedUrl.startsWith("/")
        ? normalizedUrl
        : `/${normalizedUrl}`;
};

const getFaqRouteLabel = ({ url = "", contextKey = "" }) => {
    if (isModalFaq(contextKey)) {
        return "Modal";
    }

    if (contextKey) {
        return "Modal / Sección";
    }

    return stripTrailingIdSegment(url);
};

const normalizeFaqSectionTitle = (title = "") =>
    title
        .replace(/<[^>]*>/g, "")
        .replace(
            /[\u{1F300}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu,
            "",
        )
        .replace(/\s+/g, " ")
        .trim();

const buildFaqsFromGuideBlocks = ({ answer = "", sort_order = 0 }) => {
    const container = document.createElement("div");
    container.innerHTML = answer;

    const nodes = Array.from(container.childNodes).filter((node) => {
        if (node.nodeType === Node.TEXT_NODE) {
            return node.textContent?.trim();
        }

        return true;
    });

    const guideFaqs = [];
    let currentGuide = null;

    nodes.forEach((node) => {
        const content =
            node.nodeType === Node.ELEMENT_NODE
                ? node.textContent || ""
                : node.textContent || "";
        const normalizedContent = content.replace(/\s+/g, " ").trim();
        const guideMatch = normalizedContent.match(
            /^(GU[IÍ]A|FAQ)\s+(\d+)\s*:\s*(.+)$/i,
        );

        if (guideMatch) {
            if (currentGuide) {
                guideFaqs.push(currentGuide);
            }

            currentGuide = {
                question: guideMatch[3].trim().slice(0, 255),
                answer: "",
                sort_order: Number(sort_order || 0) + guideFaqs.length,
                sectionCount: 0,
            };

            return;
        }

        if (!currentGuide) {
            return;
        }

        if (node.nodeType === Node.ELEMENT_NODE && node.tagName === "H3") {
            currentGuide.sectionCount++;
        }

        currentGuide.answer +=
            node.nodeType === Node.ELEMENT_NODE ? node.outerHTML : content;
    });

    if (currentGuide) {
        guideFaqs.push(currentGuide);
    }

    return guideFaqs.filter((faq) => faq.answer.trim().length > 0);
};

const buildSplitGuideFaqs = ({
    question = "",
    answer = "",
    sort_order = 0,
}) => {
    const guideFaqs = buildFaqsFromGuideBlocks({
        question,
        answer,
        sort_order,
    });

    if (guideFaqs.length > 0) {
        return guideFaqs;
    }

    const container = document.createElement("div");
    container.innerHTML = answer;

    const nodes = Array.from(container.childNodes).filter((node) => {
        if (node.nodeType === Node.TEXT_NODE) {
            return node.textContent?.trim();
        }

        return true;
    });

    const introNodes = [];
    const sections = [];
    let currentSection = null;

    nodes.forEach((node) => {
        const tagName =
            node.nodeType === Node.ELEMENT_NODE ? node.tagName : null;

        if (tagName === "H3") {
            if (currentSection) {
                sections.push(currentSection);
            }

            currentSection = {
                title: normalizeFaqSectionTitle(node.textContent || ""),
                nodes: [node.outerHTML],
            };

            return;
        }

        if (currentSection) {
            currentSection.nodes.push(
                node.nodeType === Node.ELEMENT_NODE
                    ? node.outerHTML
                    : node.textContent,
            );

            return;
        }

        introNodes.push(
            node.nodeType === Node.ELEMENT_NODE
                ? node.outerHTML
                : node.textContent,
        );
    });

    if (currentSection) {
        sections.push(currentSection);
    }

    if (sections.length < 3) {
        return [];
    }

    const introHtml = introNodes.join("").trim();
    const chunkSize = Math.ceil(sections.length / 3);
    const baseQuestion = question.trim();

    return Array.from({ length: 3 }, (_, index) => {
        const groupedSections = sections.slice(
            index * chunkSize,
            (index + 1) * chunkSize,
        );

        if (groupedSections.length === 0) {
            return null;
        }

        const firstTitle = groupedSections[0]?.title || `Parte ${index + 1}`;
        const lastTitle =
            groupedSections.length > 1
                ? groupedSections[groupedSections.length - 1]?.title
                : null;
        const suffix =
            lastTitle && lastTitle !== firstTitle
                ? `${firstTitle} a ${lastTitle}`
                : firstTitle;

        return {
            question: baseQuestion
                ? `${baseQuestion} - ${suffix}`.slice(0, 255)
                : suffix.slice(0, 255),
            answer: `${introHtml}${groupedSections
                .map((section) => section.nodes.join(""))
                .join("")}`,
            sort_order: Number(sort_order || 0) + index,
            sectionCount: groupedSections.length,
        };
    }).filter(Boolean);
};

const faqFormDefaultValues = {
    id: null,
    question: "",
    answer: "",
    url: "",
    context_key: "",
    sort_order: 0,
    is_public: false,
    module_ids: [],
    manual_id: "",
    name: "",
    manual: null,
};

export const FAQ_TEMPLATE = `
<h2>Introducción</h2> <p>Esta pantalla permite a los operadores y personal autorizado acceder al sistema mediante su correo electrónico y contraseña. Es la puerta de entrada principal a la plataforma, donde también se puede recuperar el acceso en caso de olvidar la clave.</p><h3>🔐 Inicio de sesión estándar</h3> <ol> <li>Escribe tu <strong>correo electrónico</strong> en el campo correspondiente.</li> <li>Escribe tu <strong>contraseña</strong> en el campo habilitado para ello.</li> <li>Haz clic en el botón <strong>Iniciar sesión</strong>.</li> <li>Una vez dentro, podrás acceder a las funciones permitidas para tu perfil.</li> </ol><h3>🔄 ¿Olvidaste tu contraseña?</h3> <ol> <li>Si no recuerdas tu contraseña, haz clic en el enlace <strong>¿Olvidaste tu contraseña?</strong>.</li> <li>Sigue las instrucciones que se te indicarán para restablecer tu acceso.</li> </ol><h3>🆘 Ayuda disponible</h3> <ul> <li>En la misma pantalla encontrarás un botón o enlace con el texto <strong>Ayuda</strong> o <strong>Ayuda de Acceso</strong>.</li> <li>Al hacer clic allí, se desplegará información adicional con preguntas frecuentes y orientación sobre el inicio de sesión.</li> </ul><h3>⚠️ Recomendaciones y mensajes de error</h3> <ul> <li>Si dejas algún campo vacío o introduces un formato de correo inválido, la pantalla te lo indicará antes de continuar.</li> <li>Si tu contraseña es incorrecta o tu cuenta tiene restricciones, recibirás un mensaje de error visible en la parte inferior del formulario.</li> <li>La pantalla también puede mostrar un mensaje como <strong>"No compartas tu información con nadie"</strong> como recordatorio de seguridad.</li> <li>En caso de intentos fallidos repetidos, podrías ver un aviso relacionado con el límite de intentos permitidos.</li> </ul><h3>✅ Buenas prácticas</h3> <ul> <li>Asegúrate de que tu correo electrónico esté bien escrito, sin espacios ni mayúsculas innecesarias.</li> <li>Utiliza siempre contraseñas seguras y no las compartas con otros usuarios.</li> <li>Si trabajas en un equipo compartido, cierra siempre tu sesión al terminar.</li> </ul>
`;

export default function FaqsScreen() {
    const dispatch = useDispatch();
    const { hasPermission } = useHasPermission();
    const canManage = hasPermission("FAQS_ADMIN");
    const [addManualActive, setAddManualActive] = useState(false);
    const importInputRef = useRef(null);
    const {
        pagination,
        manualOptions,
        moduleOptionsByType,
        modalOpen,
        active,
    } = useSelector((state) => state.faqs);

    const {
        values,
        handleInputChange,
        setInputValue,
        setFormValues,
        setErrors,
    } = useForm(defaultValues);

    const [viewMode, setViewMode] = useState(canManage ? "table" : "user");

    const highlight = (text) => highlightText(text, values.query);

    const availableModules = useMemo(() => {
        if (values.module_type) {
            return moduleOptionsByType[values.module_type] || [];
        }

        return [
            ...moduleOptionsByType.EMPLOYEES,
            ...moduleOptionsByType.TEACHERS,
            ...moduleOptionsByType.STUDENTS,
        ];
    }, [moduleOptionsByType, values.module_type]);

    useEffect(() => {
        dispatch(startGetFaqReferences());
    }, [dispatch]);

    useEffect(() => {
        dispatch(
            startShowFaqs(
                {
                    page: values.page,
                    query: values.query,
                    number_rows: values.number_rows,
                    module_type: values.module_type,
                    module_id: values.module_id,
                    visibility: values.visibility,
                    filter_url: values.filter_url,
                    refresh: values.refresh,
                },
                canManage,
            ),
        );
    }, [
        values.page,
        values.query,
        values.number_rows,
        values.module_type,
        values.module_id,
        values.visibility,
        values.filter_url,
        values.refresh,
        canManage,
        dispatch,
    ]);

    useEffect(() => {
        if (
            Number(pagination?.last_page || 0) > 0 &&
            Number(pagination?.current_page || 0) >
                Number(pagination?.last_page || 0)
        ) {
            setInputValue("page", 1);
        }
    }, [pagination?.current_page, pagination?.last_page, setInputValue]);

    const resetFaqForm = () => {
        setFormValues(faqFormDefaultValues);
    };

    useEffect(() => {
        if (active) {
            setFormValues({
                ...faqFormDefaultValues,
                id: active.id,
                question: active.question || "",
                answer: active.answer || "",
                url: active.url || "",
                context_key: active.context_key || "",
                sort_order: active.sort_order || 0,
                is_public: Boolean(active.is_public),
                manual_id: active.manual?.id || "",
                module_ids: (active.modules || []).map((module) => ({
                    value: module.id,
                    label: module.name,
                    type: module.type,
                    group: module.group,
                    code: module.code,
                })),
            });
            return;
        }

        resetFaqForm();
    }, [active]);

    const handleFiltersChange = (event) => {
        if (event.target.name === "module_type") {
            setInputValue("module_id", "");
        }

        if (event.target.name !== "page") {
            setInputValue("page", 1);
        }

        handleInputChange(event);
    };

    const openCreateModal = () => {
        resetFaqForm();
        setInputValue("answer", FAQ_TEMPLATE);
        setAddManualActive(false);
        dispatch(startClearActiveFaq());
        dispatch(startOpenFaqModal());
    };

    const openEditModal = (faq) => {
        setFormValues({
            name: "",
            manual: null,
        });
        setAddManualActive(false);
        dispatch(startSetActiveFaq(faq));
        dispatch(startOpenFaqModal());
    };

    const saveManualInline = async () => {
        const errors = {};

        if (!values.name) {
            errors.name = ["El nombre del manual es obligatorio."];
        }

        if (!values.manual) {
            errors.manual = ["Debes cargar un archivo PDF."];
        }

        if (Object.keys(errors).length > 0) {
            setErrors(errors);
            return;
        }

        setErrors({});
        dispatch(
            startCreateFaqManual(values, setErrors, (manual) => {
                setInputValue("manual_id", manual.id);
                setAddManualActive(false);
                setFormValues({
                    name: "",
                    manual: null,
                });
            }),
        );
    };

    const persistFaq = (payload, faqId = null) =>
        new Promise((resolve, reject) => {
            const callback = (faq) => resolve(faq);
            const handleErrors = (errors) => {
                setErrors(errors);
                reject(errors);
            };

            if (faqId) {
                dispatch(
                    startUpdateFaq(faqId, payload, handleErrors, callback),
                );
                return;
            }

            dispatch(startCreateFaq(payload, handleErrors, callback));
        });

    const saveFaq = async () => {
        const errors = {};

        if (!values.question) {
            errors.question = ["La pregunta es obligatoria."];
        }

        if (!values.answer) {
            errors.answer = ["La respuesta es obligatoria."];
        }

        if (!values.is_public && values.module_ids.length === 0) {
            errors.module_ids = ["Selecciona al menos un módulo."];
        }

        if (Object.keys(errors).length > 0) {
            setErrors(errors);
            return;
        }

        setErrors({});

        const payload = {
            question: values.question,
            answer: values.answer,
            url: values.url || null,
            context_key: values.context_key || null,
            sort_order: Number(values.sort_order || 0),
            is_public: Boolean(values.is_public),
            manual_id: values.manual_id || null,
            module_ids: values.module_ids.map((module) => module.value),
        };
        const splitFaqs = buildSplitGuideFaqs(payload);

        if (splitFaqs.length >= 2) {
            const confirmation = await Swal.fire({
                title: `Dividir guía en ${splitFaqs.length} FAQs`,
                html: `
                    <p class="mb-2">
                        Detecté <strong>${splitFaqs.reduce((total, faq) => total + faq.sectionCount, 0)} secciones</strong>
                        y puedo separarlas en estas guías:
                    </p>
                    <ol class="text-start">
                        ${splitFaqs
                            .map((faq) => `<li>${faq.question}</li>`)
                            .join("")}
                    </ol>
                    <p class="mb-0">Se conservarán la URL, permisos, visibilidad y manual relacionado.</p>
                `,
                icon: "question",
                showCancelButton: true,
                confirmButtonText: "Sí, dividir",
                cancelButtonText: "No, guardar una sola",
                confirmButtonColor: "#007bff",
                cancelButtonColor: "#6c757d",
            });

            if (confirmation.isConfirmed) {
                try {
                    if (values.id) {
                        const [firstFaq, ...remainingFaqs] = splitFaqs;

                        await persistFaq(
                            {
                                ...payload,
                                question: firstFaq.question,
                                answer: firstFaq.answer,
                                sort_order: firstFaq.sort_order,
                            },
                            values.id,
                        );

                        for (const faq of remainingFaqs) {
                            await persistFaq({
                                ...payload,
                                question: faq.question,
                                answer: faq.answer,
                                sort_order: faq.sort_order,
                            });
                        }
                    } else {
                        for (const faq of splitFaqs) {
                            await persistFaq({
                                ...payload,
                                question: faq.question,
                                answer: faq.answer,
                                sort_order: faq.sort_order,
                            });
                        }
                    }

                    Swal.fire({
                        title: "Éxito",
                        text: `La guía se dividió en ${splitFaqs.length} FAQs.`,
                        icon: "success",
                        toast: true,
                        position: "bottom-end",
                        timer: 8000,
                    });

                    dispatch(startCloseFaqModal());
                    resetFaqForm();
                    setInputValue("refresh", !values.refresh);
                    return;
                } catch {
                    return;
                }
            }
        }

        try {
            await persistFaq(payload, values.id || null);
            dispatch(startCloseFaqModal());
            resetFaqForm();
            setInputValue("refresh", !values.refresh);
        } catch {
            return;
        }
    };

    const deleteFaq = async (faq) => {
        dispatch(
            startDeleteFaq(faq.id, () => {
                setInputValue("refresh", !values.refresh);
            }),
        );
    };

    const handleExportFaqs = () => {
        dispatch(
            startExportFaqs(
                {
                    page: values.page,
                    query: values.query,
                    number_rows: values.number_rows,
                    module_type: values.module_type,
                    module_id: values.module_id,
                    visibility: values.visibility,
                    filter_url: values.filter_url,
                },
                (faqs) => {
                    downloadFaqExportFile(faqs, "faqs");
                },
                canManage,
            ),
        );
    };

    const handleExportSingleFaq = (faq) => {
        const sanitizedQuestion =
            faq.question
                ?.toLowerCase()
                .normalize("NFD")
                .replace(/[\u0300-\u036f]/g, "")
                .replace(/[^a-z0-9]+/g, "-")
                .replace(/^-+|-+$/g, "")
                .slice(0, 60) || `faq-${faq.id}`;

        downloadFaqExportFile([faq], sanitizedQuestion);
    };

    const handleOpenImport = () => {
        importInputRef.current?.click();
    };

    const handleImportFaqs = async (event) => {
        const file = event.target.files?.[0];

        if (!file) {
            return;
        }

        try {
            const rawContent = await file.text();
            const parsedContent = JSON.parse(rawContent);
            const faqsToImport = Array.isArray(parsedContent)
                ? parsedContent
                : Array.isArray(parsedContent?.faqs)
                  ? parsedContent.faqs
                  : [];

            if (faqsToImport.length === 0) {
                Swal.fire({
                    title: "Archivo inválido",
                    text: "El archivo no contiene FAQs para importar.",
                    icon: "warning",
                });
                event.target.value = "";
                return;
            }

            const confirmed = await Swal.fire({
                title: "¿Importar FAQs?",
                text: `Se crearán ${faqsToImport.length} FAQ(s) nuevas.`,
                icon: "question",
                showCancelButton: true,
                confirmButtonText: "Sí, importar",
                cancelButtonText: "Cancelar",
            });

            if (!confirmed.isConfirmed) {
                event.target.value = "";
                return;
            }

            dispatch(
                startImportFaqs(faqsToImport, setErrors, () => {
                    setInputValue("refresh", !values.refresh);
                }),
            );
        } catch {
            Swal.fire({
                title: "Archivo inválido",
                text: "No se pudo leer el archivo JSON seleccionado.",
                icon: "error",
            });
        }

        event.target.value = "";
    };

    const FaqEnciclopediaView = ({
        paginationData,
        highlight,
        onPageChange,
    }) => {
        const {
            data = [],
            current_page = 1,
            total = 0,
            from = 0,
            to = 0,
            per_page = values.number_rows || 10,
        } = paginationData || {};

        const customStyles = `
        .faq-enciclopedia-view {
            font-family: 'Inter', system-ui, -apple-system, sans-serif;
            color: #334155;
        }
        .faq-highlight {
            background-color: #fff9c4;
            color: #d32f2f;
            padding: 0 2px;
            border-radius: 2px;
            font-weight: bold;
        }

        /* --- Header Styling (Image 1 Style) --- */
        .faq-accordion-item {
            border: 1px solid #e2e8f0;
            border-radius: 10px !important;
            overflow: hidden;
            box-shadow: 0 2px 4px rgba(0,0,0,0.02);
            margin-bottom: 1.25rem;
            transition: all 0.25s ease;
        }
        .faq-accordion-item:hover {
            box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
            border-color: #cbd5e1;
        }
        .faq-accordion-header button {
            background: #ffffff !important;
            padding: 1.1rem 1.5rem;
            transition: all 0.2s ease;
        }
        .faq-accordion-header button:not(.collapsed) {
            background: #f0f7ff !important; /* Azul suave de la Image 1 */
            color: #1e3a8a !important;
            box-shadow: none;
            border-bottom: 1px solid #d1e9ff;
        }
        .faq-user-question {
            font-size: 1.1rem;
            font-weight: 700;
            color: inherit;
            line-height: 1.4;
        }

        /* --- Answer Content (Premium Styles from CardContainerFaqs) --- */
        .faq-answer-container {
            padding: 1.5rem 2rem;
            background-color: #ffffff;
        }
        .faq-answer-content {
            font-size: 1.05rem;
            line-height: 1.7;
            color: #475569;
        }
        .faq-answer-content * {
             background-color: transparent !important;
        }
        
        /* List Styles */
        .faq-answer-content ul {
            list-style: none;
            padding-left: 0;
            margin-top: 1rem;
        }
        .faq-answer-content ul li {
            position: relative;
            padding: 8px 14px 8px 42px;
            margin-bottom: 0.5rem;
            border-radius: 8px;
            border: 1px solid #f8fafc;
            color: #334155 !important;
        }
        .faq-answer-content ul li::before {
            content: '✓';
            position: absolute;
            left: 14px;
            top: 50%;
            transform: translateY(-50%);
            color: #10b981 !important;
            font-size: 1.2rem;
            font-weight: 900;
        }
        .faq-answer-content ol {
            list-style: none;
            counter-reset: faq-steps;
            padding-left: 0;
            position: relative;
        }
        .faq-answer-content ol li {
            counter-increment: faq-steps;
            position: relative;
            padding-left: 44px;
            margin-bottom: 1rem;
            min-height: 28px;
        }
        .faq-answer-content ol li::before {
            content: counter(faq-steps);
            position: absolute;
            left: 0;
            top: 2px;
            width: 28px;
            height: 28px;
            background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important;
            color: #ffffff !important;
            border-radius: 8px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: 700;
            font-size: 0.85rem;
            box-shadow: 0 2px 4px rgba(37, 99, 235, 0.15);
        }

        .faq-match-badge {
            font-size: 0.65rem;
            background-color: #dcfce7 !important;
            color: #15803d !important;
            border: 1px solid #bbf7d0;
            padding: 3px 8px;
            text-transform: uppercase;
            letter-spacing: 0.05em;
            font-weight: 800;
            border-radius: 4px;
        }
        .faq-enciclopedia-footer {
            display: flex;
            justify-content: space-between;
            align-items: center;
            gap: 1rem;
            margin-top: 1.5rem;
            flex-wrap: wrap;
        }
        .faq-enciclopedia-summary {
            color: #64748b;
            font-size: 0.95rem;
        }
    `;

        if (data.length === 0) {
            return (
                <div className="text-center py-5 border rounded bg-light mt-4">
                    <i className="fa fa-search fs-1 text-muted mb-3" />
                    <p className="text-muted">
                        No se encontraron resultados para los filtros aplicados.
                    </p>
                </div>
            );
        }

        return (
            <div className="faq-enciclopedia-view mt-4">
                <style>{customStyles}</style>
                <Accordion>
                    {data.map((faq) => {
                        const isMatch =
                            values.query &&
                            (faq.question
                                ?.toLowerCase()
                                .includes(values.query.toLowerCase()) ||
                                getPlainHtmlPreview(faq.answer || "")
                                    .toLowerCase()
                                    .includes(values.query.toLowerCase()));

                        return (
                            <Accordion.Item
                                eventKey={String(faq.id)}
                                key={faq.id}
                                className="faq-accordion-item"
                            >
                                <Accordion.Header className="faq-accordion-header">
                                    <div className="d-flex align-items-center gap-3 w-100 pe-3">
                                        <span
                                            className="faq-user-question"
                                            dangerouslySetInnerHTML={{
                                                __html: highlight(faq.question),
                                            }}
                                        />
                                        {isMatch && (
                                            <Badge className="faq-match-badge ms-auto">
                                                Resultado coincide
                                            </Badge>
                                        )}
                                    </div>
                                </Accordion.Header>
                                <Accordion.Body className="faq-answer-container">
                                    <div
                                        className="faq-answer-content"
                                        dangerouslySetInnerHTML={{
                                            __html: DOMPurify.sanitize(
                                                highlight(faq.answer || ""),
                                            ),
                                        }}
                                    />

                                    {(faq.url || faq.manual?.uri) && (
                                        <div className="d-flex mt-4 gap-2 border-top pt-3">
                                            {faq.url && (
                                                <Button
                                                    variant="outline-secondary"
                                                    size="sm"
                                                    className="rounded-pill px-3 py-1 font-weight-bold"
                                                    style={{
                                                        borderColor: "#cbd5e1",
                                                        color: "#475569",
                                                        fontSize: "0.85rem",
                                                    }}
                                                    onClick={() =>
                                                        window.open(
                                                            faq.url,
                                                            "_blank",
                                                        )
                                                    }
                                                >
                                                    <i className="fa fa-external-link-alt me-2 text-primary" />
                                                    Ir a la sección
                                                </Button>
                                            )}
                                            {faq.manual?.uri && (
                                                <Button
                                                    variant="outline-secondary"
                                                    size="sm"
                                                    className="rounded-pill px-3 py-1 font-weight-bold"
                                                    style={{
                                                        borderColor: "#cbd5e1",
                                                        color: "#475569",
                                                        fontSize: "0.85rem",
                                                    }}
                                                    onClick={() =>
                                                        window.open(
                                                            faq.manual.uri,
                                                            "_blank",
                                                        )
                                                    }
                                                >
                                                    <i className="fa fa-book me-2 text-info" />
                                                    Ver manual
                                                </Button>
                                            )}
                                        </div>
                                    )}
                                </Accordion.Body>
                            </Accordion.Item>
                        );
                    })}
                </Accordion>

                <div className="faq-enciclopedia-footer">
                    <small className="faq-enciclopedia-summary">
                        Mostrando {from} a {to} de {total} resultados.
                    </small>

                    <PaginationApp
                        totalItemsCount={parseInt(total) || 0}
                        activePage={parseInt(current_page) || 1}
                        itemsCountPerPage={parseInt(per_page) || 10}
                        pageRangeDisplayed={4}
                        onChange={onPageChange}
                    />
                </div>
            </div>
        );
    };

    return (
        <CardContainer title="FAQ'S">
            <Row className="mb-3">
                {canManage && (
                    <>
                        <Col md={3}>
                            <SelectSearchApp
                                title="Tipo de usuario"
                                name="module_type"
                                value={values.module_type}
                                onChange={handleFiltersChange}
                                options={OptionsFaqModuleTypes}
                                placeholder="Filtrar por tipo"
                            />
                        </Col>

                        <Col md={4}>
                            <SelectSearchApp
                                title="Módulo"
                                name="module_id"
                                value={values.module_id}
                                onChange={handleFiltersChange}
                                options={availableModules}
                                placeholder="Filtrar por módulo"
                            />
                        </Col>

                        <Col md={3}>
                            <SelectSearchApp
                                title="Visibilidad"
                                name="visibility"
                                value={values.visibility}
                                onChange={handleFiltersChange}
                                options={OptionsFaqVisibility}
                                placeholder="Todas"
                            />
                        </Col>
                    </>
                )}

                <Col md={2}>
                    {canManage && (
                        <>
                            <Button
                                className="btn-app w-100 mt-4"
                                onClick={openCreateModal}
                            >
                                <IconApp iconClassName="fa fa-plus me-2" />
                                Nueva FAQ
                            </Button>

                            <Button
                                variant="outline-secondary"
                                className="w-100 mt-2"
                                onClick={handleExportFaqs}
                            >
                                <IconApp iconClassName="fa fa-file-export me-2" />
                                Exportar todo
                            </Button>

                            <Button
                                variant="outline-secondary"
                                className="w-100 mt-2"
                                onClick={handleOpenImport}
                            >
                                <IconApp iconClassName="fa fa-file-import me-2" />
                                Importar
                            </Button>

                            <input
                                ref={importInputRef}
                                type="file"
                                accept="application/json"
                                className="d-none"
                                onChange={handleImportFaqs}
                            />
                        </>
                    )}
                </Col>

                <Col md={12}>
                    <div className="d-flex justify-content-between align-items-center mb-3">
                        <div className="flex-grow-1">
                            <InputApp
                                title="Buscar en preguntas y respuestas..."
                                name="query"
                                value={values.query}
                                onChange={handleFiltersChange}
                                maxLength={255}
                                placeholder="Escribe para buscar..."
                            />
                        </div>
                        {canManage && (
                            <div className="ms-3 pt-2">
                                <Button
                                    variant={
                                        viewMode === "table"
                                            ? "primary"
                                            : "outline-primary"
                                    }
                                    className="me-2"
                                    onClick={() => setViewMode("table")}
                                    title="Vista de administrador"
                                >
                                    <i className="fa fa-table" />
                                </Button>
                                <Button
                                    variant={
                                        viewMode === "user"
                                            ? "primary"
                                            : "outline-primary"
                                    }
                                    onClick={() => setViewMode("user")}
                                    title="Vista de enciclopedia"
                                >
                                    <i className="fa fa-book-open" />
                                </Button>
                            </div>
                        )}
                    </div>
                </Col>

                {canManage && (
                    <Col md={12}>
                        <InputApp
                            title="Filtrar por URL técnica"
                            name="filter_url"
                            value={values.filter_url}
                            onChange={handleFiltersChange}
                            maxLength={1000}
                            placeholder="Ej. /app/operators/..."
                        />
                    </Col>
                )}
            </Row>

            {viewMode === "table" ? (
                <CrudApp
                    crudName="faqs-crud"
                    values={values}
                    setInputValue={setInputValue}
                    handleInputChange={handleFiltersChange}
                    pagination={pagination}
                    tableHeaders={[
                        "Pregunta",
                        "Ruta",
                        "Visibilidad",
                        "Tipo",
                        "Manual",
                    ]}
                    hasActions={canManage}
                >
                    {pagination.data.map((faq) => (
                        <tr key={faq.id}>
                            <td className="align-middle w-40">
                                <div className="faq-admin-question">
                                    {faq.question}
                                </div>
                                <div className="faq-admin-answer-preview">
                                    {getPlainHtmlPreview(faq.answer).slice(
                                        0,
                                        180,
                                    )}
                                    {getPlainHtmlPreview(faq.answer).length >
                                    180
                                        ? "..."
                                        : ""}
                                </div>
                            </td>

                            <td className="align-middle text-center">
                                {faq.url ? (
                                    hasDynamicRouteSegments(
                                        stripTrailingIdSegment(faq.url),
                                    ) ? (
                                        <div
                                            className="text-muted"
                                            title="Ruta dinámica no disponible para acceso directo"
                                        >
                                            {getFaqRouteLabel({
                                                url: faq.url,
                                                contextKey: faq.context_key,
                                            })}
                                        </div>
                                    ) : (
                                        <a
                                            href={getFaqRouteHref(faq.url)}
                                            className="btn btn-link p-0 text-decoration-none"
                                        >
                                            {getFaqRouteLabel({
                                                url: faq.url,
                                                contextKey: faq.context_key,
                                            })}
                                        </a>
                                    )
                                ) : (
                                    <div>
                                        {faq.context_key
                                            ? getFaqRouteLabel({
                                                  contextKey:
                                                      faq.context_key,
                                              })
                                            : "Enciclopedia"}
                                    </div>
                                )}
                                {faq.context_key ? (
                                    <div className="mt-1 text-size-11 text-muted">
                                        Contexto: {faq.context_key}
                                    </div>
                                ) : null}
                                {hasTrailingIdSegment(faq.url) ? (
                                    <div className="mt-1 text-size-11 text-muted">
                                        Pregunta con ID
                                    </div>
                                ) : null}
                            </td>

                            <td className="align-middle text-center">
                                <span
                                    className={`badge ${
                                        faq.is_public ? "bg-info" : "bg-warning"
                                    }`}
                                >
                                    {faq.is_public ? "Pública" : "Restringida"}
                                </span>
                            </td>

                            <td className="align-middle text-center">
                                {Array.from(
                                    new Set(
                                        (faq.modules || []).map(
                                            (module) => module.type,
                                        ),
                                    ),
                                ).join(", ") || "General"}
                            </td>

                            <td className="align-middle text-center">
                                {faq.manual?.uri ? (
                                    <button
                                        type="button"
                                        className="btn btn-link p-0"
                                        onClick={() =>
                                            window.open(
                                                faq.manual.uri,
                                                "_blank",
                                                "noopener,noreferrer",
                                            )
                                        }
                                    >
                                        {faq.manual.name}
                                    </button>
                                ) : (
                                    "-"
                                )}
                            </td>

                            {canManage && (
                                <td className="text-center align-middle">
                                    <div>
                                        <IconApp
                                            iconClassName="fas fa-file-export mx-2"
                                            description="Exportar FAQ"
                                            color="#495057"
                                            isClickable={true}
                                            onClick={() =>
                                                handleExportSingleFaq(faq)
                                            }
                                        />

                                        <IconApp
                                            iconClassName="fas fa-pen mx-2"
                                            description="Editar FAQ"
                                            color="#495057"
                                            isClickable={true}
                                            onClick={() => openEditModal(faq)}
                                        />

                                        <IconApp
                                            iconClassName="fas fa-trash mx-2"
                                            description="Eliminar FAQ"
                                            color="#495057"
                                            isClickable={true}
                                            onClick={() => deleteFaq(faq)}
                                        />
                                    </div>
                                </td>
                            )}
                        </tr>
                    ))}
                </CrudApp>
            ) : (
                <FaqEnciclopediaView
                    paginationData={pagination}
                    highlight={highlight}
                    onPageChange={(pagePagination) =>
                        setInputValue("page", pagePagination)
                    }
                />
            )}

            <ModalApp
                openModal={modalOpen}
                hiddenButtonOnOpen
                onCloseModal={() => {
                    dispatch(startCloseFaqModal());
                    resetFaqForm();
                    setAddManualActive(false);
                }}
                Action={() => <span className="d-none" />}
                titleModal={values.id ? "Editar FAQ" : "Nueva FAQ"}
                size="xl"
                backdrop={"static"}
                keyboard={false}
                enforceFocus={false}
                autoFocus={false}
            >
                <FaqsForm
                    values={values}
                    handleInputChange={handleInputChange}
                    moduleOptions={availableModules}
                    manualOptions={manualOptions}
                    addManualActive={addManualActive}
                    setAddManualActive={setAddManualActive}
                    saveManualInline={saveManualInline}
                    saveFaq={saveFaq}
                    isEditing={Boolean(values.id)}
                />
            </ModalApp>
        </CardContainer>
    );
}
