Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\ACT - PDF copies [Legislation]\THE INDIAN PORTS ACT, 1908.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\Things to do for Witness preparation.docx
Warning: Indexing all PDF objects
Error reading the PDF file: Error
    at InvalidPDFExceptionClosure (C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:452:35)     
    at Object.<anonymous> (C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:455:2)
    at __w_pdfjs_require__ (C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:45:30)
    at Object.<anonymous> (C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:7939:23)
    at __w_pdfjs_require__ (C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:45:30)
    at C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:88:18
    at C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:91:10
    at webpackUniversalModuleDefinition (C:\Users\Administrator\Desktop\quesst -v4\node_modules\pdf-parse\lib\pdf.js\v1.10.100\build\pdf.js:18:20)    at Module._compile (node:internal/modules/cjs/loader:1469:14) {
  message: 'Invalid PDF structure'
}
Error executing search: Error: Error parsing the PDF file
    at findKeywordInPDF (C:\Users\Administrator\Desktop\quesst -v4\services\api.js:76:15)
    at async C:\Users\Administrator\Desktop\quesst -v4\services\api.js:143:32
PS C:\Users\Administrator\Desktop\quesst -v4\services> node api.js
Server running at http://192.168.7.103:3006
Mongoose connected to MongoDB
MongoDB connected
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\19(4), arbitration act - Admissibility, relevancy, materiality\Petition to Special leave to Appeal_8136_2022 - Order_11-Jul-2022.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\Arbitrator cannot adjudicate FEMA\10. Banyan_Tree_Growth_Capital_LLC_vs_Axiom_Cordages_LMH202007052018105990COM749303.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\Change in Law\CHANGE IN LAW 2022\Legal Updated COVID & FM, CHANGE IN LAW\March 2020 to May 2021- COVID, FMJ, Change in Law Judgments\7. September 2020\CRSC_Research_and_Design_Institute_Group_Co_Ltd_vsDE202007102017305529COM651634.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\Change in Law - Same economic and legal position\03. Sion_Panvel vs State of 
MH.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\Fundamental  principles of Civil  Procedure Code, 1908  and Indian Evidence  
Act, 1872 ought to be  observed by Arbitral  Tribunal\Valentine Maritime Ltd. v. Kreuz Subsea (P) Ltd., 2021 SCC OnLine Bom 75.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\Liquidated damages has to be proved\1. Egon_Zhender_International_Pvt_Ltd_vs_Namgayal_InsD133550COM962921.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\Principles of Civil Procedure Code are Applicable to Arbitration Proceedings\Valentine Maritime Ltd. v. Kreuz Subsea (P) Ltd., 2021 SCC OnLine Bom 75.pdf
Attempting to process file: \\192.168.13.30\c$\GGN Office Repository\revocation of exemption amounts to CIL\1. Adani Power (Mudra) Limited v. central electricity.pdf
Warning: TT: undefined function: 32
    the code is const express = require('express');
const sql = require('mssql');
const cors = require('cors');
const path = require('path'); 
const fs = require('fs');
const pdfParse = require('pdf-parse');
const authRoutes = require("../src/routes/auth");
const LibraryRoute = require("../src/routes/Library");
const connectDB = require('../config/db');
const NodeCache = require('node-cache');

const app = express();
app.use(cors());
app.use(express.json());
app.use("/api/auth", authRoutes);
app.use("/api/lib", LibraryRoute);
connectDB();

// SQL and Database Configuration
const sqlconfig = {
    server: '192.168.13.30',
    database: 'ocr',
    user: 'sa',
    password: 'sa@12345',
    options: {
        encrypt: false,
        trustServerCertificate: true,
        trustedConnection: true,
    },
    pool: {
        max: 10,
        min: 0,
        idleTimeoutMillis: 30000,
    },
    requestTimeout: 50000,
};

// Cache for search results
const searchCache = new NodeCache({ 
    stdTTL: 3600, // Cache for 1 hour
    checkperiod: 600 
});

// Establish SQL connection
const pool = new sql.ConnectionPool(sqlconfig);
const poolConnect = pool.connect();

pool.on('error', (err) => {
    console.error('SQL Pool Error: ', err);
});

// Helper: Parse PDF to find which page contains the keyword
async function findKeywordInPDF(filePath, keyword) {
    console.log('Attempting to process file:', filePath);

    if (!fs.existsSync(filePath)) {
        console.error('File not found:', filePath);
        throw new Error(`File not found: ${filePath}`);
    }

    try {
        const pdfBuffer = fs.readFileSync(filePath);
        const data = await pdfParse(pdfBuffer);
        const pages = data.text.split('\n\n'); // Split data by pages

        // Search keyword in all pages and return the correct page
        for (let i = 0; i < pages.length; i++) {
            if (pages[i].toLowerCase().includes(keyword.toLowerCase())) {
                return i + 1; // Return the 1-indexed page of the keyword
            }
        }

        return -1; // Not found
    } catch (err) {
        console.error('Error reading the PDF file:', err);
        throw new Error('Error parsing the PDF file');
    }
}

// Extract relative path for frontend
const getRelativePath = (fullPath) => {
    const basePath = '\\\\192.168.13.30\\c$\\GGN Office Repository\\';
    if (!fullPath || !fullPath.startsWith(basePath)) {
        console.error("Invalid file path:", fullPath);
        return ''; 
    }
    return fullPath.slice(basePath.length).replace(/\\/g, '/');
};

// Search Endpoint
app.get('/search', async (req, res) => {
    const { keyword, exclude } = req.query;

    // Validation
    if (!keyword || keyword.trim() === '') {
        return res.status(400).json({ error: "No search keyword provided." });
    }

    const cacheKey = `search:${keyword}:${exclude || 'noexclude'}`;
    const cachedResults = searchCache.get(cacheKey);
    if (cachedResults) {
        return res.json(cachedResults);
    }

    try {
        await poolConnect;
        const request = pool.request();
        let query;

        // Sanitize the search term and split by "+" for boolean AND search
        const sanitizedKeyword = keyword.replace(/[^\w\s+\-]/g, '');
        const terms = sanitizedKeyword.split('+').map(term => term.trim()).filter(Boolean);

        // Construct SQL query for boolean AND
        query = `SELECT Filename FROM files WHERE PdfData LIKE @term0`;
        request.input('term0', sql.NVarChar, `%${terms[0]}%`);

        terms.slice(1).forEach((term, index) => {
            query += ` AND PdfData LIKE @term${index + 1}`;
            request.input(`term${index + 1}`, sql.NVarChar, `%${term}%`);
        });

        // Handle exclusions
        if (exclude && exclude.trim() !== '') {
            const excludeWords = exclude.split(/\s+/).filter(Boolean);
            excludeWords.forEach((word, index) => {
                const sanitizedExclude = word.replace(/[^\w\s]/g, '');
                query += ` AND PdfData NOT LIKE @exclude${index}`;
                request.input(`exclude${index}`, sql.NVarChar, `%${sanitizedExclude}%`);
            });
        }

        const results = await request.query(query);

        if (results.recordset.length === 0) {
            return res.status(404).json({ message: 'No PDFs found matching the criteria.' });
        }

        // Process search results
        const enhancedResults = [];
        for (const record of results.recordset) {
            const filePath = record.Filename.trim();
            const pageNumber = await findKeywordInPDF(filePath, terms[0]); // Check first term

            enhancedResults.push({
                Filename: record.Filename,
                relativePath: getRelativePath(filePath),
                searchTerm: terms[0],
                page: pageNumber > 1 ? pageNumber - 1 : 1 // Adjust to page - 1
            });
        }

        searchCache.set(cacheKey, enhancedResults);
        res.json(enhancedResults);
    } catch (err) {
        console.error("Error executing search:", err);
        res.status(500).json({ error: "An error occurred during the search." });
    }
});

// File Serving Endpoint
app.get('/files/*', (req, res) => {
    const relativePath = req.params[0];
    const baseDir = '\\\\192.168.13.30\\c$\\GGN Office Repository';
    const filePath = path.join(baseDir, relativePath);

    if (!filePath.startsWith(baseDir)) {
        return res.status(400).send("Invalid file path.");
    }

    res.sendFile(filePath, (err) => {
        if (err) {
            console.error("File send error:", err);
            res.status(500).send("Error retrieving file.");
        }
    });
});

// Server Configuration
const PORT = process.env.PORT || 3006;
app.listen(PORT, '192.168.7.103', () => {
    console.log(`Server running at http://192.168.7.103:${PORT}`);
});

module.exports = app;   this is working fine for pdfs but if there are docs also .....so skip docs ...also chck if two pdfs has same name but they have differnt or same folders ...dispaly only once...if pdfnames are same