const User = require('../models/User');

const userController = {
  /**
   * Get all active users with pagination and search
   * GET /api/users
   */
  getAll: async (req, res) => {
    try {
      const page = parseInt(req.query.page) || 1;
      const limit = parseInt(req.query.limit) || 10;
      const search = req.query.search || '';
      const startDate = req.query.startDate || null;
      const endDate = req.query.endDate || null;
      const subscriptionType = req.query.subscriptionType || null;

      // Validate pagination
      if (page < 1 || limit < 1) {
        return res.status(400).json({
          status: false,
          message: 'Page and limit must be positive numbers',
          data: null,
        });
      }

      const filterType = req.query.filterType || 'all'; // 'all' or 'subscribed'

      // Validate pagination
      if (page < 1 || limit < 1) {
        return res.status(400).json({
          status: false,
          message: 'Page and limit must be positive numbers',
          data: null,
        });
      }

      const result = await User.getAll(page, limit, search, startDate, endDate, filterType, subscriptionType);

      return res.status(200).json({
        status: true,
        message: 'Users retrieved successfully',
        data: result.data,
        pagination: result.pagination,
      });
    } catch (error) {
      console.error('Get all users error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Get user by id
   * GET /api/users/:id
   */
  getById: async (req, res) => {
    try {
      const { id } = req.params;

      // Validate id
      if (!id || isNaN(id)) {
        return res.status(400).json({
          status: false,
          message: 'Invalid user ID',
          data: null,
        });
      }

      const user = await User.findById(id);
      if (!user) {
        return res.status(404).json({
          status: false,
          message: 'User not found',
          data: null,
        });
      }

      return res.status(200).json({
        status: true,
        message: 'User retrieved successfully',
        data: user,
      });
    } catch (error) {
      console.error('Get user by id error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Create new user
   * POST /api/users
   */
  create: async (req, res) => {
    try {
      const data = req.body;

      // Basic Validation
      if (!data.first_name || !data.email || !data.password) {
        return res.status(400).json({
          status: false,
          message: 'First Name, Email and Password are required',
          data: null,
        });
      }

      // Validate email format
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(data.email)) {
        return res.status(400).json({
          status: false,
          message: 'Invalid email format',
          data: null,
        });
      }

      // Subscription Conditional Validation
      const subFields = ['license_code', 'license_code_status', 'license_date', 'subscription_type'];
      const hasAnySubField = Boolean(
        data.license_code ||
        data.license_date ||
        data.subscription_type ||
        data.license_code_status === 1
      );

      if (hasAnySubField) {
        // If any is present, ALL must be present
        const missing = subFields.filter(field => !data[field] && data[field] !== 0); // Check for empty or undefined, allowing 0 for status
        if (missing.length > 0) {
          return res.status(400).json({
            status: false,
            message: `When adding subscription, all fields are required: ${missing.join(', ')}`,
            data: null,
          });
        }
      }

      // Create user
      const userId = await User.create(data);

      return res.status(201).json({
        status: true,
        message: 'User created successfully',
        data: {
          user_id: userId,
          ...data
        },
      });
    } catch (error) {
      console.error('Create user error:', error);

      if (error.message === 'Email already exists') {
        return res.status(409).json({
          status: false,
          message: 'Email already exists',
          data: null,
        });
      }

      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Update user
   * PUT /api/users/:id
   */
  update: async (req, res) => {
    try {
      const { id } = req.params;
      const { firstName, lastName, email, phone, status } = req.body;

      // Validate id
      if (!id || isNaN(id)) {
        return res.status(400).json({
          status: false,
          message: 'Invalid user ID',
          data: null,
        });
      }

      // Check if user exists
      const user = await User.findById(id);
      if (!user) {
        return res.status(404).json({
          status: false,
          message: 'User not found',
          data: null,
        });
      }

      // Validate email if provided
      if (email) {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (!emailRegex.test(email)) {
          return res.status(400).json({
            status: false,
            message: 'Invalid email format',
            data: null,
          });
        }
      }

      // Update user
      const updated = await User.update(id, req.body); // Passing full body to model which filters allowed fields

      if (!updated && Object.keys(req.body).length > 0) {
        // No rows affected
      }

      return res.status(200).json({
        status: true,
        message: 'User updated successfully',
        data: null, // Don't return full object
      });
    } catch (error) {
      console.error('Update user error:', error);

      if (error.message === 'Email already exists') {
        return res.status(409).json({
          status: false,
          message: 'Email already exists',
          data: null,
        });
      }

      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },

  /**
   * Delete user (soft delete - set status to deleted)
   * DELETE /api/users/:id
   */
  delete: async (req, res) => {
    try {
      const { id } = req.params;

      // Validate id
      if (!id || isNaN(id)) {
        return res.status(400).json({
          status: false,
          message: 'Invalid user ID',
          data: null,
        });
      }

      // Check if user exists
      const user = await User.findById(id);
      if (!user) {
        return res.status(404).json({
          status: false,
          message: 'User not found',
          data: null,
        });
      }

      // Delete user
      const deleted = await User.delete(id);

      if (!deleted) {
        return res.status(400).json({
          status: false,
          message: 'Failed to delete user',
          data: null,
        });
      }

      return res.status(200).json({
        status: true,
        message: 'User deleted successfully',
        data: null,
      });
    } catch (error) {
      console.error('Delete user error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },
  /**
   * Restore user
   * PUT /api/users/:id/restore
   */
  restore: async (req, res) => {
    try {
      const { id } = req.params;

      if (!id || isNaN(id)) {
        return res.status(400).json({ status: false, message: 'Invalid user ID' });
      }

      const restored = await User.restore(id);

      if (!restored) {
        return res.status(404).json({
          status: false,
          message: 'User not found',
        });
      }

      return res.status(200).json({
        status: true,
        message: 'User restored successfully',
      });
    } catch (error) {
      console.error('Restore user error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        error: error.message,
      });
    }
  },

  /**
   * Get user statistics
   * GET /api/users/stats
   */
  getStats: async (req, res) => {
    try {
      const stats = await User.getDashboardMetrics();

      return res.status(200).json({
        status: true,
        message: 'User statistics retrieved successfully',
        data: stats,
      });
    } catch (error) {
      console.error('Get stats error:', error);
      return res.status(500).json({
        status: false,
        message: 'Internal server error',
        data: null,
        error: error.message,
      });
    }
  },
  /**
   * Add subscription to user
   * POST /api/users/:id/subscription
   */
  addSubscription: async (req, res) => {
    try {
      const { id } = req.params;
      const { planName, startDate, endDate, status } = req.body;

      if (!id || isNaN(id)) {
        return res.status(400).json({ status: false, message: 'Invalid user ID' });
      }

      if (!planName || !startDate || !endDate) {
        return res.status(400).json({ status: false, message: 'Missing required fields' });
      }

      const subscriptionId = await User.addSubscription(id, planName, startDate, endDate, status);

      return res.status(201).json({
        status: true,
        message: 'Subscription added successfully',
        data: { id: subscriptionId, planName, startDate, endDate, status }
      });
    } catch (error) {
      console.error('Add subscription error:', error);
      return res.status(500).json({ status: false, message: 'Internal server error', error: error.message });
    }
  },

  /**
   * Export users to CSV
   * GET /api/users/export
   */
  exportUsers: async (req, res) => {
    try {
      const { search, startDate, endDate, type, ids, subscriptionType } = req.query;

      let query = `
        SELECT
          u.*,
          COALESCE(rc.report_count, 0) AS report_count
        FROM users u
        LEFT JOIN (
          SELECT user_id, COUNT(*) AS report_count
          FROM cart
          GROUP BY user_id
        ) rc ON rc.user_id = u.user_id
        WHERE 1=1
      `;
      let params = [];

      if (ids) {
        const idList = ids.split(',').map(id => parseInt(id, 10)).filter(id => !Number.isNaN(id));
        if (idList.length > 0) {
          query += ` AND u.user_id IN (${idList.map(() => '?').join(',')})`;
          params.push(...idList);
        }
      } else {
        if (subscriptionType && subscriptionType !== 'all') {
          query += ' AND u.subscription_type = ?';
          params.push(parseInt(subscriptionType, 10));
        }

        // Search filter
        if (search && search.trim()) {
          const searchTerm = `%${search}%`;
          query += ' AND (u.first_name LIKE ? OR u.last_name LIKE ? OR u.email LIKE ?)';
          params.push(searchTerm, searchTerm, searchTerm);
        }

        // Date range filter
        if (startDate) {
          query += ' AND DATE(u.date_created) >= ?';
          params.push(startDate);
        }
        if (endDate) {
          query += ' AND DATE(u.date_created) <= ?';
          params.push(endDate);
        }

        // Type-based filters for Dashboard Exports
        if (type === 'new_users_yesterday') {
          query += ' AND u.date_created >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND u.date_created < CURDATE()';
        } else if (type === 'new_users_last_7_days') {
          query += ' AND u.date_created >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)';
        } else if (type === 'new_subs_yesterday') {
          query += " AND u.license_date >= DATE_SUB(CURDATE(), INTERVAL 1 DAY) AND u.license_date < CURDATE() AND u.license_code != '' AND u.license_code IS NOT NULL AND u.license_code_status = 1";
        } else if (type === 'new_subs_last_7_days') {
          query += " AND u.license_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND u.license_code != '' AND u.license_code IS NOT NULL AND u.license_code_status = 1";
        }
      }

      query += ' ORDER BY u.date_created DESC';

      const [users] = await require('../config/database').query(query, params);

      // Define CSV fields
      const fields = [
        'user_id',
        'first_name',
        'last_name',
        'email',
        'phone',
        'status',
        'date_created',
        'license_code',
        'license_date',
        'license_code_status',
        'subscription_type',
        'report_count',
        'notes'
      ];
      const header = fields.join(',') + '\n';

      const rows = users.map(user => {
        return fields.map(field => {
          let value = user[field];
          if (value === null || value === undefined) value = '';

          if (field === 'date_created' || field === 'license_date') {
            try {
              if (value) value = new Date(value).toISOString();
            } catch (e) { }
          }

          const normalized = String(value).replace(/"/g, '""');
          if (/[",\n]/.test(normalized)) {
            return `"${normalized}"`;
          }
          return normalized;
        }).join(',');
      }).join('\n');

      const csv = header + rows;

      res.header('Content-Type', 'text/csv');
      res.header('Content-Disposition', 'attachment; filename="users_export.csv"');
      return res.send(csv);

    } catch (error) {
      console.error('Export users error:', error);
      return res.status(500).json({ status: false, message: 'Internal server error', error: error.message });
    }
  }
};

module.exports = userController;
