const db = require("../db");
const ejs = require("ejs");
const path = require("path");
const htmlToPdf = require("html-pdf-node");
const fs = require("fs");

async function createInvoicePdf(req, res) {
  const patientId = req.params.id;
  const connection = await db.promise().getConnection();

  try {
    await connection.beginTransaction();

    const year = new Date().getFullYear();

    // 🔒 Rechnungszähler sperren
    const [[counterRow]] = await connection.query(
      "SELECT counter FROM invoice_counters WHERE year = ? FOR UPDATE",
      [year]
    );

    let counter;
    if (!counterRow) {
      counter = 1;
      await connection.query(
        "INSERT INTO invoice_counters (year, counter) VALUES (?, ?)",
        [year, counter]
      );
    } else {
      counter = counterRow.counter + 1;
      await connection.query(
        "UPDATE invoice_counters SET counter = ? WHERE year = ?",
        [counter, year]
      );
    }

    const invoiceNumber = `${year}-${String(counter).padStart(4, "0")}`;

    // 🔹 Patient
    const [[patient]] = await connection.query(
      "SELECT * FROM patients WHERE id = ?",
      [patientId]
    );
    if (!patient) throw new Error("Patient nicht gefunden");

    // 🔹 Leistungen
    const [rows] = await connection.query(
      `
      SELECT
        ps.quantity,
        COALESCE(ps.price_override, s.price) AS price,
        s.name_de AS name
      FROM patient_services ps
      JOIN services s ON ps.service_id = s.id
      WHERE ps.patient_id = ?
        AND ps.invoice_id IS NULL
      `,
      [patientId]
    );

    if (!rows.length) throw new Error("Keine Leistungen vorhanden");

    const services = rows.map((s) => ({
      quantity: Number(s.quantity),
      name: s.name,
      price: Number(s.price),
      total: Number(s.price) * Number(s.quantity),
    }));

    const total = services.reduce((sum, s) => sum + s.total, 0);

    // 🔹 Arzt
    const [[doctor]] = await connection.query(
      `
      SELECT first_name, last_name, fachrichtung, arztnummer
      FROM users
      WHERE id = (
        SELECT created_by
        FROM patient_services
        WHERE patient_id = ?
        ORDER BY service_date DESC
        LIMIT 1
      )
      `,
      [patientId]
    );

    // 🔹 Firma
    const [[company]] = await connection.query(
      "SELECT * FROM company_settings LIMIT 1"
    );

    // 🖼 Logo als Base64
    let logoBase64 = null;
    if (company && company.invoice_logo_path) {
      const logoPath = path.join(
        __dirname,
        "..",
        "public",
        company.invoice_logo_path
      );

      if (fs.existsSync(logoPath)) {
        const buffer = fs.readFileSync(logoPath);
        const ext = path.extname(logoPath).toLowerCase();
        const mime =
          ext === ".jpg" || ext === ".jpeg" ? "image/jpeg" : "image/png";

        logoBase64 = `data:${mime};base64,${buffer.toString("base64")}`;
      }
    }

    // 📁 PDF-Pfad vorbereiten
    const invoiceDir = path.join(
      __dirname,
      "..",
      "public",
      "invoices",
      String(year)
    );

    if (!fs.existsSync(invoiceDir)) {
      fs.mkdirSync(invoiceDir, { recursive: true });
    }

    const fileName = `invoice-${invoiceNumber}.pdf`;
    const absoluteFilePath = path.join(invoiceDir, fileName);
    const dbFilePath = `/invoices/${year}/${fileName}`;

    // 🔹 Rechnung speichern
    const [result] = await connection.query(
      `
      INSERT INTO invoices
        (patient_id, invoice_date, file_path, total_amount, created_by, status)
      VALUES (?, CURDATE(), ?, ?, ?, 'open')
      `,
      [patientId, dbFilePath, total, req.session.user.id]
    );

    const invoiceId = result.insertId;

    const invoice = {
      number: invoiceNumber,
      date: new Date().toLocaleDateString("de-DE"),
    };

    // 🔹 HTML rendern
    const html = await ejs.renderFile(
      path.join(__dirname, "../views/invoices/invoice.ejs"),
      {
        patient,
        services,
        total,
        invoice,
        doctor,
        company,
        logoBase64,
      }
    );

    // 🔹 PDF erzeugen
    const pdfBuffer = await htmlToPdf.generatePdf(
      { content: html },
      { format: "A4", printBackground: true }
    );

    // 💾 PDF speichern
    fs.writeFileSync(absoluteFilePath, pdfBuffer);

    // 🔗 Leistungen mit Rechnung verknüpfen
    const [updateResult] = await connection.query(
      `
      UPDATE patient_services
      SET invoice_id = ?
      WHERE patient_id = ?
        AND invoice_id IS NULL
      `,
      [invoiceId, patientId]
    );
    const [[cid]] = await connection.query("SELECT CONNECTION_ID() AS cid");
    console.log("🔌 INVOICE CID:", cid.cid);
    await connection.commit();

    console.log("🔌 INVOICE CID:", cid.cid);
    // 📤 PDF anzeigen
    res.render("invoice_preview", {
      pdfUrl: dbFilePath,
    });
  } catch (err) {
    await connection.rollback();
    console.error("❌ INVOICE ERROR:", err);
    res.status(500).send(err.message || "Fehler beim Erstellen der Rechnung");
  } finally {
    connection.release();
  }
}

module.exports = { createInvoicePdf };
