
//---------------------------------------//LOAD TOOLS//---------------------------------------//


const express = require('express');
const mongoose = require('mongoose');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');

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


//---------------------------------------//CONNECT TO SCHOOL DATABASE//---------------------------------------//


//const dbServerAddress = "mongodb://192.168.131.172:27017/manfa940_database";
const dbServerAddress = "mongodb://manfa940:Dm29070@$@192.168.131.172:27017/manfa940_database?authSource=admin";
const dbLocalAddress = "mongodb://127.0.0.1:27017/manfa940_database";
const mySecretKey = "super_secret_key_123"; 

mongoose.connect(dbServerAddress)
  .then(() => console.log("Success: Connected to School Server!"))
  .catch(err => console.log("Error: Could not connect", err));


//---------------------------------------//SCHEMAS//---------------------------------------//


// User (Name, Password, and Money)

const userSchema = new mongoose.Schema({
  username: { type: String, required: true },
  password: { type: String, required: true },
  balance: { type: Number, default: 50 } 
});


// Plant

const plantSchema = new mongoose.Schema({
  owner: mongoose.Schema.Types.ObjectId,
  type: String,
  sequence: String, // Random code to remember
  quality: { type: Number, default: 0 } 
});

const User = mongoose.model('User', userSchema);
const Plant = mongoose.model('Plant', plantSchema);


//---------------------------------------//SECURITY CHECK//---------------------------------------//


// Checks if user is logged in

const checkLogin = (req, res, next) => {
  const token = req.headers['authorization']?.split(' ')[1];
  
  if (!token) return res.send("You are not logged in!");

  jwt.verify(token, mySecretKey, (err, data) => {
    if (err) return res.send("Token is bad!");
    req.userId = data.id;
    next();
  });
};


//---------------------------------------//GAME ACTIONS//---------------------------------------//


// Create Account

app.post('/register', async (req, res) => {
  const pass = await bcrypt.hash(req.body.password, 10);
  const newUser = new User({ username: req.body.username, password: pass });
  await newUser.save();
  res.send("Account created!");
});


// Login

app.post('/login', async (req, res) => {
  const findUser = await User.findOne({ username: req.body.username });
  if (!findUser) return res.send("User not found");

  const checkPass = await bcrypt.compare(req.body.password, findUser.password);
  if (!checkPass) return res.send("Wrong password");

  const myToken = jwt.sign({ id: findUser._id }, mySecretKey);
  res.json({ token: myToken });
});


// Plant a flower (Costs $10)

app.post('/plant', checkLogin, async (req, res) => {
  const player = await User.findById(req.userId);
  if (player.balance < 10) return res.send("You are too poor!");

  // Random 6 letter code
  let code = "";
  let letters = "1234";
  for (let i = 0; i < 7; i++) {
    code += letters.charAt(Math.floor(Math.random() * 7));
  }

  const newPlant = new Plant({ owner: req.userId, type: "Fern", sequence: code });
  player.balance = player.balance - 10;
  
  await player.save();
  await newPlant.save();

  res.json({ msg: "Planted! Remember this code:", code: code });
});


// Grow plant by typing code

app.post('/grow/:id', checkLogin, async (req, res) => {
  const myPlant = await Plant.findById(req.params.id);
  const userTyped = req.body.typedCode;


  // Check how many letters are correct

  let score = 0;
  if (userTyped[0] === myPlant.sequence[0]) score++;
  if (userTyped[1] === myPlant.sequence[1]) score++;
  if (userTyped[2] === myPlant.sequence[2]) score++;
  if (userTyped[3] === myPlant.sequence[3]) score++;
  if (userTyped[4] === myPlant.sequence[4]) score++;
  if (userTyped[5] === myPlant.sequence[5]) score++;
  if (userTyped[6] === myPlant.sequence[6]) score++;

  myPlant.quality = score / 7;
  await myPlant.save();
  res.send("Growth finished! Quality is: " + myPlant.quality);
});


// Sell plant for money

app.post('/sell/:id', checkLogin, async (req, res) => {
  const myPlant = await Plant.findById(req.params.id);
  

  // Money earned is $20 (profit from base price) * quality
  
  let moneyEarned = 20 * myPlant.quality;

  const player = await User.findById(req.userId);
  player.balance = player.balance + moneyEarned;

  await player.save();
  await Plant.deleteOne({ _id: req.params.id });

  res.send("Sold! You got $" + moneyEarned);
});


//---------------------------------------//START SERVER//---------------------------------------//


app.listen(3000, () => {
  console.log("Game is running on port 3000");
});

