const express = require('express');
const mysql = require('mysql2');
const cors = require('cors');

const app = express();
app.use(express.json());
app.use(cors({ origin: 'http://localhost:5173', credentials: true }));

// MySQL Connection Configuration
const db = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '', 
    database: 'school_fees_db'
});

db.connect(err => {
    if (err) {
        console.error('Database connection failed: ' + err.stack);
        return;
    }
    console.log('Connected to MySQL Database.');
});

// ================= 1. AUTHENTICATION ENDPOINTS =================

// REGISTER ENDPOINT
app.post('/api/auth/register', (req, res) => {
    const { username, password } = req.body;
    if (!username || !password) {
        return res.status(400).json({ error: 'Uzuza neza username na password!' });
    }
    db.query('INSERT INTO users (username, password) VALUES (?, ?)', [username, password], (err, result) => {
        if (err) {
            if (err.code === 'ER_DUP_ENTRY') {
                return res.status(400).json({ error: 'Iri zina (Username) ryarafashwe, koresha irindi!' });
            }
            return res.status(500).json({ error: err.message });
        }
        res.json({ message: 'Konti nshya yakozwe neza! Ubu ushobora kwinjira.' });
    });
});

// LOGIN ENDPOINT
app.post('/api/auth/login', (req, res) => {
    const { username, password } = req.body;
    db.query('SELECT * FROM users WHERE username = ? AND password = ?', [username, password], (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        if (results.length > 0) {
            res.json({ message: 'Login successful', username: results[0].username });
        } else {
            res.status(401).json({ error: 'Username cyangwa Password ntabwo ari yo!' });
        }
    });
});

// ================= 2. DASHBOARD SUMMARY ENDPOINT =================
app.get('/api/reports/dashboard-summary', (req, res) => {
    const sqlQuery = `
        SELECT 
            (SELECT COUNT(*) FROM students) AS total_students,
            COALESCE((SELECT SUM(f.Amount) FROM records r JOIN fees f ON r.FeeID = f.FeeID), 0) AS total_expected,
            COALESCE((SELECT SUM(Amount) FROM payments), 0) AS total_collected
    `;
    db.query(sqlQuery, (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        const summary = results[0];
        const total_arrears = summary.total_expected - summary.total_collected;
        res.json({
            totalStudents: summary.total_students,
            totalExpected: summary.total_expected,
            totalCollected: summary.total_collected,
            totalArrears: total_arrears < 0 ? 0 : total_arrears
        });
    });
});

// ================= 3. STUDENTS CRUD =================
app.get('/api/students', (req, res) => {
    db.query('SELECT * FROM students', (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

app.post('/api/students', (req, res) => {
    const { Name, Class } = req.body;
    db.query('INSERT INTO students (Name, Class) VALUES (?, ?)', [Name, Class], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Umunyeshuri yanditswe neza!', id: result.insertId });
    });
});

// ================= 4. INDIVIDUAL STUDENT INVOICE ENDPOINT =================
app.get('/api/students/:id/invoice', (req, res) => {
    const studentId = req.params.id;
    
    const studentSql = `
        SELECT s.StudentID, s.Name, s.Class,
            COALESCE((SELECT SUM(f.Amount) FROM records r JOIN fees f ON r.FeeID = f.FeeID WHERE r.StudentID = s.StudentID), 0) AS TotalRequired,
            COALESCE((SELECT SUM(p.Amount) FROM payments p WHERE p.StudentID = s.StudentID), 0) AS TotalPaid
        FROM students s WHERE s.StudentID = ?`;

    const paymentsSql = `SELECT PaymentID, Amount, Date FROM payments WHERE StudentID = ? ORDER BY PaymentID DESC`;

    const recordsSql = `
        SELECT r.RecordID, r.Term, f.Amount, f.Description 
        FROM records r JOIN fees f ON r.FeeID = f.FeeID 
        WHERE r.StudentID = ?`;

    db.query(studentSql, [studentId], (err, studentRes) => {
        if (err) return res.status(500).json({ error: err.message });
        if (studentRes.length === 0) return res.status(404).json({ error: "Umunyeshuri ntabwo amanyikshijwe!" });

        db.query(paymentsSql, [studentId], (err, paymentsRes) => {
            if (err) return res.status(500).json({ error: err.message });

            db.query(recordsSql, [studentId], (err, recordsRes) => {
                if (err) return res.status(500).json({ error: err.message });

                const info = studentRes[0];
                res.json({
                    studentInfo: info,
                    statement: recordsRes,
                    paymentHistory: paymentsRes,
                    balance: info.TotalRequired - info.TotalPaid
                });
            });
        });
    });
});

// ================= 5. FEES CRUD =================
app.get('/api/fees', (req, res) => {
    db.query('SELECT * FROM fees', (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

app.post('/api/fees', (req, res) => {
    const { Amount, Description } = req.body;
    db.query('INSERT INTO fees (Amount, Description) VALUES (?, ?)', [Amount, Description], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Ifishi y’ishuri yongeweho!', id: result.insertId });
    });
});

// ================= 6. PAYMENTS CRUD =================
app.get('/api/payments', (req, res) => {
    db.query('SELECT p.*, s.Name FROM payments p JOIN students s ON p.StudentID = s.StudentID ORDER BY p.PaymentID DESC', (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

app.post('/api/payments', (req, res) => {
    const { StudentID, Amount } = req.body;
    db.query('INSERT INTO payments (StudentID, Amount) VALUES (?, ?)', [StudentID, Amount], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Ubwishyu bwakiriwe neza!', id: result.insertId });
    });
});

// ================= 7. RECORDS CRUD =================
app.get('/api/records', (req, res) => {
    db.query('SELECT r.RecordID, r.Term, s.Name as StudentName, f.Amount as RequiredAmount, f.Description FROM records r JOIN students s ON r.StudentID = s.StudentID JOIN fees f ON r.FeeID = f.FeeID', (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json(results);
    });
});

app.post('/api/records', (req, res) => {
    const { Term, StudentID, FeeID } = req.body;
    db.query('INSERT INTO records (Term, StudentID, FeeID) VALUES (?, ?, ?)', [Term, StudentID, FeeID], (err, result) => {
        if (err) return res.status(500).json({ error: err.message });
        res.json({ message: 'Ibyo kwishyura byashyizweho!', id: result.insertId });
    });
});

// ================= 8. REPORTS & GENERAL BALANCES =================
app.get('/api/reports/balances', (req, res) => {
    const sqlQuery = `
        SELECT 
            s.StudentID, s.Name, s.Class,
            COALESCE((SELECT SUM(f.Amount) FROM records r JOIN fees f ON r.FeeID = f.FeeID WHERE r.StudentID = s.StudentID), 0) AS TotalRequired,
            COALESCE((SELECT SUM(p.Amount) FROM payments p WHERE p.StudentID = s.StudentID), 0) AS TotalPaid
        FROM students s`;
        
    db.query(sqlQuery, (err, results) => {
        if (err) return res.status(500).json({ error: err.message });
        const report = results.map(row => ({
            ...row,
            Balance: row.TotalRequired - row.TotalPaid
        }));
        res.json(report);
    });
});

app.listen(5000, () => console.log('Backend server running on port 5000'));