// controllers/authController.js
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { User, Session, Store,RegisterAssignment,Register } = require('../models');

exports.register = async (req, res) => {
  try {
    const { username, email, password, firstName, lastName, role, storeId } = req.body;

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

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

    // Create user
    const user = await User.create({
      username,
      email,
      password: hashedPassword,
      firstName,
      lastName,
      role,
      storeId
    });

    res.status(201).json({
      message: 'User created successfully',
      user: {
        id: user.id,
        username: user.username,
        email: user.email,
        role: user.role
      }
    });
  } catch (error) {
    res.status(500).json({ message: 'Error creating user', error: error.message });
  }
};


exports.login = async (req, res) => {
  try {
    const { username, password } = req.body;

   // console.log('Login attempt for username:', username);
    // Find user by username instead of email
    const user = await User.findOne({
      where: { username, isActive: true },
      include: [{ model: Store, as: 'store' },
        { model: Register, as: 'openedRegisters' },
        { model: RegisterAssignment, as: 'registerAssignments' },
          {
    model: Register,
    as: 'assignedRegisters',  // <-- MUST match your alias in the association
    through: {
      attributes: ['id', 'assignedAt', 'isPrimary', 'isActive'],
    }}
      ]
    });

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

    // Check password
    const isValidPassword = await bcrypt.compare(password, user.password);
    if (!isValidPassword) {
      return res.status(401).json({ message: 'Invalid credentials' });
    }

    // Generate token
    const token = jwt.sign(
      { id: user.id, username: user.username, role: user.role,store_id: user.storeId },
      process.env.JWT_SECRET,
      { expiresIn: '8h' }
    );

    // Destroy any existing sessions for this user (single session only)
await Session.destroy({
  where: { userId: user.id }
});

    // Create session
    await Session.create({
      userId: user.id,
      token,
      ipAddress: req.ip,
      userAgent: req.headers['user-agent'],
      expiresAt: new Date(Date.now() + 8 * 60 * 60 * 1000)
    });

    // Update last login timestamp
    await user.update({ lastLogin: new Date() });

    res.json({
      message: 'Login successful',
      token,
      user: {
        id: user.id,
        store_id: user.storeId,
        username: user.username,
        firstName: user.firstName,
        lastName: user.lastName,
        role: user.role,
        store: user.store,
        register: user.openedRegisters.length > 0 ? user.openedRegisters : null,
        registerId: user.openedRegisters.length > 0 ? user.openedRegisters[0].id : null,
     
      }
    });
  } catch (error) {
    res.status(500).json({ message: 'Error logging in', error: error.message });
  }
};


exports.loginEmail = async (req, res) => {
  try {
    const { username, password } = req.body;


    console.log('Login attempt for email:', username);

    // Find user
    const user = await User.findOne({ 
      where: { email, isActive: true },
      include: [{ model: Store, as: 'store' }]
    });

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

    // Check password
    const isValidPassword = await bcrypt.compare(password, user.password);
    if (!isValidPassword) {
      return res.status(401).json({ message: 'Invalid credentials' });
    }

    // Generate token
    const token = jwt.sign(
      { id: user.id, email: user.email, role: user.role },
      process.env.JWT_SECRET,
      { expiresIn: '8h' }
    );

    // Create session
    await Session.create({
      userId: user.id,
      token,
      ipAddress: req.ip,
      userAgent: req.headers['user-agent'],
      expiresAt: new Date(Date.now() + 8 * 60 * 60 * 1000)
    });

    // Update last login
    await user.update({ lastLogin: new Date() });

    res.json({
      message: 'Login successful',
      token,
      user: {
        id: user.id,
        username: user.username,
        email: user.email,
        firstName: user.firstName,
        lastName: user.lastName,
        role: user.role,
        store: user.store
      }
    });
  } catch (error) {
    res.status(500).json({ message: 'Error logging in', error: error.message });
  }
};

exports.logout = async (req, res) => {
  try {
    const token = req.headers.authorization?.split(' ')[1];
    await Session.destroy({ where: { token } });
    res.json({ message: 'Logged out successfully' });
  } catch (error) {
    res.status(500).json({ message: 'Error logging out', error: error.message });
  }
};


exports.verifyToken = async (req, res) => {
  try {
    // User is already authenticated by middleware
    // Store access is already verified by verifyStoreAccess middleware
     
    res.json({
      valid: true,
      user: {
        id: req.user.id,
        username: req.user.username,
        role: req.user.role,
        store_id: req.user.store_id
      }
    });
  } catch (error) {
    console.error('Token verification error:', error);
    res.status(500).json({ error: 'Verification failed' });
  }
};

exports.verifyPin = async (req, res) => {
  try {
    const { userId, pin } = req.body;
    const user = await User.findByPk(userId);

    if (!user || user.pin !== pin) {
      return res.status(401).json({ message: 'Invalid PIN' });
    }

    res.json({ message: 'PIN verified', user: { id: user.id, firstName: user.firstName } });
  } catch (error) {
    res.status(500).json({ message: 'Error verifying PIN', error: error.message });
  }
};