const db = require('../db/models');
const ValidationError = require('./notifications/errors/validation');

const Op = db.Sequelize.Op;

async function checkPermissions(permission, currentUser) {
  if (!currentUser) {
    throw new ValidationError('auth.unauthorized');
  }

  const userPermission = currentUser.custom_permissions.find(
    (cp) => cp.name === permission,
  );

  if (userPermission) {
    return true;
  }

  if (!currentUser.app_role) {
    throw new ValidationError('auth.forbidden');
  }

  const permissions = await currentUser.app_role.getPermissions();
  return !!permissions.find((p) => p.name === permission);
}

function textMatch(fields, searchQuery) {
  return {
    [Op.or]: fields.map((field) => ({
      [field]: { [Op.iLike]: `%${searchQuery}%` },
    })),
  };
}

function searchResult(type, label, description, path) {
  return {
    type,
    label,
    description,
    path,
  };
}

module.exports = class SearchService {
  static async search(searchQuery, currentUser) {
    if (!searchQuery) {
      throw new ValidationError('iam.errors.searchQueryRequired');
    }

    await checkPermissions('search', currentUser);

    const [clients, sessions, actionItems, resources, packages] = await Promise.all([
      db.clients.findAll({
        where: textMatch(['name', 'email', 'company', 'role_title', 'goals', 'notes'], searchQuery),
        limit: 10,
      }),
      db.sessions.findAll({
        where: textMatch(['title', 'ai_summary', 'key_topics', 'commitments', 'homework'], searchQuery),
        limit: 10,
      }),
      db.action_items.findAll({
        where: textMatch(['title', 'notes'], searchQuery),
        limit: 10,
      }),
      db.resources.findAll({
        where: textMatch(['title', 'description', 'url'], searchQuery),
        limit: 10,
      }),
      db.packages.findAll({
        where: textMatch(['title', 'description', 'price', 'duration'], searchQuery),
        limit: 10,
      }),
    ]);

    return [
      ...clients.map((client) => searchResult(
        'Client',
        client.name,
        client.email || client.company,
        '/clients',
      )),
      ...sessions.map((session) => searchResult(
        'Session',
        session.title,
        session.ai_summary,
        '/session-memory',
      )),
      ...actionItems.map((actionItem) => searchResult(
        'Action Item',
        actionItem.title,
        actionItem.notes,
        '/dashboard',
      )),
      ...resources.map((resource) => searchResult(
        'Resource',
        resource.title,
        resource.description,
        '/client-portal',
      )),
      ...packages.map((coachingPackage) => searchResult(
        'Package',
        coachingPackage.title,
        coachingPackage.description,
        '/',
      )),
    ];
  }
};
