let morgan = require("morgan")
let bodyparser = require("body-parser") 
let multer = require('multer')
let path = require("path")
let express = require('express')
const  bcrypt = require('bcrypt')
require("dotenv").config();
const session =  require('express-session')
const passport = require('passport')
const GoogleStrategy = require("passport-google-oauth20").Strategy;

const PORT = 3000

let app =  express()
const db = require("./config/conn")


const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, 'uploads/');
    },
    filename: (req, file, cb) => {
        cb(null, Date.now() + path.extname(file.originalname));
    }
});

const upload = multer({storage:storage});

app.use(bodyparser.urlencoded({extended:true}));
app.use(morgan('tiny'));
app.use(express.static('public'));
app.use(express.static('uploads'))
app.use(
    session({
        secret:'IwillRiasewonderland.09011998TheTechApostle',
        resave:false,
        saveUninitialized:true

    })
)
app.use((req, res, next)=>{
    res.locals.currentPath =  req.path;
    next();
})

app.use(passport.initialize());
app.use(passport.session());
passport.use(
    new GoogleStrategy(
      {
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL: "/auth/google/callback",
      },
      (accessToken, refreshToken, profile, done) => {
        // Here, you can save user details to the database
        return done(null, profile);
      }
    )
  );

passport.serializeUser((user, done)=>done(null, user));
passport.deserializeUser((user, done)=> done(null, user));

app.get("/admin/loginGoogle", (req, res)=>{
    res.send("<a href='/auth/google'>Login with Google</a>")
})

app.get("/auth/google",passport.authenticate('google', {scope: ["profile","email"]}))
app.get("/auth/google/callback", passport.authenticate("google", {failureRedirect:"/"}), (req, res)=>{
    res.redirect("/profile")
});

app.get("/profile", (req, res)=>{
    res.send(`Welcome ${req.user.displayName}`);
});



app.get("/logout", (req,res)=>{
    res.logOut();
    res.redirect("/")
})




app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, "views"));


app.post("/freightservice", upload.single('image'),(req, res)=>{
    if (!req.file) {
        return res.status(400).send('No file uploaded.');
    }
    const {name, description} = req.body;
    const image =  req.file.filename;

    const query = "INSERT INTO freightservice(name, image,description)VALUES(?,?,?)";
    db.query(query, [name, image, description], (err, result)=>{
        if(err){
            console.log(err, 'Failed to insert into freightservices');
        }else{
            console.log(result, "Inserted Successfully");
            res.redirect("/admin/addservices")
        }
    })

})

app.get('/', (req, res)=>{
    const queryCategory = "SELECT * FROM servicecategory GROUP BY name";
    db.query(queryCategory, (err, result)=>{
        if(err){
            console.log('Failed')
        }
        res.render("index", {queryCategory:result});
    })
    
});

app.get('/airfreight',(req,res)=>{
    res.render("airfreight")
})

app.get("/contact", (req,res)=>{
    const {message, status} = req.query
    const queryCategory = "SELECT * FROM servicecategory GROUP BY name";
    db.query(queryCategory, (err, result)=>{
        if(err){
            console.log('Failed')
        }
        res.render("contact", {queryCategory:result, message, status});
    })
})

app.post("/contactUsAuth", async(req,res)=>{
    const {name, email, subject, message} =  req.body
    if(!name || !email || !message || !subject){
       return res.status("400").send('Field Must not Empty');
    }
    enterContact = "INSERT INTO contactUS(name, email, subject, message)VALUES(?,?,?,?)";
    db.query(enterContact, [name,email, subject, message], (err, result)=>{
        if(err){
            res.status(500).send('Failed to insert')
            return res.redirect("/contact?message=Message Failed to Sent&status=error")
        }else{
            return res.redirect("/contact?message=Message Sent Successfully&status=success")
        }
    });
    

})

app.get("/login", (req, res)=>{
    const {message, status} = req.query
    const queryCategory = "SELECT * FROM servicecategory GROUP BY name";
    db.query(queryCategory, (err, result)=>{
        if(err){
            console.log('Failed')
        }
        res.render("login", {queryCategory:result,message, status})
    });
})

function isAunthenticated(req, res, next){
    if(req.session.user){
        return next()
    }else{
        res.redirect("/login")
    }
}

app.get("/blog", (req, res)=>{
    const queryCategory = `
        SELECT 
        freightservice.name, 
        servicecategory.name AS name, 
        MIN(servicecategory.id) AS id, 
        COUNT(freightservice.name) AS name_count
    FROM freightservice
    INNER JOIN servicecategory ON servicecategory.name = freightservice.category
    GROUP BY servicecategory.name, freightservice.name;

  `;

    const queryService = "SELECT name,id, COUNT(name) FROM freightservice  INNER JOIN servicecategory ON servicecategory.name = freightservice.name GROUP BY servicecategory.name";
    db.query(queryCategory, (err, result)=>{
        if(err){
            console.log(err,'Failed')
        }
        res.render("blog", {queryCategory:result});
    })
    
})


app.post("/loginAuth", (req, res)=>{
    const {email, password} =  req.body
    checkUserExist = "SELECT * FROM user WHERE email=?"
    db.query(
        checkUserExist, 
        [email],
        (err, result)=>{
            if(!email || !password){
                return res.redirect("/login?message=Email and Password Field Must not be empty&status=error");
            }
            if(result.length===0){
                return res.redirect("/login?message=Wrong email, check and try again&status=error");
            }
            user = result[0];
            bcrypt.compare(password, user.password, (err, isMatch)=>{
                if(err){
                    return res.redirect("/login?message=Wrong Password Credential, check and try again&status=error");
                }
                req.session.user = user
                res.redirect("admin/");

            })
        }
    )
})

app.get('/getCategory/:id', (req, res)=>{
    const getMainCategory = req.params.id;
    const mainCategory = "SELECT * FROM servicecategory WHERE id=?";
    db.query(mainCategory,[getMainCategory], (err, result)=>{
        if(err){
            console.log('Failed')
        }else{
            if(result.length === 0){
                console.log(err)
            }
            const myNameOfCat = result[0].name;
            const getNameCat = "SELECT * FROM freightservice WHERE name=?";
            db.query(getNameCat, [myNameOfCat], (err, dresult)=>{
                if(err){
                    console.log(err)
                }else{

                    const queryCategory = "SELECT * FROM servicecategory GROUP BY name";
                        db.query(queryCategory, (err, result)=>{
                            if(err){
                                console.log('Failed')
                            }
                            res.render("getCategory", {queryCategory:result,cateName:myNameOfCat, getMainInfo:dresult});
                        })
                    
                    //console.log(dresult)
                    
                }
            })
        }
        
    })
    
});



app.get('/about', (req, res)=>{
    const queryCategory = "SELECT * FROM servicecategory GROUP BY name";
    db.query(queryCategory, (err, result)=>{
        if(err){
            console.log('Failed')
        }
        res.render("about", {queryCategory:result});
    })
   
});

app.get("/admin/",isAunthenticated, async (req, res) => {
    try {
        const query = "SELECT DISTINCT(name), id, description, image FROM freightservice";
        const queryCategory = "SELECT DISTINCT(name) FROM servicecategory";
        const countProduct = "SELECT COUNT(DISTINCT(name)) as count FROM freightservice";

        // Run all queries in parallel
        const [products, categories, countResult] = await Promise.all([
            new Promise((resolve, reject) => db.query(query, (err, result) => err ? reject(err) : resolve(result))),
            new Promise((resolve, reject) => db.query(queryCategory, (err, result) => err ? reject(err) : resolve(result))),
            new Promise((resolve, reject) => db.query(countProduct, (err, result) => err ? reject(err) : resolve(result)))
        ]);

        const productCount = countResult[0].count; // Avoid potential undefined errors

        // Render template with fetched data
        res.render("admin/", { products, productCount, categories });

    } catch (err) {
        console.error("Database error:", err);
        res.status(500).send("Error fetching data");
    }
});


app.get("/admin/removeService/:id", (req, res)=>{
    removeService = req.params.id
    const deleteProduct = "DELETE FROM freightservice WHERE id= ?";
    db.query(deleteProduct, [removeService], (err, result)=>{
        if(err){
            res.status(500).send(err, "Failed to delete servive");
        }else{
        // res.render("admin/")
        res.redirect('admin?message=Services Deleted Successfully');
        }
    })
})
app.get("/admin/addservices", async (req, res)=>{

    try{
        const queryCategory = "SELECT DISTINCT(name) FROM servicecategory";

        const[categories] = await Promise.all([
            new Promise((resolve, reject)=> db.query(queryCategory,(err, result) => err ? reject(err) : resolve(result))),
        ]);
        res.render("admin/addservices", {categories})
    }
    catch(err){
        console.log(err, "Failed to Fecth Data to publish to page")
    }
    
    
})

app.get('/admin/signup', (req,res)=>{
    
    res.render('admin/signup')
})
const UserReg = require("./routes/userRoutes")
// app.post('/admin/signup', async (req,res)=>{
    
// });
app.use("/admin/signup", UserReg);

app.post("/admin/addCategory", (req, res)=>{
    const { name } =  req.body
    const checkQuery = "SELECT * FROM servicecategory WHERE name = ?";
    db.query(checkQuery, [name], (err, results) => {
        if (err) {
            console.error("Database Error:", err);
            return res.status(500).send("Error checking for existing category: " + err);
        }

        // If the category already exists, return an error response
        if (results.length > 0) {
            // return res.redirect("/admin/addservices?error=Category already exists");
            return res.send("<script>alert('Category already exists'); window.location.href='/admin/addservices';</script>");

        }
        
    const query  = "INSERT INTO servicecategory(name, date_created)VALUES(?,?)";
    date_created = new Date()
    db.query(query, [name, date_created],(err, result)=>{
        if(err){
            res.status(500).send(err, 'Failed to send data into the table');
        }
        res.send("<script>alert('Service Category Successfully Added'); window.location.href='../admin/addservices'</script>")
        // res.redirect("../admin/addservices?message=Service Category Successfully Added");
    })
})  
})





app.listen(PORT, ()=>{
    console.log(`Welcome, Application running in port ${PORT}`);
});



