const express = require('express');
const Database = require('better-sqlite3');
const validateSepa = require('../utils/sepaValidator');
const { encrypt } = require('../utils/crypto');
const generateVertragsnummer = require('../utils/vertragsnummer');
const createContractPdf = require('../utils/contractPdf');
const sendContractMail = require('../utils/sendContractMail');
const sendAdminMail = require('../utils/sendAdminMail');

const router = express.Router();
const db = new Database('plusfit.db');

/* =========================
   Helper
   ========================= */
function loadActiveContracts() {
    return db.prepare(`
        SELECT *
        FROM vertragsarten
        WHERE aktiv = 1
        ORDER BY betrag ASC
    `).all();
}

/* =========================
   GET /register
   ========================= */
router.get('/', (req, res) => {
    const vertragId = req.query.vertrag || null;

    return res.render('register', {
        vertragsarten: loadActiveContracts(),
        selectedVertrag: vertragId,
        formData: {}
    });
});

/* =========================
   POST /register/create
   ========================= */
router.post('/create', async (req, res) => {
    const u = req.body;
    const vertragsarten = loadActiveContracts();

    /* =========================
       Vertragsdaten laden
       ========================= */
    const contractData = db.prepare(`
        SELECT name, laufzeit, betrag
        FROM vertragsarten
        WHERE id = ? AND aktiv = 1
    `).get(u.vertragsvariante);

    if (!contractData) {
        return res.render('register', {
            vertragsarten,
            selectedVertrag: u.vertragsvariante,
            error: 'Vertragsdaten konnten nicht geladen werden.',
            formData: u
        });
    }

    /* =========================
       Pflicht-Zustimmungen
       ========================= */
    if (!u.agreeConsent || !u.agreeAgb || !u.agreeSepa) {
        return res.render('register', {
            vertragsarten,
            selectedVertrag: u.vertragsvariante,
            error: 'Bitte bestätige alle rechtlichen Hinweise, um fortzufahren.',
            formData: u
        });
    }

    /* =========================
       Formale SEPA-Prüfung
       ========================= */
    const sepaError = validateSepa({
        ibanValue: u.iban,
        bic: u.bic,
        mandatsreferenz: u.mandatsreferenz
    });

    if (sepaError) {
        return res.render('register', {
            vertragsarten,
            selectedVertrag: u.vertragsvariante,
            error: sepaError,
            formData: u
        });
    }

    /* =========================
       Logische Prüfungen
       ========================= */
    const mandatsExists = db.prepare(`
        SELECT id FROM users
        WHERE mandatsreferenz = ?
    `).get(u.mandatsreferenz);

    if (mandatsExists) {
        return res.render('register', {
            vertragsarten,
            selectedVertrag: u.vertragsvariante,
            error: 'Diese Mandatsreferenz ist bereits vergeben.',
            formData: u
        });
    }

    /* =========================
       Vertrags- & Zustimmungsdaten
       ========================= */
    const vertragsnummer = generateVertragsnummer();

    const zustimmungsDatum = new Date().toISOString();
    const zustimmungsIp = (
        req.headers['x-forwarded-for'] ||
        req.socket?.remoteAddress ||
        ''
    ).split(',')[0].trim();

    const vertragsversion = 'v1.0';

    const widerrufBis = new Date();
    widerrufBis.setDate(widerrufBis.getDate() + 14);

    /* =========================
       Verschlüsselung
       ========================= */
    const ibanEncrypted = encrypt(u.iban);
    const bicEncrypted = encrypt(u.bic);

    /* =========================
       SPEICHERN
       ========================= */
    db.prepare(`
        INSERT INTO users (
            vertragsnummer,
            vertragsvariante,

            vorname, nachname,
            strasse, hausnummer, plz, ort, land,
            mobil, telefon, email,

            kontoinhaber, iban, bic, mandatsreferenz,

            zustimmung_agb,
            zustimmung_sepa,
            zustimmung_einverstaendnis,
            zustimmung_datum,
            zustimmung_ip,
            vertragsversion,

            widerruf_moeglich_bis,
            status,
            gesperrt
        ) VALUES (
            ?,?,
            ?,?,
            ?,?,?,?,?,
            ?,?,?,
            ?,?,?,?,
            ?,?,?,?,
            ?,?,
            ?,?,
            0
        )
    `).run(
        vertragsnummer,
        u.vertragsvariante,

        u.vorname, u.nachname,
        u.strasse, u.hausnummer, u.plz, u.ort, u.land,
        u.mobil, u.telefon, u.email,

        u.kontoinhaber,
        ibanEncrypted,
        bicEncrypted,
        u.mandatsreferenz,

        u.agreeAgb ? 1 : 0,
        u.agreeSepa ? 1 : 0,
        u.agreeConsent ? 1 : 0,
        zustimmungsDatum,
        zustimmungsIp,
        vertragsversion,

        widerrufBis.toISOString(),
        'aktiv'
    );

    /* =========================
       Vertrags-PDF
       ========================= */
    const pdfPath = await createContractPdf({
    vertragsnummer,
    vorname: u.vorname,
    nachname: u.nachname,
    vertragName: contractData.name,
    laufzeit: contractData.laufzeit,
    betrag: contractData.betrag,
    datum: zustimmungsDatum,
    ip: zustimmungsIp
});

    /* =========================
       Vertragsmail
       ========================= */
    await sendContractMail({
    email: u.email,
    vorname: u.vorname,
    vertragsnummer,
    vertragName: contractData.name,
    betrag: contractData.betrag,
    datum: zustimmungsDatum,
    pdfPath
});

await sendAdminMail({
    vertragsnummer,
    vorname: u.vorname,
    nachname: u.nachname,
    email: u.email,
    vertragName: contractData.name,
    betrag: contractData.betrag,
    datum: zustimmungsDatum,
    ip: zustimmungsIp
});

    /* =========================
       ERFOLG
       ========================= */
    return res.render('registerSuccess', { vertragsnummer });
});

module.exports = router;
