const { logger } = require('../../middleware/logger');

class AdminRepository {
  static async getUserStats(conn) {
    logger.info('AdminRepository.getUserStats:start');
    try {
      const [[{ totalUsers }]] = await conn.query(`SELECT COUNT(*) AS totalUsers FROM users`);
      const [[{ adminUsers }]] = await conn.query(`SELECT COUNT(*) AS adminUsers FROM users WHERE role IN ('admin', 'super_admin')`);
      const [[{ verificationPending }]] = await conn.query(`
        SELECT COUNT(*) AS verificationPending
        FROM user_status
        WHERE
          status = 'pending'
          AND email_verified = 1
          AND profile_completed = 1
          AND documents_uploaded = 1
          AND contract_signed = 1
          AND is_admin_verified = 0
      `);
      const [[{ activeUsers }]] = await conn.query(`
        SELECT COUNT(*) AS activeUsers
        FROM user_status us
        JOIN users u ON us.user_id = u.id
        WHERE us.is_admin_verified = 1 AND u.role = 'user'
      `);
      const [[{ personalUsers }]] = await conn.query(`SELECT COUNT(*) AS personalUsers FROM users WHERE user_type = 'personal'`);
      const [[{ companyUsers }]] = await conn.query(`SELECT COUNT(*) AS companyUsers FROM users WHERE user_type = 'company'`);
      logger.info('AdminRepository.getUserStats:success', { totalUsers, adminUsers, verificationPending, activeUsers, personalUsers, companyUsers });
      return { totalUsers, adminUsers, verificationPending, activeUsers, personalUsers, companyUsers };
    } catch (error) {
      logger.error('AdminRepository.getUserStats:error', { error: error.message });
      throw error;
    }
  }

  static async getUserList(conn) {
    logger.info('AdminRepository.getUserList:start');
    try {
      const [rows] = await conn.query(`
        SELECT 
          u.id, u.email, u.user_type, u.role, u.created_at, u.last_login_at,
          us.status, us.is_admin_verified,
          pp.first_name, pp.last_name,
          cp.company_name
        FROM users u
        LEFT JOIN user_status us ON u.id = us.user_id
        LEFT JOIN personal_profiles pp ON u.id = pp.user_id
        LEFT JOIN company_profiles cp ON u.id = cp.user_id
        ORDER BY u.created_at DESC
      `);
      logger.info('AdminRepository.getUserList:success', { count: rows.length });
      return rows;
    } catch (error) {
      logger.error('AdminRepository.getUserList:error', { error: error.message });
      throw error;
    }
  }

  static async getVerificationPendingUsers(conn) {
    logger.info('AdminRepository.getVerificationPendingUsers:start');
    try {
      const [rows] = await conn.query(`
        SELECT 
          u.id, u.email, u.user_type, u.role, u.created_at, u.last_login_at,
          us.status, us.is_admin_verified,
          pp.first_name, pp.last_name,
          cp.company_name
        FROM users u
        LEFT JOIN user_status us ON u.id = us.user_id
        LEFT JOIN personal_profiles pp ON u.id = pp.user_id
        LEFT JOIN company_profiles cp ON u.id = cp.user_id
        WHERE
          us.status = 'pending'
          AND us.email_verified = 1
          AND us.profile_completed = 1
          AND us.documents_uploaded = 1
          AND us.contract_signed = 1
          AND us.is_admin_verified = 0
        ORDER BY u.created_at DESC
      `);
      logger.info('AdminRepository.getVerificationPendingUsers:success', { count: rows.length });
      return rows;
    } catch (error) {
      logger.error('AdminRepository.getVerificationPendingUsers:error', { error: error.message });
      throw error;
    }
  }

  static async getUnverifiedUsers(conn) {
    logger.info('AdminRepository.getUnverifiedUsers:start');
    try {
      const [rows] = await conn.query(`
        SELECT 
          u.id, u.email, u.user_type, u.role, u.created_at, u.last_login_at,
          us.status, us.is_admin_verified, us.email_verified, us.profile_completed, 
          us.documents_uploaded, us.contract_signed,
          pp.first_name, pp.last_name,
          cp.company_name
        FROM users u
        LEFT JOIN user_status us ON u.id = us.user_id
        LEFT JOIN personal_profiles pp ON u.id = pp.user_id
        LEFT JOIN company_profiles cp ON u.id = cp.user_id
        WHERE us.is_admin_verified = 0
        ORDER BY u.created_at DESC
      `);
      logger.info('AdminRepository.getUnverifiedUsers:success', { count: rows.length });
      return rows;
    } catch (error) {
      logger.error('AdminRepository.getUnverifiedUsers:error', { error: error.message });
      throw error;
    }
  }

  static async getUserDocuments(conn, userId) {
    logger.info('AdminRepository.getUserDocuments:start', { userId });
    try {
      const [documents] = await conn.query(`SELECT * FROM user_documents WHERE user_id = ?`, [userId]);
      logger.info('AdminRepository.getUserDocuments:success', { userId, count: documents.length });
      return documents;
    } catch (error) {
      logger.error('AdminRepository.getUserDocuments:error', { userId, error: error.message });
      throw error;
    }
  }

  static async getUserContracts(conn, userId) {
    logger.info('AdminRepository.getUserContracts:start', { userId });
    try {
      const [contracts] = await conn.query(
        `SELECT * FROM user_documents WHERE user_id = ? AND document_type = 'contract'`, [userId]
      );
      logger.info('AdminRepository.getUserContracts:success', { userId, count: contracts.length });
      return contracts;
    } catch (error) {
      logger.error('AdminRepository.getUserContracts:error', { userId, error: error.message });
      throw error;
    }
  }

  static async getUserIdDocuments(conn, userId) {
    logger.info('AdminRepository.getUserIdDocuments:start', { userId });
    try {
      const [idDocs] = await conn.query(`SELECT * FROM user_id_documents WHERE user_id = ?`, [userId]);
      logger.info('AdminRepository.getUserIdDocuments:success', { userId, count: idDocs.length });
      return idDocs;
    } catch (error) {
      logger.error('AdminRepository.getUserIdDocuments:error', { userId, error: error.message });
      throw error;
    }
  }

  static async verifyUser(conn, userId) {
    logger.info('AdminRepository.verifyUser:start', { userId });
    try {
      await conn.query(
        `UPDATE user_status SET is_admin_verified = 1, admin_verified_at = NOW(), status = 'active' WHERE user_id = ?`,
        [userId]
      );
      logger.info('AdminRepository.verifyUser:success', { userId });
    } catch (error) {
      logger.error('AdminRepository.verifyUser:error', { userId, error: error.message });
      throw error;
    }
  }

  static async assignPermissions(conn, userId, permissions) {
    logger.info('AdminRepository.assignPermissions:start', { userId, permissions });
    try {
      const [permRows] = await conn.query(
        `SELECT id, name FROM permissions WHERE name IN (?)`, [permissions]
      );
      for (const perm of permRows) {
        await conn.query(
          `INSERT IGNORE INTO user_permissions (user_id, permission_id) VALUES (?, ?)`,
          [userId, perm.id]
        );
      }
      logger.info('AdminRepository.assignPermissions:success', { userId, permissions });
    } catch (error) {
      logger.error('AdminRepository.assignPermissions:error', { userId, error: error.message });
      throw error;
    }
  }

  static async getUserById(conn, userId) {
    logger.info('AdminRepository.getUserById:start', { userId });
    try {
      const [rows] = await conn.query(`SELECT * FROM users WHERE id = ? LIMIT 1`, [userId]);
      logger.info('AdminRepository.getUserById:success', { userId, found: !!(rows.length) });
      return rows.length ? rows[0] : null;
    } catch (error) {
      logger.error('AdminRepository.getUserById:error', { userId, error: error.message });
      throw error;
    }
  }

  static async getPersonalProfile(conn, userId) {
    logger.info('AdminRepository.getPersonalProfile:start', { userId });
    try {
      const [rows] = await conn.query(`SELECT * FROM personal_profiles WHERE user_id = ? LIMIT 1`, [userId]);
      logger.info('AdminRepository.getPersonalProfile:success', { userId, found: !!(rows.length) });
      return rows.length ? rows[0] : null;
    } catch (error) {
      logger.error('AdminRepository.getPersonalProfile:error', { userId, error: error.message });
      throw error;
    }
  }

  static async getCompanyProfile(conn, userId) {
    logger.info('AdminRepository.getCompanyProfile:start', { userId });
    try {
      const [rows] = await conn.query(`SELECT * FROM company_profiles WHERE user_id = ? LIMIT 1`, [userId]);
      logger.info('AdminRepository.getCompanyProfile:success', { userId, found: !!(rows.length) });
      return rows.length ? rows[0] : null;
    } catch (error) {
      logger.error('AdminRepository.getCompanyProfile:error', { userId, error: error.message });
      throw error;
    }
  }

  static async getUserPermissions(conn, userId) {
    logger.info('AdminRepository.getUserPermissions:start', { userId });
    try {
      const [permRows] = await conn.query(
        `SELECT p.id, p.name, p.description, p.is_active
         FROM user_permissions up
         JOIN permissions p ON up.permission_id = p.id
         WHERE up.user_id = ? AND p.is_active = TRUE`,
        [userId]
      );
      logger.info('AdminRepository.getUserPermissions:success', { userId, count: permRows.length });
      return permRows;
    } catch (error) {
      logger.error('AdminRepository.getUserPermissions:error', { userId, error: error.message });
      throw error;
    }
  }

  static async updateUserPermissions(conn, userId, permissions) {
    logger.info('AdminRepository.updateUserPermissions:start', { userId, permissions });
    try {
      await conn.query(`DELETE FROM user_permissions WHERE user_id = ?`, [userId]);
      if (permissions.length > 0) {
        const [permRows] = await conn.query(
          `SELECT id, name FROM permissions WHERE name IN (?) AND is_active = TRUE`, [permissions]
        );
        const permIds = permRows.map(row => row.id);
        if (permIds.length > 0) {
          const values = permIds.map(pid => [userId, pid]);
          await conn.query(
            `INSERT INTO user_permissions (user_id, permission_id) VALUES ?`, [values]
          );
        }
      }
      logger.info('AdminRepository.updateUserPermissions:success', { userId, permissions });
    } catch (error) {
      logger.error('AdminRepository.updateUserPermissions:error', { userId, error: error.message });
      throw error;
    }
  }
}

module.exports = AdminRepository;
