const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const transactionRoutes = require('./routes/transactionRoutes');
const userRoutes = require('./routes/userRoutes');
const goalRoutes = require('./routes/goalRoutes');
const predictionRoutes = require('./routes/predictionRoutes');
require('dotenv').config();


const app = express(); // Initialize app here
app.use(cors());


app.use(express.json());

// Routes
app.use('/api/transactions', transactionRoutes);
app.use('/api/users', userRoutes);
app.use('/api/goals', goalRoutes);
app.use('/api/predictions', predictionRoutes);

// MongoDB Connection
mongoose.connect(process.env.MONGODB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then(() => {
  console.log('Connected to MongoDB');
}).catch(err => {
  console.error('MongoDB connection error:', err);
});

module.exports = app;



const express = require('express');
const router = express.Router();
const Goal = require('../models/goal');

// Add a new financial goal
router.post('/', async (req, res) => {
  const { userId, goalType, targetAmount, deadline } = req.body;

  try {
    const goal = new Goal({ userId, goalType, targetAmount, deadline });
    await goal.save();
    res.status(201).json(goal);
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

// Get goals for a user
router.get('/:userId', async (req, res) => {
  const { userId } = req.params;

  try {
    const goals = await Goal.find({ userId });
    res.json(goals);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

module.exports = router;

const express = require('express');
const router = express.Router();
const axios = require('axios');

// Get predictions for a user
router.get('/:userId', async (req, res) => {
  const { userId } = req.params;
  // Fetch user's transactions from the database and prepare data for prediction
  // For simplicity, we'll just send a static month
  const month = new Date().getMonth() + 1; // Current month

  try {
    const response = await axios.post('http://localhost:5001/predict', { month });
    res.json([response.data]); // Return as an array for frontend compatibility
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Failed to fetch predictions' });
  }
});

module.exports = router;


const express = require('express');
const mongoose = require('mongoose'); // Import mongoose for ObjectId
const router = express.Router();
const Transaction = require('../models/transaction'); // Adjust the path as needed
const User = require('../models/user'); // Import User model


// Route to add a transaction
router.post('/', async (req, res) => {
  const { userId, category, amount, date } = req.body;

  // Input validation
  if (!userId || !category || typeof amount !== 'number' || !date) {
    return res.status(400).json({ message: 'Invalid input data' });
  }
  // Check if the user exists
  const user = await User.findById(userId);
  if (!user) {
    return res.status(404).json({ message: 'User not found. Please log in again.' });
  }

  const newTransaction = new Transaction({ userId, category, amount, date });

  try {
    // Save the transaction
    const savedTransaction = await newTransaction.save();

    // Update user's current balance
    await User.findByIdAndUpdate(userId, { $inc: { currentBalance: amount } });

    console.log('Transaction saved:', savedTransaction);
    res.status(201).json(savedTransaction);
  } catch (error) {
    console.error('Error saving transaction:', error);
    res.status(500).json({ message: 'Failed to add transaction', error: error.message });
  }
});

// Route to fetch transactions for a user
router.get('/:userId', async (req, res) => {
  const { userId } = req.params;

  // Ensure userId is valid before querying
  if (!mongoose.Types.ObjectId.isValid(userId)) {
    return res.status(400).json({ message: 'Invalid user ID format' });
  }

  try {
    const transactions = await Transaction.find({ userId });
    res.status(200).json(transactions);
  } catch (error) {
    console.error('Error fetching transactions:', error);
    res.status(500).json({ message: 'Failed to fetch transactions', error: error.message });
  }
});

module.exports = router;


const bcrypt = require('bcrypt');
const express = require('express');
const router = express.Router();
const User = require('../models/user'); // Adjust the path to your User model

// Password hashing function
const hashPassword = async (password) => {
  const saltRounds = 10;
  return await bcrypt.hash(password, saltRounds);
};

// User Registration
router.post('/register', async (req, res) => {
  const { name, username, password } = req.body; // Include name

  try {
    // Check if user already exists
    const existingUser = await User.findOne({ username });
    if (existingUser) {
      return res.status(400).json({ message: 'User already exists' });
    }

    // Hash the password
    const hashedPassword = await hashPassword(password);
    
    // Create a new user with name
    const newUser = new User({ name, username, password: hashedPassword });
    await newUser.save();

    res.status(201).json(newUser);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Failed to register user' });
  }
});

// User Login
router.post('/login', async (req, res) => {
  const { username, password } = req.body; // Get username and password from request body
  console.log("Attempting to log in with:", username, password);


  try {
    // Find the user by username
    const user = await User.findOne({ username });
    if (!user) {
      return res.status(400).json({ message: 'Invalid credentials' });
    }

    // Compare hashed password
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) {
      return res.status(400).json({ message: 'Invalid credentials' });
    }

    // If everything is okay, send user data (omit password)
    res.status(200).json({ id: user._id, username: user.username }); // Adjust this based on what you want to return
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Server error' });
  }
});

// Update User Balance
router.post('/updateBalance', async (req, res) => {
  const { userId, amount } = req.body; // Expecting userId and amount in the request body

  try {
    const user = await User.findById(userId);
    if (!user) {
      return res.status(404).json({ message: 'User not found' });
    }

    user.currentBalance += amount; // Update current balance
    await user.save(); // Save the updated user

    res.status(200).json({ currentBalance: user.currentBalance }); // Return updated balance
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Server error' });
  }
});

module.exports = router;



const mongoose = require('mongoose');

const GoalSchema = new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
  goalType: { type: String, required: true }, // e.g., 'savings', 'budget'
  targetAmount: { type: Number, required: true },
  currentProgress: { type: Number, default: 0 },
  deadline: { type: Date }
});

module.exports = mongoose.model('Goal', GoalSchema);


const mongoose = require('mongoose');

const TransactionSchema = new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  category: { type: String, required: true },
  amount: { type: Number, required: true },
  date: { type: Date, required: true }, // Include date
});

module.exports = mongoose.model('Transaction', TransactionSchema);


const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  name: { type: String, required: true },
  username: { type: String, required: true, unique: true }, // Change from email to username
  password: { type: String, required: true },
  currentBalance: { type: Number, default: 0 },
  totalAmount: { type: Number, default: 0 },
  bankAccount: { type: String }
});

const User = mongoose.model('User', userSchema);
module.exports = User;


make a complete vite react app with tailwind  css and good styling to work with this backend also fix all the backend code and give all files with structure and complte code