const db = require("../db");
const path = require("path");
const { rgb } = require("pdf-lib");
const { addWatermark } = require("../utils/pdfWatermark");
const { createCreditPdf } = require("../utils/creditPdf");

exports.openInvoices = async (req, res) => {
  try {
    const [rows] = await db.promise().query(`
  SELECT 
    i.id,
    i.invoice_date,
    i.total_amount,
    i.status,
    p.firstname,
    p.lastname
  FROM invoices i
  JOIN patients p ON p.id = i.patient_id
  WHERE i.status = 'open'
  ORDER BY i.invoice_date DESC
`);
    const invoices = rows.map((inv) => {
      let formattedDate = "";

      if (inv.invoice_date) {
        let dateObj;

        // Falls String aus DB
        if (typeof inv.invoice_date === "string") {
          dateObj = new Date(inv.invoice_date + "T00:00:00");
        }

        // Falls Date-Objekt
        else if (inv.invoice_date instanceof Date) {
          dateObj = inv.invoice_date;
        }

        if (dateObj && !isNaN(dateObj)) {
          formattedDate = dateObj.toLocaleDateString("de-DE", {
            day: "2-digit",
            month: "2-digit",
            year: "numeric",
          });
        }
      }

      return {
        ...inv,
        invoice_date_formatted: formattedDate,
        total_amount_formatted: Number(inv.total_amount || 0).toFixed(2),
      };
    });

    res.render("invoices/open-invoices", {
      // ✅ wichtig für Layout
      title: "Offene Rechnungen",
      active: "open_invoices",
      sidebarPartial: "partials/sidebar-invoices",

      user: req.session.user,
      invoices,
    });
  } catch (err) {
    console.error("❌ openInvoices Fehler:", err);
    res.status(500).send("Fehler beim Laden der offenen Rechnungen");
  }
};

// Als bezahlt markieren
exports.markAsPaid = async (req, res) => {
  try {
    const id = req.params.id;
    const userId = req.session.user.id;

    // PDF-Pfad holen
    const [[invoice]] = await db
      .promise()
      .query("SELECT file_path FROM invoices WHERE id = ?", [id]);

    await db.promise().query(
      `
      UPDATE invoices
      SET 
        status='paid',
        paid_at = NOW(),
        paid_by = ?
      WHERE id = ?
      `,
      [userId, id],
    );

    // Wasserzeichen setzen
    if (invoice?.file_path) {
      const fullPath = path.join(__dirname, "..", "public", invoice.file_path);

      await addWatermark(
        fullPath,
        "BEZAHLT",
        rgb(0, 0.7, 0), // Grün
      );
    }

    res.redirect("/invoices/open");
  } catch (err) {
    console.error("❌ markAsPaid:", err);
    res.status(500).send("Fehler");
  }
};

// Stornieren
exports.cancelInvoice = async (req, res) => {
  try {
    const id = req.params.id;
    const userId = req.session.user.id;

    const [[invoice]] = await db
      .promise()
      .query("SELECT file_path FROM invoices WHERE id = ?", [id]);

    await db.promise().query(
      `
      UPDATE invoices
      SET 
        status='cancelled',
        cancelled_at = NOW(),
        cancelled_by = ?
      WHERE id = ?
      `,
      [userId, id],
    );

    // Wasserzeichen setzen
    if (invoice?.file_path) {
      const fullPath = path.join(__dirname, "..", "public", invoice.file_path);

      await addWatermark(
        fullPath,
        "STORNIERT",
        rgb(0.8, 0, 0), // Rot
      );
    }

    res.redirect("/invoices/open");
  } catch (err) {
    console.error("❌ cancelInvoice:", err);
    res.status(500).send("Fehler");
  }
};

// Stornierte Rechnungen anzeigen
exports.cancelledInvoices = async (req, res) => {
  try {
    // Jahr aus Query (?year=2024)
    const year = req.query.year || new Date().getFullYear();

    const [rows] = await db.promise().query(
      `
      SELECT 
        i.id,
        i.invoice_date,
        i.total_amount,
        p.firstname,
        p.lastname
      FROM invoices i
      JOIN patients p ON p.id = i.patient_id
      WHERE 
        i.status = 'cancelled'
        AND YEAR(i.invoice_date) = ?
      ORDER BY i.invoice_date DESC
      `,
      [year],
    );

    // Formatieren
    const invoices = rows.map((inv) => {
      let formattedDate = "";

      if (inv.invoice_date) {
        let dateObj;

        // Falls String aus DB
        if (typeof inv.invoice_date === "string") {
          dateObj = new Date(inv.invoice_date + "T00:00:00");
        }

        // Falls Date-Objekt
        else if (inv.invoice_date instanceof Date) {
          dateObj = inv.invoice_date;
        }

        if (dateObj && !isNaN(dateObj)) {
          formattedDate = dateObj.toLocaleDateString("de-DE", {
            day: "2-digit",
            month: "2-digit",
            year: "numeric",
          });
        }
      }

      return {
        ...inv,
        invoice_date_formatted: formattedDate,
        total_amount_formatted: Number(inv.total_amount || 0).toFixed(2),
      };
    });

    // verfügbare Jahre laden (für Dropdown)
    const [years] = await db.promise().query(`
      SELECT DISTINCT YEAR(invoice_date) AS year
      FROM invoices
      WHERE status = 'cancelled'
      ORDER BY year DESC
    `);

    res.render("invoices/cancelled-invoices", {
      title: "Stornierte Rechnungen",

      user: req.session.user,
      invoices,

      years: years.map((y) => y.year),
      selectedYear: year,

      sidebarPartial: "partials/sidebar-invoices",
      active: "cancelled_invoices",
    });
  } catch (err) {
    console.error("❌ cancelledInvoices:", err);
    res.status(500).send("Fehler beim Laden der stornierten Rechnungen");
  }
};

// Auflistung bezahlter Rechnungen
exports.paidInvoices = async (req, res) => {
  try {
    const year = parseInt(req.query.year) || new Date().getFullYear();
    const quarter = parseInt(req.query.quarter) || 0;

    let where = `WHERE i.status = 'paid' AND i.type = 'invoice' AND c.id IS NULL`;

    const params = [];

    if (year) {
      where += " AND YEAR(i.invoice_date) = ?";
      params.push(year);
    }

    if (quarter) {
      where += " AND QUARTER(i.invoice_date) = ?";
      params.push(quarter);
    }

    const [rows] = await db.promise().query(
      `
      SELECT 
        i.id,
        i.invoice_date,
        i.total_amount,
        p.firstname,
        p.lastname,
        c.id AS credit_id
      FROM invoices i
      JOIN patients p ON p.id = i.patient_id

      LEFT JOIN invoices c
        ON c.parent_invoice_id = i.id
        AND c.type = 'credit'

      ${where}
      ORDER BY i.invoice_date DESC
      `,
      params,
    );

    // Datum + Betrag formatieren
    const invoices = rows.map((inv) => {
      const d = new Date(inv.invoice_date);

      return {
        ...inv,

        invoice_date_formatted: d.toLocaleDateString("de-DE"),

        total_amount_formatted: Number(inv.total_amount).toFixed(2),
      };
    });

    // Jahre laden
    const [years] = await db.promise().query(`
      SELECT DISTINCT YEAR(invoice_date) AS year
      FROM invoices
      WHERE status='paid'
      ORDER BY year DESC
    `);

    res.render("invoices/paid-invoices", {
      title: "Bezahlte Rechnungen",

      user: req.session.user,
      invoices,

      years: years.map((y) => y.year),
      selectedYear: year,
      selectedQuarter: quarter,

      sidebarPartial: "partials/sidebar-invoices",
      active: "paid_invoices",
      query: req.query,
    });
  } catch (err) {
    console.error("❌ paidInvoices:", err);
    res.status(500).send("Fehler");
  }
};

exports.createCreditNote = async (req, res) => {
  try {
    const invoiceId = req.params.id;
    const userId = req.session.user.id;

    // Originalrechnung
    const [[invoice]] = await db.promise().query(
      `
      SELECT i.*, p.firstname, p.lastname
      FROM invoices i
      JOIN patients p ON p.id = i.patient_id
      WHERE i.id = ? AND i.status = 'paid' AND i.type = 'invoice'
      `,
      [invoiceId],
    );

    if (!invoice) {
      return res.status(400).send("Ungültige Rechnung");
    }
    // Prüfen: Gibt es schon eine Gutschrift?
    const [[existing]] = await db
      .promise()
      .query(
        `SELECT id FROM invoices WHERE parent_invoice_id = ? AND type = 'credit'`,
        [invoiceId],
      );

    if (existing) {
      return res.redirect("/invoices/paid?error=already_credited");
    }

    // Gutschrift anlegen
    const [result] = await db.promise().query(
      `
      INSERT INTO invoices
      (
        type,
        parent_invoice_id,
        patient_id,
        invoice_date,
        total_amount,
        created_by,
        status,
        paid_at,
        paid_by
      )
      VALUES
      ('credit', ?, ?, CURDATE(), ?, ?, 'paid', NOW(), ?)
      `,
      [
        invoice.id,
        invoice.patient_id,
        -Math.abs(invoice.total_amount),
        userId,
        userId,
      ],
    );

    const creditId = result.insertId;

    // PDF erzeugen
    const pdfPath = await createCreditPdf({
      creditId,
      originalInvoice: invoice,
      creditAmount: -Math.abs(invoice.total_amount),
      patient: invoice,
    });

    // PDF-Pfad speichern
    await db
      .promise()
      .query(`UPDATE invoices SET file_path = ? WHERE id = ?`, [
        pdfPath,
        creditId,
      ]);

    res.redirect("/invoices/paid");
  } catch (err) {
    console.error("❌ createCreditNote:", err);
    res.status(500).send("Fehler");
  }
};

exports.creditOverview = async (req, res) => {
  try {
    const year = parseInt(req.query.year) || 0;

    let where = "WHERE c.type = 'credit'";
    const params = [];

    if (year) {
      where += " AND YEAR(c.invoice_date) = ?";
      params.push(year);
    }

    const [rows] = await db.promise().query(
      `
      SELECT
        i.id           AS invoice_id,
        i.invoice_date AS invoice_date,
        i.file_path    AS invoice_file,
        i.total_amount AS invoice_amount,

        c.id           AS credit_id,
        c.invoice_date AS credit_date,
        c.file_path    AS credit_file,
        c.total_amount AS credit_amount,

        p.firstname,
        p.lastname

      FROM invoices c

      JOIN invoices i
        ON i.id = c.parent_invoice_id

      JOIN patients p
        ON p.id = i.patient_id

      ${where}

      ORDER BY c.invoice_date DESC
      `,
      params,
    );

    // Formatieren
    const items = rows.map((r) => {
      const formatDate = (d) =>
        d ? new Date(d).toLocaleDateString("de-DE") : "";

      return {
        ...r,

        invoice_date_fmt: formatDate(r.invoice_date),
        credit_date_fmt: formatDate(r.credit_date),

        invoice_amount_fmt: Number(r.invoice_amount).toFixed(2),
        credit_amount_fmt: Number(r.credit_amount).toFixed(2),
      };
    });

    // Jahre laden
    const [years] = await db.promise().query(`
      SELECT DISTINCT YEAR(invoice_date) AS year
      FROM invoices
      WHERE type='credit'
      ORDER BY year DESC
    `);

    res.render("invoices/credit-overview", {
      title: "Gutschriften-Übersicht",

      user: req.session.user,

      items,

      years: years.map((y) => y.year),
      selectedYear: year,

      sidebarPartial: "partials/sidebar-invoices",
      active: "credits",
    });
  } catch (err) {
    console.error("❌ creditOverview:", err);
    res.status(500).send("Fehler");
  }
};
