const express = require('express');
const { v4: uuidv4 } = require('uuid');
const config = require('../config');
const emailService = require('../services/emailService');

const router = express.Router();

module.exports = (pool, query) => {
  // Register new user
  router.post('/register', async (req, res, next) => {
    const { email, firstName, lastName } = req.body;
    
    try {
      // Check if user already exists
      const userCheck = await query(
        'SELECT * FROM users WHERE email = $1',
        [email]
      );
      
      if (userCheck.rows.length > 0) {
        return res.status(400).json({ 
          error: true, 
          message: 'User with this email already exists' 
        });
      }
      
      // Create new user
      const result = await query(
        'INSERT INTO users (email, first_name, last_name) VALUES ($1, $2, $3) RETURNING id, email',
        [email, firstName, lastName]
      );
      
      res.status(201).json({
        message: 'User registered successfully',
        user: result.rows[0]
      });
    } catch (error) {
      next(error);
    }
  });
  
  // Request login code
  router.post('/login-request', async (req, res, next) => {
    const { email } = req.body;
    console.log('/login-request')
    console.log(JSON.stringify(config, null, 4))
    try {
      // Check if user exists
      const userResult = await query(
        'SELECT * FROM users WHERE email = $1',
        [email]
      );
      
      if (userResult.rows.length === 0) {
        return res.status(404).json({ 
          error: true, 
          message: 'User not found' 
        });
      }
      
      const user = userResult.rows[0];
      
      // Generate a random 6-digit code
      // Set expiration time (15 minutes from now)
      const authCode = Math.floor(100000 + Math.random() * 900000).toString();
      
      const expiresAt = new Date();
      expiresAt.setMinutes(expiresAt.getMinutes() + 15);
      
      // Create auth record
      const authResult = await query(
        'INSERT INTO authentications (code, expires_at) VALUES ($1, $2) RETURNING id',
        [authCode, expiresAt]
      );
      
      const authId = authResult.rows[0].id;
      
      // Update user with auth record
      await query(
        'UPDATE users SET current_auth_id = $1 WHERE id = $2',
        [authId, user.id]
      );
      
      const loginLink = `${config.site.protocol}://${config.site.domain}/verify?code=${authCode}&email=${encodeURIComponent(email)}`;
      
      try {
        await emailService.sendLoginCodeEmail({
          to: email,
          code: authCode,
          loginLink: loginLink
        });
      } catch (emailError) {
        console.error('Failed to send login code email:', emailError);
      }
      let retObj = { 
        message: 'Login code sent to address: ' + email
      }

      if(process.env.ENVIRONMENT === "beta"){
        retObj.code = authCode;
      }
      
      res.json(retObj);
    } catch (error) {
      next(error);
    }
  });
  
  // Verify login code
  router.post('/verify', async (req, res, next) => {
    const { email, code } = req.body;
    
    try {
      // Get user and auth record
      const userResult = await query(
        `SELECT u.*, a.code, a.expires_at, a.is_used 
         FROM users u 
         JOIN authentications a ON u.current_auth_id = a.id 
         WHERE u.email = $1`,
        [email]
      );
      
      if (userResult.rows.length === 0) {
        return res.status(400).json({ 
          error: true, 
          message: 'Invalid request or no login code requested' 
        });
      }
      
      const { code: storedCode, expires_at, is_used, id: userId, is_disabled } = userResult.rows[0];
      // Check if account is disabled
      if (is_disabled) {
        return res.status(403).json({
          error: true,
          message: 'Your account has been disabled. Please contact support for assistance.'
        });
      }
      // Check code
      if (storedCode !== code) {
        return res.status(400).json({ 
          error: true, 
          message: 'Invalid code' 
        });
      }
      
      // Check if expired
      if (new Date() > new Date(expires_at)) {
        return res.status(400).json({ 
          error: true, 
          message: 'Code has expired, Please restart login' 
        });
      }
      
      // Check if already used
      if (is_used) {
        return res.status(400).json({ 
          error: true, 
          message: 'Code has already been used' ,
          data: is_used
        });
      }
      
      // Mark auth as used
      await query(
        'UPDATE authentications SET is_used = true WHERE code = $1',
        [code]
      );
      
      // Generate API key
      const apiKey = uuidv4();
      
      // Save API key to user
      await query(
        'UPDATE users SET api_key = $1, last_login = NOW() WHERE id = $2',
        [apiKey, userId]
      );
      
      // Get user information including admin status
      const userInfo = await query(
        'SELECT id, email, first_name, last_name, is_admin FROM users WHERE id = $1',
        [userId]
      );
      
      res.json({ 
        message: 'Login successful',
        userId: userId,
        isAdmin: userInfo.rows[0].is_admin,
        firstName: userInfo.rows[0].first_name,
        lastName: userInfo.rows[0].last_name,
        email: userInfo.rows[0].email,
        apiKey: apiKey
      });
    } catch (error) {
      next(error);
    }
  });
  //apikey check
  router.post('/verify-key', async (req, res, next) => {
    const { apiKey, email } = req.body;
    
    try {
      // Verify the API key against email
      const result = await query(
        'SELECT id, email, first_name, last_name, is_admin, is_disabled FROM users WHERE api_key = $1 AND email = $2',
        [apiKey, email]
      );
      
      if (result.rows.length === 0) {
        return res.status(401).json({
          error: true,
          message: 'Invalid API key'
        });
      }
      if (result.rows[0].is_disabled) {
        return res.status(403).json({
          error: true,
          message: 'Your account has been disabled. Please contact support for assistance.'
        });
      }
      
      res.json({
        valid: true,
        user: result.rows[0]
      });
    } catch (error) {
      next(error);
    }
  });
  // Logout
  router.post('/logout', async (req, res, next) => {
    const { userId } = req.body;
    
    try {
      // Get current auth ID
      const userResult = await query(
        'SELECT current_auth_id FROM users WHERE id = $1',
        [userId]
      );
      
      if (userResult.rows.length === 0) {
        return res.status(404).json({ 
          error: true, 
          message: 'User not found' 
        });
      }
      
      const authId = userResult.rows[0].current_auth_id;
      
      // Clear auth ID and API key
      await query(
        'UPDATE users SET current_auth_id = NULL, api_key = NULL WHERE id = $1',
        [userId]
      );
      
      // Delete auth record
      if (authId) {
        await query(
          'DELETE FROM authentications WHERE id = $1',
          [authId]
        );
      }
      
      res.json({ message: 'Logged out successfully' });
    } catch (error) {
      next(error);
    }
  });
  
  return router;
};