import "dotenv/config";
import express from "express";
import mysql from "mysql2/promise";

// Create a connection pool to MySQL
const pool = mysql.createPool({
    host: process.env.DB_HOST || "localhost",
    user: process.env.DB_USER || "root",
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME || "roadrentals",
    waitForConnections: true,
    connectionLimit: 10,
    queueLimit: 0
});

const app = express();
app.use(express.json());

const checkToken = (req, res, next) => {
    console.log("Welcome");
    next();
};

app.use(checkToken);

app.get("/", (req, res) => {
    res.json({ status: 1, message: "Home Page API" });
});

app.get("/api/news", (req, res) => {
    res.json({ status: 1, message: "News API" });
});

// Database Connected Endpoint
app.post("/api/auth/register", async (req, res) => {
    try {
        const { name, email, mobile_number, password } = req.body;

        if (!name || !email || !mobile_number || !password) {
            return res.status(400).json({ detail: "Missing required fields" });
        }

        // Search the MySQL Database
        const [users] = await pool.execute("SELECT * FROM User WHERE email = ?", [email]);
        const existingUser = users[0];

        if (existingUser) {
            return res.status(409).json({ detail: "Email already registered" });
        }

        // Insert new user row into MySQL table
        const [result] = await pool.execute(
            "INSERT INTO User (name, email, mobile_number, password) VALUES (?, ?, ?, ?)",
            [name, email, mobile_number, password]
        );

        const newUser = {
            id: result.insertId,
            name,
            email,
            mobile_number
        };
        
        return res.status(201).json({ status: 1, message: "User registered successfully", user: newUser });

    } catch (error) {
        console.error("Database Error:", error);
        return res.status(500).json({ detail: "Internal Server Error" });
    }
});

// Create a New Booking
app.post("/api/bookings", async (req, res) => {
    try {
        const { 
            tripType, 
            pickupLocation, 
            dropLocation, 
            pickupDateTime, 
            returnDateTime, 
            packageType, 
            carName, 
            totalAmount 
        } = req.body;

        if (!tripType || !pickupLocation || !pickupDateTime) {
            return res.status(400).json({ detail: "Missing required booking details" });
        }

        const [result] = await pool.execute(
            `INSERT INTO Bookings (trip_type, pickup_location, drop_location, pickup_datetime, return_datetime, package_type, car_name, total_amount) 
             VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
            [
                tripType, 
                pickupLocation, 
                dropLocation || null, 
                new Date(pickupDateTime), 
                returnDateTime ? new Date(returnDateTime) : null, 
                packageType || null, 
                carName || null, 
                totalAmount || null
            ]
        );

        return res.status(201).json({ 
            status: 1, 
            message: "Booking requested successfully!", 
            bookingId: result.insertId 
        });

    } catch (error) {
        console.error("Booking Error:", error);
        return res.status(500).json({ detail: "Failed to create booking" });
    }
});

// --- DYNAMIC PRICING ENGINE (DB DRIVEN) ---
app.post("/api/pricing/calculate", async (req, res) => {
    try {
        const { tripType, pickupDate, returnDate, packageType } = req.body;

        const start = new Date(pickupDate);
        const end = returnDate ? new Date(returnDate) : start;
        const diffTime = Math.abs(end - start);
        const durationDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) || 1;

        // Fetch ACTIVE vehicles from DB
        const [rows] = await pool.execute("SELECT * FROM Vehicles WHERE isAvailable = TRUE");
        
        const results = rows.map(vehicle => {
            const features = typeof vehicle.features === 'string' ? JSON.parse(vehicle.features) : vehicle.features;
            
            let totalBaseFare = vehicle.baseFarePerDay * durationDays;
            let totalDriverAllowance = vehicle.driverAllowancePerDay * durationDays;
            
            // Special Case: Local Packages
            if (tripType === 'local' && packageType) {
                if (packageType.includes("4Hr")) totalBaseFare = 1500;
                else if (packageType.includes("8Hr")) totalBaseFare = 2500;
                else if (packageType.includes("12Hr")) totalBaseFare = 3500;
                totalDriverAllowance = 0; 
            }
            
            // Special Case: Airport Transfers
            if (tripType === 'airport') {
                if (vehicle.type === 'SEDAN') totalBaseFare = 1200;
                else if (vehicle.type === 'SUV') totalBaseFare = 2200;
                else totalBaseFare = 1800;
                totalDriverAllowance = 0;
            }

            const grandTotal = totalBaseFare + totalDriverAllowance;
            const advancePayment = Math.round(grandTotal * 0.20); 

            return {
                ...vehicle,
                features,
                calc: {
                    days: durationDays,
                    baseFare: totalBaseFare,
                    driverAllowance: totalDriverAllowance,
                    totalKmIncluded: vehicle.includedKmPerDay * (tripType === 'airport' ? 0.2 : durationDays),
                    grandTotal,
                    advancePayment,
                    math: tripType === 'airport' || tripType === 'local' 
                        ? `Fixed ${tripType.charAt(0).toUpperCase() + tripType.slice(1)} Rate`
                        : `(₹${vehicle.baseFarePerDay} x ${durationDays} Days) + ₹${totalDriverAllowance} Driver`
                },
                inclusions: ["AC", "Professional Driver", tripType === 'airport' ? "Airport Toll Included" : "First " + (vehicle.includedKmPerDay * (tripType === 'airport' ? 1 : durationDays)) + " Kms"],
                exclusions: ["Parking Charges", "Extra Waiting Time", "Inter-state Permits"]
            };
        });

        res.json({ status: 1, data: results });
    } catch (error) {
        console.error("Pricing Error:", error);
        res.status(500).json({ detail: "Failed to calculate pricing" });
    }
});

// --- ADMIN API ENDPOINTS ---

// Secure Admin Login
app.post("/api/admin/login", async (req, res) => {
    const { adminId, password } = req.body;
    
    // Environment-based credentials for security
    const VALID_ADMIN_ID = process.env.ADMIN_ID || "admin";
    const VALID_ADMIN_PASS = process.env.ADMIN_PASSWORD || "admin123";

    if (adminId === VALID_ADMIN_ID && password === VALID_ADMIN_PASS) {
        res.json({ success: true, token: "secure_session_token_xyz_987" });
    } else {
        res.status(401).json({ detail: "Invalid Admin ID or Password" });
    }
});

// Get Full Fleet for Management
app.get("/api/admin/vehicles", async (req, res) => {
    try {
        const [rows] = await pool.execute("SELECT * FROM Vehicles ORDER BY id DESC");
        const cars = rows.map(v => ({
            ...v,
            features: typeof v.features === 'string' ? JSON.parse(v.features) : v.features
        }));
        res.json(cars);
    } catch (err) {
        res.status(500).json({ detail: "Fail to fetch fleet" });
    }
});

// Update Availability or Pricing
app.patch("/api/admin/vehicles/:id", async (req, res) => {
    try {
        const { id } = req.params;
        const { baseFarePerDay, isAvailable } = req.body;

        if (baseFarePerDay !== undefined) {
            await pool.execute("UPDATE Vehicles SET baseFarePerDay = ? WHERE id = ?", [baseFarePerDay, id]);
        }
        if (isAvailable !== undefined) {
            await pool.execute("UPDATE Vehicles SET isAvailable = ? WHERE id = ?", [isAvailable, id]);
        }

        res.json({ success: true, message: "Vehicle updated successfully" });
    } catch (err) {
        res.status(500).json({ detail: "Failed to update vehicle" });
    }
});

// Add New Cab
app.post("/api/admin/vehicles", async (req, res) => {
    try {
        const v = req.body;
        const features = JSON.stringify(v.features || []);
        
        await pool.execute(
            `INSERT INTO Vehicles (name, type, seats, luggage, image, baseFarePerDay, driverAllowancePerDay, extraKmRate, includedKmPerDay, badge, features) 
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
            [v.name, v.type, v.seats, v.luggage, v.image, v.baseFarePerDay, v.driverAllowancePerDay, v.extraKmRate, v.includedKmPerDay, v.badge, features]
        );
        
        res.status(201).json({ success: true, message: "New vehicle added" });
    } catch (err) {
        res.status(500).json({ detail: "Failed to add new vehicle" });
    }
});

// Delete Cab
app.delete("/api/admin/vehicles/:id", async (req, res) => {
    try {
        const { id } = req.params;
        await pool.execute("DELETE FROM Vehicles WHERE id = ?", [id]);
        res.json({ success: true, message: "Vehicle removed" });
    } catch (err) {
        res.status(500).json({ detail: "Failed to delete vehicle" });
    }
});


const PORT = 8000;

app.listen(PORT, () => {
    console.log(`Server running on http://localhost:${PORT}`);
});