const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const crypto = require('crypto');
const { supabase } = require('../config/supabase');
const { sendPasswordResetEmail } = require('../services/email');

// POST: credentials - login
exports.credentials = async (req, res) => {
  const { user_name, ps, clientId, nonce } = req.body;

  try {
    // Get user from database (need users table)
    // For now, return mock response matching old API format
    const { data: user, error } = await supabase
      .from('users')
      .select('*')
      .eq('username', user_name)
      .single();

    if (error || !user) {
      return res.status(401).json({ error: 'Invalid credentials' });
    }

    // Verify password
    const validPassword = await bcrypt.compare(ps, user.password_hash);
    if (!validPassword) {
      return res.status(401).json({ error: 'Invalid credentials' });
    }

    // Generate JWT token
    const access_token = jwt.sign(
      {
        username: user_name,
        user_id: user.id,
        role: user.role
      },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN }
    );

    return res.json({
      access_token,
      user_id: user.id,
      role: user.role,
      first_name: user.first_name,
      last_name: user.last_name,
      email: user.email
    });

  } catch (error) {
    console.error('Credentials error:', error);
    return res.status(500).json({ error: error.message });
  }
};

// POST: new_user_form - register new user
exports.newUserForm = async (req, res) => {
  const {
    firstName,
    lastName,
    email,
    password,
    devices,
    agreementDate,
    privacyPolicyVersion,
    phone
  } = req.body;

  try {
    // Hash password
    const password_hash = await bcrypt.hash(password, 10);

    // Generate username from email
    const username = email.split('@')[0];

    // Insert new user
    const { data: user, error } = await supabase
      .from('users')
      .insert({
        username,
        email,
        password_hash,
        first_name: firstName,
        last_name: lastName,
        phone,
        devices: devices ? JSON.parse(devices) : [],
        agreement_date: agreementDate,
        privacy_policy_version: privacyPolicyVersion,
        role: 'beneficiary',
        created_at: new Date().toISOString()
      })
      .select()
      .single();

    if (error) {
      return res.status(400).json({ error: error.message });
    }

    // Generate token for auto-login
    const access_token = jwt.sign(
      {
        username: user.username,
        user_id: user.id,
        role: user.role
      },
      process.env.JWT_SECRET,
      { expiresIn: process.env.JWT_EXPIRES_IN }
    );

    return res.json({
      success: true,
      access_token,
      user_id: user.id
    });

  } catch (error) {
    console.error('New user form error:', error);
    return res.status(500).json({ error: error.message });
  }
};

// POST: forgot_password - request password reset
exports.forgotPassword = async (req, res) => {
  const { email } = req.body;

  if (!email) {
    return res.status(400).json({ error: 'Email is required' });
  }

  try {
    // Find user by email in person_details table
    const { data: user, error: userError } = await supabase
      .from('person_details')
      .select('user_id, email, first_name')
      .eq('email', email)
      .single();

    if (userError || !user) {
      // Don't reveal if email exists or not (security)
      return res.json({
        success: true,
        message: 'If this email exists, a password reset link will be sent'
      });
    }

    // Generate reset token
    const resetToken = crypto.randomBytes(32).toString('hex');
    const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 hour

    // Store reset token in password_resets table
    const { error: insertError } = await supabase
      .from('password_resets')
      .insert({
        user_id: user.user_id,
        token: resetToken,
        expires_at: expiresAt.toISOString()
      });

    if (insertError) {
      console.error('Failed to store reset token:', insertError);
      return res.status(500).json({ error: 'Failed to process request' });
    }

    // Send reset email
    try {
      await sendPasswordResetEmail(email, resetToken);
    } catch (emailError) {
      console.error('Failed to send email:', emailError);
      // Still return success to not reveal email status
    }

    return res.json({
      success: true,
      message: 'If this email exists, a password reset link will be sent'
    });

  } catch (error) {
    console.error('Forgot password error:', error);
    return res.status(500).json({ error: error.message });
  }
};

// POST: reset_password - set new password using token
exports.resetPassword = async (req, res) => {
  const { token, password } = req.body;

  if (!token || !password) {
    return res.status(400).json({ error: 'Token and password are required' });
  }

  if (password.length < 6) {
    return res.status(400).json({ error: 'Password must be at least 6 characters' });
  }

  try {
    // Find valid reset token
    const { data: resetRecord, error: tokenError } = await supabase
      .from('password_resets')
      .select('*')
      .eq('token', token)
      .is('used_at', null)
      .gt('expires_at', new Date().toISOString())
      .single();

    if (tokenError || !resetRecord) {
      return res.status(400).json({ error: 'Invalid or expired reset token' });
    }

    // Hash new password
    const passwordHash = await bcrypt.hash(password, 10);

    // Update password in person_details table
    // Note: Currently passwords are stored in 'key' field as plain text
    // This updates to password_hash field (need to add this column)
    const { error: updateError } = await supabase
      .from('person_details')
      .update({
        key: password,  // Legacy: update plain text (TODO: migrate to password_hash)
        // password_hash: passwordHash  // Future: use hashed password
      })
      .eq('user_id', resetRecord.user_id);

    if (updateError) {
      console.error('Failed to update password:', updateError);
      return res.status(500).json({ error: 'Failed to update password' });
    }

    // Mark token as used
    await supabase
      .from('password_resets')
      .update({ used_at: new Date().toISOString() })
      .eq('id', resetRecord.id);

    return res.json({
      success: true,
      message: 'Password has been reset successfully'
    });

  } catch (error) {
    console.error('Reset password error:', error);
    return res.status(500).json({ error: error.message });
  }
};
