const express = require('express');
const router = express.Router();

// Importă conexiunea la baza de date
const pool = require('../db'); 

// Importă middleware-ul de autentificare
const authenticateToken = require('../middleware/auth');

// Endpoint pentru a obține produsele - protejează ruta cu middleware-ul de autentificare
router.post('/', async (req, res) => {
    const { 
        id_firma, 
        id_furnizor, 
        id_punct, 
        data_document,
        id_intrare,
        numar_int,
        document_int,
        produse,
        username, 
        totalAchizitie,
        totalAchizitiecutva,
        totalAchizitieFaraTva, 
        tvaAchizitie9, 
        tvaAchizitie19,
        continueProcess 
    } = req.body;

    try {
        // 🔹 Verifică dacă factura există deja în baza de date (după id_furnizor, document_int și numar_int)
        const [existingRecepit] = await pool.promise().query(
            `SELECT * FROM avize WHERE id_furnizor = ? AND document_int = ? AND numar_int = ?`,
            [id_furnizor, document_int, numar_int]
        );

        if (existingRecepit.length > 0) {
            return res.status(400).json({ message: 'Factura există în baza de date' });
        }

        // 🔹 Dacă factura există și utilizatorul nu a confirmat continuarea
        if (!continueProcess && existingRecepit.length > 0) {
            return res.status(400).json({
                message: 'Numărul avizului există. Doriți să continuați?',
                continue: false
            });
        }

        // 🔹 Inserare în tabelul `facturi`
        const [facturiResult] = await pool.promise().query(
            `INSERT INTO avize 
             (id_firma, id_furnizor, id_punct, data_document, document_int, numar_int, id_intrare, username,
              total_vanzare, total_vanzare_cu_tva, 
              tva_vanzare_9, tva_vanzare_19)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [id_firma, id_furnizor, id_punct, data_document, document_int, numar_int, id_intrare, username,
            totalAchizitie, totalAchizitiecutva, 
              tvaAchizitie9, tvaAchizitie19]
        );

        const id_factura = facturiResult.insertId;

        // 🔹 Inserare produse în `facturi_produse`
        const insertProductsQuery = `
            INSERT INTO avize_produse 
            (id_factura, barcode, denumire, cantitate, pret_unitar, pret_vanzare, 
             unitate_masura, valoare_tva, valoare, id_produs)
            VALUES ?
        `;

        // Construim array-ul de valori pentru inserare
        const values = produse.map(produs => [
            id_factura,
            produs.barcode,
            produs.denumire,
            produs.cantitate,
            produs.pret_unitar,
            produs.pret_vanzare,
            produs.unitate_masura,
            produs.valoare_tva,
            produs.valoare,
            produs.id_produs
        ]);

        if (values.length > 0) {
            await pool.promise().query(insertProductsQuery, [values]);
        }

        // 🔹 Actualizare `serii_documente`
        await pool.promise().query(
            `UPDATE serii_documente SET ultimul_numar = ? WHERE id_serie = ?`,
            [numar_int, id_intrare]
        );
// 🔹 Actualizare coloana price_fact în tabelul products
if (produse.length > 0) {
    const updatePromises = produse.map(produs => {
        return pool.promise().query(
            `UPDATE products SET price_fact = ? WHERE id = ?`,
            [produs.pret_unitar, produs.id_produs]
        );
    });

    await Promise.all(updatePromises);
}

        // 🔹 Construim id_document și inserăm în `raport_gestiune`
        const id_document = `${document_int}_${numar_int}`;
        await pool.promise().query(
            `INSERT INTO raport_gestiune (id_document, data_document, nr_document, val_iesire)
             VALUES (?, ?, ?, ?)`,
            [id_document, data_document, numar_int, totalAchizitie]
        );

        res.status(201).json({ message: 'Avizul a fost salvată cu succes!' });

    } catch (err) {
        console.error(err.message);
        res.status(500).json({ error: 'Eroare la salvarea Avizului' });
    }
});





router.all('/print_factura', async (req, res) => {
    try {
        let { document_int, numar_int, continueProcess } = req.method === 'POST' ? req.body : req.query;

        // Validăm parametrii primiți
        if (!document_int || !numar_int) {
            return res.status(400).json({ error: 'Lipsesc parametrii necesari: document_int și numar_int' });
        }

        console.log(`Cerere pentru document_int: ${document_int}, numar_int: ${numar_int}`);

        // Creăm id_document pentru interogare
        const id_document = `${document_int}_${numar_int}`;

        // Căutăm recepția în baza de date
        const [facturi] = await pool.promise().query(
            `SELECT * FROM avize WHERE CONCAT(document_int, '_', numar_int) = ?`,
            [id_document]
        );

        if (facturi.length === 0) {
            console.warn(`Receptia cu ID ${id_document} nu a fost găsită în baza de date.`);
            return res.status(404).json({ message: 'Avizul nu există în baza de date' });
        }

        const receptie = facturi[0]; // Obținem prima înregistrare
        const id_factura = receptie.id_factura;

        // Extragem produsele aferente facturii
        const [produse] = await pool.promise().query(
            `SELECT * FROM avize_produse WHERE id_factura = ?`,
            [id_factura]
        );

        console.log(`Găsite ${produse.length} produse pentru factura cu ID ${id_factura}`);

        // Trimitem datele ca răspuns
        return res.status(200).json({
          receptie,
            produse
        });

    } catch (err) {
        console.error('Eroare la interogarea bazei de date:', err);
        return res.status(500).json({ error: 'Eroare internă a serverului' });
    }
});

router.get('/facturi/:id_furnizor', async (req, res) => {
    try {
        const { id_furnizor } = req.params;

        // Verifică dacă furnizorul există
        const [furnizor] = await pool.promise().query(
            'SELECT * FROM furnizori WHERE id_furnizor = ?',
            [id_furnizor]
        );

        if (!furnizor || furnizor.length === 0) {
            return res.status(404).json({ error: "Furnizorul nu există!" });
        }

        // Selectează toate facturile furnizorului
        const [facturi] = await pool.promise().query(
            'SELECT * FROM avize WHERE id_furnizor = ?',
            [id_furnizor]
        );

        // 🛠️ DEBUGGING - Verificăm ce returnează baza de date
        console.log(`Tipul lui facturi:`, typeof facturi); // Ar trebui să fie 'object'
        console.log(`Este facturi un array?`, Array.isArray(facturi)); // Trebuie să fie TRUE
        console.log(`Facturi găsite pentru furnizor ${id_furnizor}:`, JSON.stringify(facturi, null, 2));

        if (!facturi || facturi.length === 0) {
            return res.status(404).json({ error: "Nu există facturi pentru acest furnizor!" });
        }

        res.status(200).json(facturi); // Trimite toate facturile corect
    } catch (error) {
        console.error('Eroare la interogarea bazei de date:', error);
        res.status(500).json({ error: 'Eroare server!' });
    }
});
// Endpoint pentru a obține următorul id_factura
router.get('/next-id-factura', async (req, res) => {
    try {
        const [rows] = await pool.promise().query('SELECT MAX(id_factura) as lastId FROM avize');
        const nextId = (rows[0].lastId || 0); // Dacă nu există înregistrări, începe de la 1
        
        res.json({ nextId });
    } catch (error) {
        console.error('Eroare la extragerea ultimului ID:', error);
        res.status(500).json({ error: 'Eroare la server' });
    }
});
router.put('/:id', async (req, res) => {
    const { 
        id_firma, 
        id_furnizor, 
        numar_document, 
        id_punct, 
        data_document,
        id_intrare,
        document_int,
        numar_int,
        produse, 
       username,
        totalVanzare, 
        totalVanzareFaraTva, 
       
        tvaVanzare9, 
        tvaVanzare19 
    } = req.body;

    const id_receptie = req.params.id;

    try {
        // Verificare dacă recepția există
        const [existingRecepit] = await pool.promise().query(
            `SELECT * FROM avize WHERE id_factura = ?`,
            [id_receptie]
        );

        if (existingRecepit.length === 0) {
            return res.status(404).json({ message: 'Avizul nu a fost găsită.' });
        }

        // Actualizare în tabelul `receptii`
        await pool.promise().query(
            `UPDATE avize 
             SET id_firma = ?, id_furnizor = ?, numar_document = ?, id_punct = ?, data_document = ?, id_intrare = ?, username = ?,
                 document_int = ?, numar_int = ?, 
                 total_vanzare = ?, total_vanzare_cu_tva = ?, 
                 tva_vanzare_9 = ?, tva_vanzare_19 = ?
             WHERE id_factura = ?`,
            [
                id_firma, id_furnizor, numar_document, id_punct, data_document, id_intrare, username,
                document_int, numar_int, 
                totalVanzareFaraTva, totalVanzare,
                tvaVanzare9, tvaVanzare19, id_receptie
            ]
        );

        // Ștergere produse existente din `produse_receptie` pentru această recepție
        await pool.promise().query(`DELETE FROM avize_produse WHERE id_factura = ?`, [id_receptie]);

        const insertProductsQuery = `
            INSERT INTO avize_produse 
            (id_factura, barcode, denumire, cantitate, pret_unitar, pret_vanzare, unitate_masura, valoare_tva,  valoare, id_produs)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        `;

        const updateProductsQuery = `
            UPDATE products 
            SET price_fact = ? 
            WHERE id = ?
        `;

        // Inserare noile produse
        for (const produs of produse) {
            const { barcode, denumire, cantitate, pret_unitar, pret_vanzare, unitate_masura, valoare_tva, valoare, id_produs } = produs;

            // Inserare în tabelul `produse_receptie`
            await pool.promise().query(insertProductsQuery, [id_receptie, barcode, denumire, cantitate, pret_unitar, pret_vanzare, unitate_masura, valoare_tva, valoare, id_produs]);

            // Actualizare în tabelul `products`
            await pool.promise().query(updateProductsQuery, [ pret_unitar, id_produs]);
        }

        // Actualizare în tabelul `raport_gestiune`
      
        

        res.status(200).json({ message: 'Recepția a fost actualizată cu succes!' });
    } catch (err) {
        console.error(err.message);
        res.status(500).json({ error: 'Eroare la actualizarea recepției' });
    }
});
router.get('/receptii/data', async (req, res) => {
    const { dataStart, dataEnd } = req.query;

    try {
        // Interogare cu JOIN pentru a adăuga numele furnizorului
        const [receptii] = await pool.promise().query(
            `SELECT r.*, f.denumire AS furnizor_nume
             FROM avize r
             LEFT JOIN furnizori f ON r.id_furnizor = f.id_furnizor
             WHERE r.data_document BETWEEN ? AND ? 
             ORDER BY r.data_document ASC`,
            [dataStart, dataEnd]
        );

        if (receptii.length === 0) {
            return res.status(404).json({ message: 'Nu există recepții pentru perioada selectată.' });
        }

        // Adăugăm produse pentru fiecare recepție
        const [produse] = await pool.promise().query(
            `SELECT * FROM avize_produse WHERE id_factura IN (?)`,
            [receptii.map((receptie) => receptie.id_receptie)]
        );

        // Asociază produsele pentru fiecare recepție
        const receptiiWithProduse = receptii.map(receptie => {
            const produseReceptie = produse.filter(produs => produs.id_receptie === receptie.id_receptie);
            return { ...receptie, produse: produseReceptie };
        });

        res.status(200).json(receptiiWithProduse);
    } catch (err) {
        console.error(err.message);
        res.status(500).json({ error: 'Eroare la preluarea recepțiilor.' });
    }
});
router.get('/avize/:id', async (req, res) => {
    const { id } = req.params;

    try {
        const [receptie] = await pool.promise().query(
            `SELECT * FROM avize WHERE id_factura= ?`,
            [id]
        );

        if (receptie.length === 0) {
            return res.status(404).json({ message: 'Recepția nu a fost găsită.' });
        }

        const [produse] = await pool.promise().query(
            `SELECT * FROM avize_produse WHERE id_factura = ?`,
            [id]
        );

        res.status(200).json({ ...receptie[0], produse });
    } catch (err) {
        console.error(err.message);
        res.status(500).json({ error: 'Eroare la preluarea recepției.' });
    }
});
router.delete('/:id_receptie', async (req, res) => {
    const { id_receptie } = req.params;

    try {
        // Verificare dacă există recepția în baza de date
        const [existingRecepit] = await pool.promise().query(
            `SELECT * FROM avize WHERE id_factura = ?`,
            [id_receptie]
        );

        if (existingRecepit.length === 0) {
            return res.status(404).json({ message: 'Recepția nu a fost găsită în baza de date' });
        }

        // Start Transaction pentru a asigura că toate operațiile sunt realizate cu succes sau nu se face nimic
        await pool.promise().query('START TRANSACTION');

        // 1. Recuperăm produsele asociate acestei recepții pentru a actualiza stocul
        const [produse] = await pool.promise().query(
            `SELECT pr.id_produs, pr.cantitate 
            FROM avize_produse pr
            WHERE pr.id_factura = ?`,
            [id_receptie]
        );

       

        // 3. Ștergem produsele asociate acestei recepții din tabelul `produse_receptie`
        await pool.promise().query(
            `DELETE FROM avize_produse WHERE id_factura = ?`,
            [id_receptie]
        );

       
        // 5. Actualizăm numărul ultimului document în `serii_documente`
        await pool.promise().query(
            `UPDATE serii_documente 
            SET ultimul_numar = (SELECT MAX(numar_int) FROM receptii WHERE id_intrare = ?) 
            WHERE id_serie = ?`,
            [existingRecepit[0].id_intrare, existingRecepit[0].id_intrare]
        );

        // 6. Ștergem recepția propriu-zisă din tabelul `receptii`
        await pool.promise().query(
            `DELETE FROM avize WHERE id_factura = ?`,
            [id_receptie]
        );

        // 7. Commit la tranzacție pentru a aplica toate modificările
        await pool.promise().query('COMMIT');

        res.status(200).json({ message: 'Recepția a fost ștearsă cu succes și toate legăturile au fost actualizate!' });
    } catch (err) {
        // Dacă apare o eroare, facem rollback pentru a nu afecta baza de date
        await pool.promise().query('ROLLBACK');
        console.error(err.message);
        res.status(500).json({ error: 'Eroare la ștergerea recepției și a legăturilor sale' });
    }
});


router.post('/inventar', async (req, res) => {
  const produse = req.body; // array cu stoc, data_inventar și pret

  if (!Array.isArray(produse) || produse.length === 0) {
    return res.status(400).json({ error: 'Trebuie să trimiți o listă de produse!' });
  }

  const connection = await pool.promise().getConnection();
  await connection.beginTransaction();

  try {
    // 1. Preiau seria și ultimul număr pentru INVENTAR
    const [rows] = await connection.query(
      `SELECT ultimul_numar, serie_document 
       FROM serii_documente 
       WHERE nume_document = 'INVENTAR' 
       LIMIT 1`
    );

    if (rows.length === 0) {
      throw new Error("Nu există serie definită pentru documentul INVENTAR!");
    }

    let { ultimul_numar, serie_document } = rows[0];
    ultimul_numar = ultimul_numar + 1; // incrementez numărul

    // Construiesc id_document
    const id_document = `${serie_document}_${ultimul_numar}`;

    // 2. Pregătesc valorile pentru inventar
    const inventarValues = produse.map((produs) => {
      const { id_produs, stoc_scriptic, stoc_faptic, data_inventar, pret_produs } = produs;

      if (
        !id_produs ||
        stoc_scriptic === undefined ||
        stoc_faptic === undefined ||
        !data_inventar ||
        pret_produs === undefined
      ) {
        throw new Error(`Date incomplete pentru produsul ${id_produs}`);
      }

      const diferenta = stoc_faptic - stoc_scriptic;
      const total_valoare_diferenta = diferenta * parseFloat(pret_produs);

      return [
        id_produs,
        stoc_scriptic,
        stoc_faptic,
        diferenta,
        data_inventar,
        pret_produs,
        total_valoare_diferenta,
        ultimul_numar,
        serie_document
      ];
    });

    // 3. Inserare în inventar
    const sqlInventar = `INSERT INTO inventar 
      (id_produs, stoc_scriptic, stoc_faptic, diferenta, data_inventar, pret_produs, total_valoare_diferenta, numar_document, serie_document) 
      VALUES ?`;

    const [inventarResults] = await connection.query(sqlInventar, [inventarValues]);

    // 4. Calculez totalul pentru raport_gestiune
    const totalValoare = inventarValues.reduce((sum, row) => sum + row[6], 0); // col 6 = total_valoare_diferenta
    const dataDocument = produse[0].data_inventar; // presupun că toate au aceeași dată

    // Inserare un singur rând în raport_gestiune
    const sqlRaport = `INSERT INTO raport_gestiune 
      (data_document, id_document, nr_document, val_intrare) 
      VALUES (?, ?, ?, ?)`;

    const [raportResults] = await connection.query(sqlRaport, [
      dataDocument,
      id_document,
      ultimul_numar,
      totalValoare
    ]);

    // 5. Actualizez ultimul_numar în tabelul serii_documente
    await connection.query(
      `UPDATE serii_documente 
       SET ultimul_numar = ? 
       WHERE nume_document = 'INVENTAR'`,
      [ultimul_numar]
    );

    await connection.commit();

    res.status(201).json({
      message: 'Inventarul și raportul de gestiune au fost actualizate cu succes!',
      affectedRowsInventar: inventarResults.affectedRows,
      affectedRowsRaport: raportResults.affectedRows,
      serie_document,
      numar_document: ultimul_numar,
      id_document,
      total_valoare_inventar: totalValoare
    });
  } catch (err) {
    await connection.rollback();
    console.error('Database error:', err);
    res.status(500).json({ error: 'Eroare la actualizarea inventarului și raportului de gestiune.' });
  } finally {
    connection.release();
  }
});


module.exports = router;
