const express = require('express');
const router = express.Router();
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const jwt = require('jsonwebtoken');
const db = require('./db');
const { generateUniqueId } = require('../shared/utils/crypto');

// Check user session (GET)
router.get('/api/auth/session', (req, res) => {
  const token = req.cookies.token;

  if (!token) {
    return res.json({ userId: null });
  }

  try {
    // Verify the token
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    res.json({ userId: decoded.userId });
  } catch (error) {
    console.error('Invalid token:', error);
    res.status(401).json({ userId: null, error: 'Invalid token' });
  }
});

// Sign in anonymously (POST)
router.post('/api/auth/signin-anonymous', async (req, res) => {
  const userId = generateUniqueId(); // Generate unique ID for anonymous user
  console.error('??????????????? signing-in as anonymous', userId);

  try {
    // Insert the anonymous user into the database (no sensitive data, just ID)
    await db.query('INSERT INTO users (id, provider) VALUES (?, ?)', [
      userId,
      'anonymous',
    ]);

    // Generate JWT token for the anonymous user
    const token = jwt.sign(
      { userId, provider: 'anonymous' },
      process.env.JWT_SECRET,
      { expiresIn: '1h' }
    );

    // Set the JWT in an httpOnly cookie for better security
    res.cookie('token', token, { httpOnly: true, secure: true });
    console.error('!!!!!!!!!!!!!!! signed-in as anonymous', userId, token);

    res.status(200).json({ message: 'Anonymous user signed in' });
  } catch (error) {
    console.error('Error creating anonymous user:', error);
    res.status(500).json({ error: 'Server error' });
  }
});

router.post('/api/auth/refresh-token', (req, res) => {
  const refreshToken = req.cookies.refreshToken;
  if (!refreshToken) return res.status(403).send('Refresh token required');

  // Verify the refresh token and issue a new JWT
  try {
    const decoded = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
    const newToken = jwt.sign(
      { userId: decoded.userId },
      process.env.JWT_SECRET,
      { expiresIn: '1h' }
    );
    res.cookie('token', newToken, { httpOnly: true, secure: true });
    res.json({ message: 'Token refreshed' });
  } catch (error) {
    res.status(403).send('Invalid refresh token');
  }
});

// Initialize Passport
router.use(passport.initialize());

// Google OAuth Strategy
passport.use(
  new GoogleStrategy(
    {
      clientID: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      callbackURL: process.env.GOOGLE_REDIRECT_URI,
    },
    async (accessToken, refreshToken, profile, done) => {
      const googleId = profile.id; // This is the unique ID from Google

      try {
        // Insert the Google user into the database if they don't exist
        await db.query(
          'INSERT INTO users (id, provider) VALUES (?, ?) ON DUPLICATE KEY UPDATE id = id',
          [googleId, 'google']
        );

        // Generate JWT token for the Google user
        const token = jwt.sign(
          { userId: googleId, provider: 'google' },
          process.env.JWT_SECRET,
          { expiresIn: '1h' }
        );

        // Pass the token back
        return done(null, token);
      } catch (error) {
        return done(error);
      }
    }
  )
);

// Start Google OAuth login
router.get(
  '/api/auth/google',
  passport.authenticate('google', { scope: ['profile', 'email'] })
);

// Callback route for Google OAuth
router.get(
  '/api/auth/google/callback',
  passport.authenticate('google', { failureRedirect: '/' }),
  (req, res) => {
    // After successful authentication, generate the JWT (which is in req.user)
    const token = req.user; // Passport's Google strategy should return the JWT

    // Set the JWT in an httpOnly cookie
    res.cookie('token', token, { httpOnly: true, secure: true });

    // Redirect to the frontend dashboard or a secure page without the token in the URL
    res.redirect('/dashboard');
  }
);

// Example of a protected route (no neeaxios.d for query token)
router.get('/dashboard', (req, res) => {
  // Extract token from cookies (JWT is automatically sent as a cookie)
  const token = req.cookies.token;

  if (!token) {
    return res.status(403).send('Token is required');
  }

  try {
    // Verify the token and decode it
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    res.send(`Welcome, user with ID: ${decoded.userId}`);
  } catch (err) {
    res.status(403).send('Invalid token');
  }
});

module.exports = router;
