const { getUserByEmail, findOrCreateUserByGoogle } = require('../repositories/userRepository');
const jwt = require("jsonwebtoken");
const { getJwtSecret } = require('../config/jwtSecret');
const passport = require('../config/passport');
const { OAuth2Client } = require('google-auth-library');

// POST /login
const login = async (req, res) => {
  try {
    const { email, password } = req.body;
    console.log('[LOGIN] Request received for email:', email || '(missing)');

    // Validate input
    if (!email || !password) {
      console.log('[LOGIN] 400 - Missing email or password');
      return res.status(400).json({
        success: false,
        message: 'Email and password are required'
      });
    }

    // Get user by email
    const user = await getUserByEmail(email);

    if (!user) {
      console.log('[LOGIN] 401 - No user found for email:', email);
      return res.status(401).json({
        success: false,
        message: 'Invalid email or password'
      });
    }

    // Debug: show status_id (type and value - DB may return string "1" vs number 1)
    console.log('[LOGIN] User found. user_id:', user.user_id, '| status_id:', user.status_id, '(type:', typeof user.status_id, ')');

    // Check if account is active (normalize: DB can return number 1 or string "1")
    const statusId = user.status_id != null ? Number(user.status_id) : null;
    if (statusId !== 1) {
      console.log('[LOGIN] 403 - Account inactive. status_id:', user.status_id, '-> normalized:', statusId, '!== 1');
      return res.status(403).json({
        success: false,
        message: 'Account is inactive'
      });
    }

    // Compare password (plain text comparison as per requirement)
    if (user.password !== password) {
      console.log('[LOGIN] 401 - Password mismatch for user:', user.user_id);
      return res.status(401).json({
        success: false,
        message: 'Invalid email or password'
      });
    }

    // Extract role information (handle role_name or roleName from DB driver)
    const roles = user.roles || [];
    const roleNames = roles.map((role) => (role && (role.role_name ?? role.roleName)) || '');
    const roleIds = roles.map((role) => (role && (role.role_id ?? role.roleId)) != null ? Number(role.role_id ?? role.roleId) : null).filter((id) => id != null);

    // Generate JWT token with all role information
    const token = jwt.sign(
      {
        userId: user.user_id,
        email: user.email_id,
        employeeName: user.employee_name,
        roles: roleNames,
        roleIds: roleIds
      },
      getJwtSecret(),
      {
        expiresIn: process.env.JWT_EXPIRES_IN || "7d"
      }
    );

    console.log('[LOGIN] 200 - Login successful for user_id:', user.user_id, 'email:', user.email_id);
    // Send success response with token
    return res.status(200).json({
      success: true,
      message: 'Login successful',
      token: token,
      user: {
        userId: user.user_id,
        employeeName: user.employee_name,
        email: user.email_id,
        allRoles: roles.map(role => ({
          roleId: role.role_id,
          roleName: role.role_name
        }))
      }
    });

  } catch (error) {
    console.error('[LOGIN] 500 - Error:', error.message, error);
    return res.status(500).json({
      success: false,
      message: 'Internal server error',
      error: error.message
    });
  }
};

// Generate JWT token helper function (used by Google login etc.)
const generateToken = (user) => {
  const roles = user.roles || [];
  const roleNames = roles.map((role) => (role && (role.role_name ?? role.roleName)) || '');
  const roleIds = roles.map((role) => (role && (role.role_id ?? role.roleId)) != null ? Number(role.role_id ?? role.roleId) : null).filter((id) => id != null);

  return jwt.sign(
    {
      userId: user.user_id,
      email: user.email_id,
      employeeName: user.employee_name,
      roles: roleNames,
      roleIds: roleIds
    },
    getJwtSecret(),
    {
      expiresIn: process.env.JWT_EXPIRES_IN || "7d"
    }
  );
};

// Client ID used by the frontend (@react-oauth/google) - token must be verified with this audience
const FRONTEND_GOOGLE_CLIENT_ID = '932347645492-2bl00q52tkh3sd8mc5bq1p7kqrarp2gc.apps.googleusercontent.com';

// POST /auth/google/token - Verify Google ID token (from @react-oauth/google) and return app JWT
const googleToken = async (req, res) => {
  try {
    const { credential } = req.body;

    if (!credential) {
      return res.status(400).json({
        success: false,
        message: 'Google credential is required'
      });
    }

    // Must use the SAME client ID as the frontend (token audience); GOOGLE_CLIENT_ID_WEB overrides if set
    const clientId = process.env.GOOGLE_CLIENT_ID_WEB || FRONTEND_GOOGLE_CLIENT_ID;
    if (!clientId) {
      return res.status(500).json({
        success: false,
        message: 'Google OAuth is not configured'
      });
    }

    const client = new OAuth2Client(clientId);
    const ticket = await client.verifyIdToken({
      idToken: credential,
      audience: clientId
    });
    const payload = ticket.getPayload();
    const { email, name, given_name, family_name, sub } = payload;

    const profile = {
      id: sub,
      emails: [{ value: email }],
      displayName: name || [given_name, family_name].filter(Boolean).join(' ').trim() || 'Google User'
    };

    const user = await findOrCreateUserByGoogle(profile);

    if (user.status_id !== 1) {
      return res.status(403).json({
        success: false,
        message: 'Account is inactive. Please contact administrator to activate your account.'
      });
    }

    const token = generateToken(user);
    const roles = user.roles || [];

    return res.status(200).json({
      success: true,
      message: 'Google login successful',
      token,
      user: {
        userId: user.user_id,
        employeeName: user.employee_name,
        email: user.email_id,
        allRoles: roles.map(role => ({
          roleId: role.role_id,
          roleName: role.role_name
        }))
      }
    });
  } catch (error) {
    console.error('Google token auth error:', error);
    return res.status(401).json({
      success: false,
      message: 'Invalid Google credential or authentication failed',
      error: error.message
    });
  }
};

function isGoogleOAuthRedirectConfigured() {
  return Boolean(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET);
}

// OAuth Google - Initiate authentication
const googleAuth = (req, res, next) => {
  if (!isGoogleOAuthRedirectConfigured()) {
    return res.status(503).json({
      success: false,
      message:
        'Google OAuth (redirect) is not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in SAT_backend/.env.',
    });
  }
  return passport.authenticate('google', {
    scope: ['profile', 'email'],
  })(req, res, next);
};

// OAuth Google - Callback handler
const googleCallback = async (req, res) => {
  try {
    if (!isGoogleOAuthRedirectConfigured()) {
      return res.status(503).json({
        success: false,
        message:
          'Google OAuth (redirect) is not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in SAT_backend/.env.',
      });
    }
    // This middleware handles the OAuth callback
    passport.authenticate('google', { session: false }, async (err, user, info) => {
      if (err) {
        console.error('OAuth error:', err);
        return res.status(500).json({
          success: false,
          message: 'OAuth authentication failed',
          error: err.message
        });
      }

      if (!user) {
        return res.status(401).json({
          success: false,
          message: 'Google authentication failed'
        });
      }

      // Check if account is active
      if (user.status_id !== 1) {
        return res.status(403).json({
          success: false,
          message: 'Account is inactive. Please contact administrator to activate your account.',
          user: {
            userId: user.user_id,
            employeeName: user.employee_name,
            email: user.email_id,
            status: 'inactive'
          }
        });
      }

      // Extract role information
      const roles = user.roles || [];
      const roleNames = roles.map(role => role.role_name);
      const roleIds = roles.map(role => role.role_id);

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

      // Redirect to frontend with token (or return JSON)
      // Option 1: Redirect to frontend with token in query
      const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:3000';
      return res.redirect(`${frontendUrl}/auth/callback?token=${token}&success=true`);

      // Option 2: Return JSON (uncomment if you prefer JSON response)
      // return res.status(200).json({
      //   success: true,
      //   message: 'Google login successful',
      //   token: token,
      //   user: {
      //     userId: user.user_id,
      //     employeeName: user.employee_name,
      //     email: user.email_id,
      //     allRoles: roles.map(role => ({
      //       roleId: role.role_id,
      //       roleName: role.role_name
      //     }))
      //   }
      // });
    })(req, res);
  } catch (error) {
    console.error('Google callback error:', error);
    const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:3000';
    return res.redirect(`${frontendUrl}/auth/callback?success=false&error=${encodeURIComponent(error.message)}`);
  }
};

// OAuth Google - Callback handler (JSON response version)
const googleCallbackJSON = async (req, res) => {
  try {
    if (!isGoogleOAuthRedirectConfigured()) {
      return res.status(503).json({
        success: false,
        message:
          'Google OAuth (redirect) is not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in SAT_backend/.env.',
      });
    }
    passport.authenticate('google', { session: false }, async (err, user, info) => {
      if (err) {
        console.error('OAuth error:', err);
        return res.status(500).json({
          success: false,
          message: 'OAuth authentication failed',
          error: err.message
        });
      }

      if (!user) {
        return res.status(401).json({
          success: false,
          message: 'Google authentication failed'
        });
      }

      // Check if account is active
      if (user.status_id !== 1) {
        return res.status(403).json({
          success: false,
          message: 'Account is inactive. Please contact administrator to activate your account.',
          user: {
            userId: user.user_id,
            employeeName: user.employee_name,
            email: user.email_id,
            status: 'inactive'
          }
        });
      }

      // Generate JWT token
      const token = generateToken(user);
      const roles = user.roles || [];

      return res.status(200).json({
        success: true,
        message: 'Google login successful',
        token: token,
        user: {
          userId: user.user_id,
          employeeName: user.employee_name,
          email: user.email_id,
          allRoles: roles.map(role => ({
            roleId: role.role_id,
            roleName: role.role_name
          }))
        }
      });
    })(req, res);
  } catch (error) {
    console.error('Google callback error:', error);
    return res.status(500).json({
      success: false,
      message: 'Internal server error',
      error: error.message
    });
  }
};

module.exports = { 
  login, 
  googleToken,
  googleAuth, 
  googleCallback, 
  googleCallbackJSON,
  generateToken 
};
