// screens/ProfileScreen.js

import React, { useContext } from 'react';
import { View, StyleSheet, ScrollView, Alert } from 'react-native';
import { Title, Caption, Text, Button } from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { AuthContext } from '../context/AuthContext';
import { useTheme } from 'react-native-paper';

/**
 * Simple Profile Screen Component
 */
const ProfileScreen = ({ navigation }) => {
  const { user, logout } = useContext(AuthContext);
  const theme = useTheme(); // Access the current theme

  // Handler for logout action
  const handleLogout = () => {
    Alert.alert(
      'Logout',
      'Are you sure you want to logout?',
      [
        { text: 'Cancel', style: 'cancel' },
        {
          text: 'Logout',
          style: 'destructive',
          onPress: () => logout(),
        },
      ],
      { cancelable: true }
    );
  };

  return (
    <ScrollView style={[styles.container, { backgroundColor: theme.colors.background }]}>
      {/* User Information Section */}
      <View style={styles.userInfoSection}>
        <Title style={[styles.title, { color: theme.colors.text }]}>{user.name}</Title>
        <Caption style={[styles.caption, { color: theme.colors.text }]}>{user.email}</Caption>
      </View>

      {/* Logout Button */}
      <View style={styles.logoutSection}>
        <Button
          mode="contained"
          icon="logout"
          onPress={handleLogout}
          style={styles.logoutButton}
          contentStyle={styles.buttonContent}
          accessibilityLabel="Logout"
          accessibilityHint="Logs you out of the application"
        >
          Logout
        </Button>
      </View>
    </ScrollView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  userInfoSection: {
    paddingHorizontal: 20,
    paddingVertical: 40,
    alignItems: 'center', // Center the user info
    backgroundColor: 'transparent',
  },
  title: {
    fontSize: 26,
    fontWeight: 'bold',
  },
  caption: {
    fontSize: 16,
    lineHeight: 16,
    marginTop: 5,
  },
  logoutSection: {
    paddingHorizontal: 20,
    marginTop: 30,
    alignItems: 'center', // Center the logout button
  },
  logoutButton: {
    width: '100%', // Make the button stretch across the container
    borderRadius: 5,
    backgroundColor: undefined, // Let the theme handle the color
  },
  buttonContent: {
    height: 50, // Ensures consistent button height
    justifyContent: 'center',
  },
});

export default ProfileScreen;

// models/User.js

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const UserSchema = new mongoose.Schema({
    username: { 
        type: String, 
        required: [true, 'Username is required'], 
        unique: true,
        trim: true
    },
    email: { 
        type: String, 
        required: [true, 'Email is required'], 
        unique: true,
        trim: true,
        lowercase: true,
        match: [/\S+@\S+\.\S+/, 'Email is invalid']
    },
    password: { 
        type: String, 
        required: [true, 'Password is required'], 
        minlength: [6, 'Password must be at least 6 characters long']
    },
    role: { 
        type: String, 
        enum: ['user', 'admin'], 
        default: 'user' 
    },
    desiredPhysique: { 
        type: String, 
        enum: {
            values: ['lean', 'muscular', 'athletic'], 
            message: 'Desired Physique must be either lean, muscular, or athletic'
        }, 
        required: [true, 'Desired Physique is required'] 
    },
    fitnessGoals: {
        type: [String],
        default: []
    },
    dietaryPreferences: {
        type: [String],
        default: []
    },
    dietaryRestrictions: {
        type: [String],
        default: []
    },
}, { timestamps: true });

// Middleware to hash password before saving
UserSchema.pre('save', async function(next) {
    if (!this.isModified('password')) return next();
    try {
        const salt = await bcrypt.genSalt(10);
        this.password = await bcrypt.hash(this.password, salt);
        next();
    } catch(err) {
        next(err);
    }
});

// Method to compare entered password with hashed password
UserSchema.methods.comparePassword = function(candidatePassword) {
    return bcrypt.compare(candidatePassword, this.password);
}

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

// middleware/authMiddleware.js

const jwt = require('jsonwebtoken');
require('dotenv').config(); // Ensure environment variables are loaded

/**
 * Authentication middleware to verify JWT tokens.
 */
const authMiddleware = (req, res, next) => {
    const authHeader = req.header('Authorization');

    if (!authHeader) {
        console.warn('No Authorization header provided.');
        return res.status(401).json({ message: 'No token, authorization denied' });
    }

    // The expected format is "Bearer <token>"
    const parts = authHeader.split(' ');
    if (parts.length !== 2 || parts[0] !== 'Bearer') {
        console.warn('Invalid Authorization header format.');
        return res.status(401).json({ message: 'Token is not valid' });
    }

    const token = parts[1];

    try {
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        req.user = decoded.userId; // Attach user ID to request object
        console.log('Token verified. User ID:', req.user);
        next();
    } catch (err) {
        console.error('Token verification failed:', err);
        res.status(401).json({ message: 'Token is not valid' });
    }
}

module.exports = authMiddleware;

// controllers/authController.js

const jwt = require('jsonwebtoken');
const User = require('../models/User');

/**
 * Helper function to generate JWT
 * @param {String} userId - The user's unique identifier
 * @returns {String} - Signed JWT token
 */
const generateToken = (userId) => {
    return jwt.sign(
        { userId },
        process.env.JWT_SECRET,
        { expiresIn: '1h' }
    );
};

/**
 * @desc    Register a new user
 * @route   POST /api/auth/register
 * @access  Public
 */
const register = async (req, res) => {
    const { username, email, password, desiredPhysique, fitnessGoals, dietaryPreferences, dietaryRestrictions } = req.body;

    try {
        // Validate required fields
        if (!username || !email || !password || !desiredPhysique) {
            return res.status(400).json({ message: 'Please provide username, email, password, and desired physique' });
        }

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

        // Check if email already exists
        existingUser = await User.findOne({ email });
        if (existingUser) {
            return res.status(400).json({ message: 'Email already in use' });
        }

        // Create new user
        const newUser = new User({
            username,
            email,
            password,
            desiredPhysique,
            fitnessGoals: fitnessGoals || [],
            dietaryPreferences: dietaryPreferences || [],
            dietaryRestrictions: dietaryRestrictions || [],
        });

        // Save user to database
        await newUser.save();

        // Generate JWT
        const token = generateToken(newUser._id);

        // Respond with token and success message
        res.status(201).json({ token, message: 'User registered successfully' });
    } catch (err) {
        console.error('Registration error:', err);

        // Handle Mongoose validation errors
        if (err.name === 'ValidationError') {
            const messages = Object.values(err.errors).map(val => val.message);
            return res.status(400).json({ message: messages });
        }

        // Generic server error
        res.status(500).json({ message: 'Server error' });
    }
};

/**
 * @desc    Authenticate user and get token
 * @route   POST /api/auth/login
 * @access  Public
 */
const login = async (req, res) => {
    const { email, password } = req.body; // Using email for login

    try {
        // Validate input
        if (!email || !password) {
            return res.status(400).json({ message: 'Please provide email and password' });
        }

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

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

        // Generate JWT
        const token = generateToken(user._id);

        // Respond with token and success message
        res.json({ token, message: 'Login successful' });
    } catch (err) {
        console.error('Login error:', err);
        res.status(500).json({ message: 'Server error' });
    }
};

module.exports = { register, login };

// server.js

require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const morgan = require('morgan'); // For logging HTTP requests
const helmet = require('helmet'); // For securing HTTP headers
const rateLimit = require('express-rate-limit'); // For rate limiting

const app = express();

// Middleware
app.use(express.json());
app.use(helmet());
app.use(morgan('combined')); // Use 'dev' for development

// CORS Configuration
const allowedOrigins = ['http://localhost:19006', 'http://your-frontend-domain.com']; // Update with your Expo app's origin

app.use(cors({
    origin: function (origin, callback) {
        // Allow requests with no origin (like mobile apps, curl requests)
        if (!origin) return callback(null, true);
        if (allowedOrigins.indexOf(origin) === -1) {
            const msg = 'The CORS policy for this site does not allow access from the specified Origin.';
            return callback(new Error(msg), false);
        }
        return callback(null, true);
    },
    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true,
}));

// Rate Limiting
const authLimiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100, // limit each IP to 100 requests per windowMs
    message: { message: 'Too many requests from this IP, please try again after 15 minutes' },
});

// Apply rate limiting to auth routes
const authRoutes = require('./routes/auth');
app.use('/api/auth', authLimiter, authRoutes);

// Other Routes (Placeholder)
// Ensure that these route files exist and are properly set up
const exerciseRoutes = require('./routes/exercises');
app.use('/api/exercises', exerciseRoutes);

const progressRoutes = require('./routes/progress');
app.use('/api/progress', progressRoutes);

// Health Check Route
app.get('/', (req, res) => {
    res.send('Fitness App Backend');
});

// 404 Handler
app.use((req, res, next) => {
    res.status(404).json({ message: 'Endpoint not found' });
});

// Global Error Handler
app.use((err, req, res, next) => {
    console.error('Global error handler:', err.stack);
    res.status(500).json({ message: 'Server error' });
});

// Connect to MongoDB and Start Server
mongoose.connect(process.env.MONGO_URI, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
})
.then(() => {
    console.log('MongoDB Connected');
    const PORT = process.env.PORT || 5000;
    app.listen(PORT, () => {
        console.log(`Server running on port ${PORT}`);
    });
})
.catch(err => {
    console.error('MongoDB connection error:', err);
});

Error frontend:
 ERROR  TypeError: Cannot read property 'name' of undefined

This error is located at:
    in ProfileScreen (created by SceneView)