const express = require("express");
const { query, batchQuery } = require("../config/database");
const logger = require("../config/logger");
const { asyncHandler } = require("../middleware/errorHandler");
const { cacheMiddleware, cache } = require("../middleware/cache");
const {
  addCacheHeaders,
  fieldFilter,
  paginate,
  trackResponseTime,
  generateETag,
  optimizeJSON,
} = require("../middleware/apiOptimization");
const {
  sendSuccess,
  sendError,
  sendNotFound,
} = require("../utils/responseHelpers");
const router = express.Router();

// Apply global optimizations to all routes
router.use(trackResponseTime);
router.use(fieldFilter);
router.use(optimizeJSON);

// Reusable query fragments
const PRODUCT_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,
        '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
`;

const handleDatabaseError = (res, error, context) => {
  logger.error(`${context} error:`, error);
  sendError(res);
};

// Get all products - Cached for 5 minutes, optimized with index hints
router.get(
  "/products",
  cacheMiddleware(300000),
  asyncHandler(async (req, res) => {
    const result = await query(
      `SELECT ${PRODUCT_FIELDS}, ${PRODUCT_IMAGE_AGG}
       FROM products p
       LEFT JOIN product_images pi ON pi.product_id = p.id
       WHERE p.isactive = true
       GROUP BY p.id
       ORDER BY p.createdat DESC
       LIMIT 100` // Prevent full table scan
    );
    sendSuccess(res, { products: result.rows });
  })
);

// Get featured products - Cached for 10 minutes, optimized with index scan
router.get(
  "/products/featured",
  cacheMiddleware(600000, (req) => `featured:${req.query.limit || 4}`),
  asyncHandler(async (req, res) => {
    const limit = Math.min(parseInt(req.query.limit) || 4, 20);
    const result = await query(
      `SELECT p.id, p.name, p.slug, p.shortdescription, p.price, 
              p.category, p.stockquantity, ${PRODUCT_IMAGE_AGG}
       FROM products p
       LEFT JOIN product_images pi ON pi.product_id = p.id
       WHERE p.isactive = true AND p.isfeatured = true
       GROUP BY p.id
       ORDER BY p.createdat DESC
       LIMIT $1`,
      [limit]
    );
    sendSuccess(res, { products: result.rows });
  })
);

// Get single product by ID or slug - Cached for 15 minutes
router.get(
  "/products/:identifier",
  cacheMiddleware(900000, (req) => `product:${req.params.identifier}`),
  asyncHandler(async (req, res) => {
    const { identifier } = req.params;

    // Optimized UUID check
    const isUUID = identifier.length === 36 && identifier.indexOf("-") === 8;

    // Single optimized query for both cases
    const whereClause = isUUID ? "p.id = $1" : "(p.id = $1 OR p.slug = $1)";

    const result = await query(
      `SELECT p.*,
              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,
                    'display_order', pi.display_order,
                    'is_primary', pi.is_primary,
                    '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
       FROM products p
       LEFT JOIN product_images pi ON pi.product_id = p.id
       WHERE ${whereClause} AND p.isactive = true
       GROUP BY p.id
       LIMIT 1`,
      [identifier]
    );

    if (result.rows.length === 0) {
      return sendNotFound(res, "Product");
    }

    sendSuccess(res, { product: result.rows[0] });
  })
);

// Get all product categories - Cached for 30 minutes
router.get(
  "/categories",
  cacheMiddleware(1800000), // 30 minutes cache
  asyncHandler(async (req, res) => {
    const result = await query(
      `SELECT DISTINCT category 
       FROM products 
       WHERE isactive = true AND category IS NOT NULL AND category != '' 
       ORDER BY category ASC`
    );
    sendSuccess(res, { categories: result.rows.map((row) => row.category) });
  })
);

// Get site settings
router.get(
  "/settings",
  asyncHandler(async (req, res) => {
    const result = await query("SELECT * FROM sitesettings LIMIT 1");
    sendSuccess(res, { settings: result.rows[0] || {} });
  })
);

// Get homepage sections - Cached for 15 minutes
router.get(
  "/homepage/sections",
  cacheMiddleware(900000), // 15 minutes cache
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT * FROM homepagesections ORDER BY displayorder ASC"
    );
    sendSuccess(res, { sections: result.rows });
  })
);
// Get portfolio projects - Cached for 10 minutes
router.get(
  "/portfolio/projects",
  cacheMiddleware(600000), // 10 minutes cache
  asyncHandler(async (req, res) => {
    const result = await query(
      `SELECT id, title, description, featuredimage, images, category, 
     categoryid, isactive, createdat 
     FROM portfolioprojects WHERE isactive = true 
     ORDER BY displayorder ASC, createdat DESC`
    );
    sendSuccess(res, { projects: result.rows });
  })
);

// Get blog posts - Cached for 5 minutes
router.get(
  "/blog/posts",
  cacheMiddleware(300000), // 5 minutes cache
  asyncHandler(async (req, res) => {
    const result = await query(
      `SELECT id, title, slug, excerpt, content, imageurl, ispublished, createdat 
     FROM blogposts WHERE ispublished = true ORDER BY createdat DESC`
    );
    sendSuccess(res, { posts: result.rows });
  })
);

// Get single blog post by slug
router.get(
  "/blog/posts/:slug",
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT * FROM blogposts WHERE slug = $1 AND ispublished = true",
      [req.params.slug]
    );

    if (result.rows.length === 0) {
      return sendNotFound(res, "Blog post");
    }

    sendSuccess(res, { post: result.rows[0] });
  })
);

// Get custom pages - Cached for 10 minutes
router.get(
  "/pages",
  cacheMiddleware(600000),
  asyncHandler(async (req, res) => {
    const result = await query(
      `SELECT id, title, slug, pagecontent as content, metatitle, 
              metadescription, isactive, createdat 
       FROM pages 
       WHERE isactive = true 
       ORDER BY createdat DESC`
    );
    sendSuccess(res, { pages: result.rows });
  })
);

// Get single page by slug - Cached for 15 minutes
router.get(
  "/pages/:slug",
  cacheMiddleware(900000, (req) => `page:${req.params.slug}`),
  asyncHandler(async (req, res) => {
    const result = await query(
      `SELECT id, title, slug, pagecontent as content, metatitle, metadescription 
       FROM pages 
       WHERE slug = $1 AND isactive = true`,
      [req.params.slug]
    );

    if (result.rows.length === 0) {
      return sendNotFound(res, "Page");
    }

    sendSuccess(res, { page: result.rows[0] });
  })
);

// Get menu items for frontend navigation - Cached for 30 minutes
router.get(
  "/menu",
  cacheMiddleware(1800000),
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT settings FROM site_settings WHERE key = 'menu'"
    );
    const items =
      result.rows.length > 0 ? result.rows[0].settings.items || [] : [];
    const visibleItems = items.filter((item) => item.visible !== false);
    sendSuccess(res, { items: visibleItems });
  })
);

// Get homepage settings for frontend
router.get(
  "/homepage/settings",
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT settings FROM site_settings WHERE key = 'homepage'"
    );
    const settings = result.rows.length > 0 ? result.rows[0].settings : {};
    sendSuccess(res, { settings });
  })
);

// Get all team members (public)
router.get(
  "/team-members",
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT id, name, position, bio, image_url FROM team_members ORDER BY display_order ASC, created_at DESC"
    );
    sendSuccess(res, { teamMembers: result.rows });
  })
);

// Get menu items (public)
router.get(
  "/menu",
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT settings FROM site_settings WHERE key = 'menu'"
    );

    if (result.rows.length === 0) {
      return sendSuccess(res, { items: [] });
    }

    // Parse JSON settings if it's a string
    let settings = result.rows[0].settings;
    if (typeof settings === "string") {
      try {
        settings = JSON.parse(settings);
      } catch (e) {
        logger.error("Failed to parse menu settings:", e);
        return sendSuccess(res, { items: [] });
      }
    }

    const items = settings.items || [];
    // Filter only visible items for public
    const visibleItems = items.filter((item) => item.visible !== false);
    sendSuccess(res, { items: visibleItems });
  })
);

module.exports = router;
