/**
 * Optimized Query Builders
 * Reusable SQL query builders with proper field selection and pagination
 */

const PRODUCT_BASE_FIELDS = [
  "p.id",
  "p.name",
  "p.slug",
  "p.shortdescription",
  "p.description",
  "p.price",
  "p.category",
  "p.stockquantity",
  "p.sku",
  "p.weight",
  "p.dimensions",
  "p.material",
  "p.isfeatured",
  "p.isbestseller",
  "p.createdat",
];

const PRODUCT_IMAGE_AGG = `
  COALESCE(
    json_agg(
      json_build_object(
        'id', pi.id,
        'image_url', pi.image_url,
        'color_variant', pi.color_variant,
        'color_code', pi.color_code,
        'alt_text', pi.alt_text,
        'is_primary', pi.is_primary,
        'display_order', pi.display_order,
        'variant_price', pi.variant_price,
        'variant_stock', pi.variant_stock
      ) ORDER BY pi.display_order, pi.created_at
    ) FILTER (WHERE pi.id IS NOT NULL),
    '[]'::json
  ) as images
`;

/**
 * Build product query with images
 * @param {Object} options - Query options
 * @param {string[]} options.fields - Additional fields to select
 * @param {string} options.where - WHERE clause
 * @param {string} options.orderBy - ORDER BY clause
 * @param {number} options.limit - LIMIT value
 * @returns {string} SQL query
 */
const buildProductQuery = ({
  fields = [],
  where = "p.isactive = true",
  orderBy = "p.createdat DESC",
  limit = null,
} = {}) => {
  const selectFields = [...PRODUCT_BASE_FIELDS, ...fields].join(", ");

  return `
    SELECT ${selectFields}, ${PRODUCT_IMAGE_AGG}
    FROM products p
    LEFT JOIN product_images pi ON pi.product_id = p.id
    WHERE ${where}
    GROUP BY p.id
    ORDER BY ${orderBy}
    ${limit ? `LIMIT ${limit}` : ""}
  `.trim();
};

/**
 * Build optimized query for single product by ID or slug
 * @param {string} identifier - Product ID or slug
 * @returns {Object} Query object with text and values
 */
const buildSingleProductQuery = (identifier) => {
  const isUUID = identifier.length === 36 && identifier.indexOf("-") === 8;
  const whereClause = isUUID ? "p.id = $1" : "(p.id = $1 OR p.slug = $1)";

  return {
    text:
      buildProductQuery({ where: `${whereClause} AND p.isactive = true` }) +
      " LIMIT 1",
    values: [identifier],
  };
};

/**
 * Build blog post query with field selection
 * @param {Object} options - Query options
 * @param {boolean} options.includeContent - Include full content
 * @param {boolean} options.publishedOnly - Filter by published status
 * @returns {string} SQL query
 */
const buildBlogQuery = ({
  includeContent = true,
  publishedOnly = true,
} = {}) => {
  const fields = includeContent
    ? "id, title, slug, excerpt, content, featuredimage, imageurl, images, ispublished, createdat"
    : "id, title, slug, excerpt, featuredimage, imageurl, ispublished, createdat";

  const whereClause = publishedOnly ? "WHERE ispublished = true" : "";

  return `SELECT ${fields} FROM blogposts ${whereClause} ORDER BY createdat DESC`;
};

/**
 * Build pages query with field selection
 * @param {Object} options - Query options
 * @param {boolean} options.includeContent - Include page content
 * @param {boolean} options.activeOnly - Filter by active status
 * @returns {string} SQL query
 */
const buildPagesQuery = ({ includeContent = true, activeOnly = true } = {}) => {
  const fields = includeContent
    ? "id, title, slug, pagecontent as content, metatitle, metadescription, isactive, createdat"
    : "id, title, slug, metatitle, metadescription, isactive, createdat";

  const whereClause = activeOnly ? "WHERE isactive = true" : "";

  return `SELECT ${fields} FROM pages ${whereClause} ORDER BY createdat DESC`;
};

/**
 * Build portfolio projects query
 * @param {boolean} activeOnly - Filter by active status
 * @returns {string} SQL query
 */
const buildPortfolioQuery = (activeOnly = true) => {
  const whereClause = activeOnly ? "WHERE isactive = true" : "";

  return `
    SELECT 
      id, title, description, imageurl, images, 
      category, categoryid, isactive, createdat, displayorder
    FROM portfolioprojects 
    ${whereClause}
    ORDER BY displayorder ASC, createdat DESC
  `.trim();
};

/**
 * Build categories query
 * @returns {string} SQL query
 */
const buildCategoriesQuery = () => {
  return `
    SELECT DISTINCT category 
    FROM products 
    WHERE isactive = true 
      AND category IS NOT NULL 
      AND category != '' 
    ORDER BY category ASC
  `.trim();
};

/**
 * Pagination helper
 * @param {number} page - Page number (1-indexed)
 * @param {number} limit - Items per page
 * @returns {Object} Offset and limit
 */
const getPagination = (page = 1, limit = 20) => {
  const validPage = Math.max(1, parseInt(page) || 1);
  const validLimit = Math.min(100, Math.max(1, parseInt(limit) || 20));
  const offset = (validPage - 1) * validLimit;

  return { offset, limit: validLimit, page: validPage };
};

/**
 * Add pagination to query
 * @param {string} query - Base SQL query
 * @param {number} page - Page number
 * @param {number} limit - Items per page
 * @returns {string} SQL query with pagination
 */
const addPagination = (query, page, limit) => {
  const { offset, limit: validLimit } = getPagination(page, limit);
  return `${query} LIMIT ${validLimit} OFFSET ${offset}`;
};

module.exports = {
  buildProductQuery,
  buildSingleProductQuery,
  buildBlogQuery,
  buildPagesQuery,
  buildPortfolioQuery,
  buildCategoriesQuery,
  getPagination,
  addPagination,
  PRODUCT_BASE_FIELDS,
  PRODUCT_IMAGE_AGG,
};
