const PUBLIC_RUNTIME_ALLOWED_PATH = '/';

const PUBLIC_RUNTIME_ENTITY_FIELDS = {
  projects: [
    'id',
    'name',
    'slug',
    'description',
    'phase',
    'logo_url',
    'favicon_url',
    'og_image_url',
    'theme_config_json',
    'custom_css_json',
    'cdn_base_url',
    'entry_page_slug',
  ],
  tour_pages: [
    'id',
    'projectId',
    'environment',
    'source_key',
    'name',
    'slug',
    'sort_order',
    'background_image_url',
    'background_video_url',
    'background_audio_url',
    'background_loop',
    'requires_auth',
    'ui_schema_json',
  ],
  page_elements: [
    'id',
    'pageId',
    'element_type',
    'name',
    'sort_order',
    'is_visible',
    'x_percent',
    'y_percent',
    'width_percent',
    'height_percent',
    'rotation_deg',
    'style_json',
    'content_json',
  ],
  page_links: [
    'id',
    'from_pageId',
    'to_pageId',
    'transitionId',
    'direction',
    'external_url',
    'is_active',
    'trigger_selector',
  ],
  transitions: [
    'id',
    'projectId',
    'environment',
    'source_key',
    'name',
    'slug',
    'video_url',
    'audio_url',
    'supports_reverse',
    'duration_sec',
  ],
  project_audio_tracks: [
    'id',
    'projectId',
    'environment',
    'source_key',
    'name',
    'slug',
    'url',
    'loop',
    'volume',
    'sort_order',
    'is_enabled',
  ],
};

const pickFields = (record, fields) => {
  if (!record || typeof record !== 'object') {
    return record;
  }

  return fields.reduce((acc, field) => {
    if (Object.prototype.hasOwnProperty.call(record, field)) {
      acc[field] = record[field];
    }

    return acc;
  }, {});
};

const isPublicRuntimeReadRequest = (req) => {
  return req.isRuntimePublicRequest === true && req.method === 'GET';
};

const blockNonPublicRuntimeListEndpoints = (req, res, next) => {
  if (!isPublicRuntimeReadRequest(req)) {
    return next();
  }

  if (req.path !== PUBLIC_RUNTIME_ALLOWED_PATH) {
    return res.status(404).send({ message: 'Not found' });
  }

  if (req.query.filetype === 'csv') {
    return res.status(404).send({ message: 'Not found' });
  }

  return next();
};

const sanitizePublicRuntimeListResponse = (entityName) => {
  const fields = PUBLIC_RUNTIME_ENTITY_FIELDS[entityName] || [];

  return (req, res, next) => {
    if (!isPublicRuntimeReadRequest(req) || req.path !== PUBLIC_RUNTIME_ALLOWED_PATH || fields.length === 0) {
      return next();
    }

    const originalSend = res.send.bind(res);

    res.send = (body) => {
      if (!body || typeof body !== 'object') {
        return originalSend(body);
      }

      if (!Array.isArray(body.rows)) {
        return originalSend(body);
      }

      const sanitizedRows = body.rows.map((row) => pickFields(row, fields));

      return originalSend({
        ...body,
        rows: sanitizedRows,
      });
    };

    return next();
  };
};

module.exports = {
  blockNonPublicRuntimeListEndpoints,
  sanitizePublicRuntimeListResponse,
};
