import { AdminUser } from '../models/AdminUser.js';
import { PaymentItem } from '../models/PaymentItem.js';
import { Transaction } from '../models/Transaction.js';
import { generateToken } from '../middleware/auth.js';

// Admin login
export const login = async (req, res) => {
  try {
    const { email, password } = req.body;

    // Get user from database
    const user = await AdminUser.getByEmail(email);
    if (!user) {
      return res.status(401).json({
        success: false,
        message: 'Invalid credentials'
      });
    }

    // Verify password
    const isValidPassword = await user.verifyPassword(password);
    if (!isValidPassword) {
      return res.status(401).json({
        success: false,
        message: 'Invalid credentials'
      });
    }

    // Update last login
    await user.updateLastLogin();

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

    res.json({
      success: true,
      data: {
        token,
        user: {
          id: user.id,
          staff_email: user.staff_email,
          staff_id: user.staff_id,
          full_name: user.getFullName(),
          role: user.role,
          last_login: user.last_login
        }
      }
    });

  } catch (error) {
    console.error('Login error:', error);
    res.status(500).json({
      success: false,
      message: 'Login failed'
    });
  }
};

// Get current user profile
export const getProfile = async (req, res) => {
  try {
    const user = req.user;
    
    res.json({
      success: true,
      data: {
        id: user.id,
        staff_email: user.staff_email,
        staff_id: user.staff_id,
        surname: user.surname,
        first_name: user.first_name,
        other_name: user.other_name,
        full_name: user.getFullName(),
        role: user.role,
        staff_passport: user.staff_passport,
        is_active: user.is_active,
        last_login: user.last_login,
        created_at: user.created_at,
        updated_at: user.updated_at
      }
    });

  } catch (error) {
    console.error('Profile fetch error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to fetch profile'
    });
  }
};

// Get dashboard statistics
export const getDashboardStats = async (req, res) => {
  try {
    const filters = {
      date_from: req.query.date_from,
      date_to: req.query.date_to
    };

    const statistics = await Transaction.getStatistics(filters);
    const recentTransactions = await Transaction.getAll(1, 10);

    res.json({
      success: true,
      data: {
        statistics,
        recentTransactions
      }
    });

  } catch (error) {
    console.error('Dashboard stats error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to fetch dashboard statistics'
    });
  }
};

// Get all admin users (programming role only)
export const getAllUsers = async (req, res) => {
  try {
    const users = await AdminUser.getAll();
    
    res.json({
      success: true,
      data: users
    });

  } catch (error) {
    console.error('Users fetch error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to fetch users'
    });
  }
};

// Create new admin user (programming role only)
export const createUser = async (req, res) => {
  try {
    const {
      staff_email,
      staff_id,
      surname,
      first_name,
      other_name,
      role,
      password,
      staff_passport
    } = req.body;

    // Check if email already exists
    const existingUser = await AdminUser.getByEmail(staff_email);
    if (existingUser) {
      return res.status(400).json({
        success: false,
        message: 'User with this email already exists'
      });
    }

    // Check if staff ID already exists
    const existingStaffId = await AdminUser.getByStaffId(staff_id);
    if (existingStaffId) {
      return res.status(400).json({
        success: false,
        message: 'User with this staff ID already exists'
      });
    }

    // Create user
    const userId = await AdminUser.create({
      staff_email,
      staff_id,
      surname,
      first_name,
      other_name,
      role,
      password,
      staff_passport
    });

    res.status(201).json({
      success: true,
      message: 'User created successfully',
      data: { userId }
    });

  } catch (error) {
    console.error('User creation error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to create user'
    });
  }
};

// Update admin user (programming role only)
export const updateUser = async (req, res) => {
  try {
    const { email } = req.params;
    const updateData = req.body;


    // Check if user exists
    const user = await AdminUser.getByEmail(email);
    if (!user) {
      return res.status(404).json({
        success: false,
        message: 'User not found'
      });
    }

    // Update user
    await AdminUser.update(email, updateData);

    res.json({
      success: true,
      message: 'User updated successfully'
    });

  } catch (error) {
    console.error('User update error:', error);
    
    // Handle validation errors
    if (error.message === 'No valid fields to update') {
      return res.status(400).json({
        success: false,
        message: 'No valid fields provided for update'
      });
    }
    
    // Handle duplicate field errors
    if (error.message.includes('already exists')) {
      return res.status(400).json({
        success: false,
        message: error.message
      });
    }
    
    res.status(500).json({
      success: false,
      message: 'Failed to update user'
    });
  }
};

// Deactivate admin user (programming role only)
export const deactivateUser = async (req, res) => {
  try {
    const { email } = req.params;

    // Check if user exists
    const user = await AdminUser.getByEmail(email);
    if (!user) {
      return res.status(404).json({
        success: false,
        message: 'User not found'
      });
    }

    // Prevent deactivating self
    if (user.staff_email === req.user.staff_email) {
      return res.status(400).json({
        success: false,
        message: 'Cannot deactivate your own account'
      });
    }

    // Deactivate user
    await AdminUser.deactivate(email);

    res.json({
      success: true,
      message: 'User deactivated successfully'
    });

  } catch (error) {
    console.error('User deactivation error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to deactivate user'
    });
  }
};

// Get all payment items (admin)
export const getAllPaymentItems = async (req, res) => {
  try {
    const items = await PaymentItem.getAll();
    
    res.json({
      success: true,
      data: items
    });

  } catch (error) {
    console.error('Payment items fetch error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to fetch payment items'
    });
  }
};

// Create payment item (programming role only)
export const createPaymentItem = async (req, res) => {
  try {
    const {
      payment_item_id,
      payment_item,
      amount,
      service_type_id,
      description
    } = req.body;

    // Check if payment item ID already exists
    const existingItem = await PaymentItem.getById(payment_item_id);
    if (existingItem) {
      return res.status(400).json({
        success: false,
        message: 'Payment item with this ID already exists'
      });
    }

    // Create payment item
    const itemId = await PaymentItem.create({
      payment_item_id,
      payment_item,
      amount,
      service_type_id,
      description
    });

    res.status(201).json({
      success: true,
      message: 'Payment item created successfully',
      data: { itemId }
    });

  } catch (error) {
    console.error('Payment item creation error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to create payment item'
    });
  }
};

// Update payment item (programming role only)
export const updatePaymentItem = async (req, res) => {
  try {
    const { id } = req.params;
    const updateData = req.body;

    // Check if payment item exists
    const item = await PaymentItem.getById(id);
    if (!item) {
      return res.status(404).json({
        success: false,
        message: 'Payment item not found'
      });
    }

    // Update payment item
    await PaymentItem.update(id, updateData);

    res.json({
      success: true,
      message: 'Payment item updated successfully'
    });

  } catch (error) {
    console.error('Payment item update error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to update payment item'
    });
  }
};

// Deactivate payment item (programming role only)
export const deactivatePaymentItem = async (req, res) => {
  try {
    const { id } = req.params;

    // Check if payment item exists
    const item = await PaymentItem.getById(id);
    if (!item) {
      return res.status(404).json({
        success: false,
        message: 'Payment item not found'
      });
    }

    // Deactivate payment item
    await PaymentItem.deactivate(id);

    res.json({
      success: true,
      message: 'Payment item deactivated successfully'
    });

  } catch (error) {
    console.error('Payment item deactivation error:', error);
    res.status(500).json({
      success: false,
      message: 'Failed to deactivate payment item'
    });
  }
};
