const express = require("express");
const { query } = require("../config/database");
const { requireAuth } = require("../middleware/auth");
const { cache } = require("../middleware/cache");
const { apiLimiter } = require("../config/rateLimiter");
const {
  invalidateProductCache,
  invalidateBlogCache,
  invalidatePortfolioCache,
  invalidateHomepageCache,
} = require("../utils/cacheInvalidation");
const logger = require("../config/logger");
const { asyncHandler } = require("../middleware/errorHandler");
const {
  sendSuccess,
  sendError,
  sendNotFound,
} = require("../utils/responseHelpers");
const { getById, deleteById, countRecords } = require("../utils/queryHelpers");
const { HTTP_STATUS } = require("../config/constants");
const router = express.Router();

// Apply rate limiting to all admin routes
router.use(apiLimiter);

// Dashboard stats API
router.get(
  "/dashboard/stats",
  requireAuth,
  asyncHandler(async (req, res) => {
    const [productsCount, projectsCount, blogCount, pagesCount] =
      await Promise.all([
        countRecords("products"),
        countRecords("portfolioprojects"),
        countRecords("blogposts"),
        countRecords("pages"),
      ]);

    sendSuccess(res, {
      stats: {
        products: productsCount,
        projects: projectsCount,
        blog: blogCount,
        pages: pagesCount,
      },
      user: {
        name: req.session.name,
        email: req.session.email,
        role: req.session.role,
      },
    });
  })
);

// Generic CRUD factory function
const createCRUDRoutes = (config) => {
  const { table, resourceName, listFields = "*", requiresAuth = true } = config;
  const auth = requiresAuth ? requireAuth : (req, res, next) => next();

  // List all
  router.get(
    `/${resourceName}`,
    auth,
    asyncHandler(async (req, res) => {
      const result = await query(
        `SELECT ${listFields} FROM ${table} ORDER BY createdat DESC`
      );
      sendSuccess(res, { [resourceName]: result.rows });
    })
  );

  // Get by ID
  router.get(
    `/${resourceName}/:id`,
    auth,
    asyncHandler(async (req, res) => {
      const item = await getById(table, req.params.id);
      if (!item) {
        return sendNotFound(res, resourceName);
      }
      const responseKey = resourceName.slice(0, -1); // Remove 's' for singular
      sendSuccess(res, { [responseKey]: item });
    })
  );

  // Delete
  router.delete(
    `/${resourceName}/:id`,
    auth,
    asyncHandler(async (req, res) => {
      const deleted = await deleteById(table, req.params.id);
      if (!deleted) {
        return sendNotFound(res, resourceName);
      }
      sendSuccess(res, { message: `${resourceName} deleted successfully` });
    })
  );
};

// Helper function to generate slug
const generateSlug = (name) => {
  return name
    .toLowerCase()
    .replace(/[^a-z0-9\s-]/g, "")
    .replace(/\s+/g, "-")
    .replace(/-+/g, "-")
    .trim();
};

// Products CRUD
router.get(
  "/products",
  requireAuth,
  asyncHandler(async (req, res) => {
    const result = await query(
      `SELECT p.id, p.name, p.price, p.stockquantity, p.isactive, p.isfeatured, 
            p.isbestseller, p.category, p.createdat,
            (SELECT COUNT(*) FROM product_images WHERE product_id = p.id) as image_count
     FROM products p 
     ORDER BY p.createdat DESC`
    );
    sendSuccess(res, { products: result.rows });
  })
);

router.get(
  "/products/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    // Get product details
    const product = await getById("products", req.params.id);
    if (!product) {
      return sendNotFound(res, "Product");
    }

    // Get associated images with color variants
    const imagesResult = await query(
      `SELECT id, image_url, color_variant, alt_text, display_order, is_primary 
     FROM product_images 
     WHERE product_id = $1 
     ORDER BY display_order ASC, created_at ASC`,
      [req.params.id]
    );

    product.images = imagesResult.rows;
    sendSuccess(res, { product });
  })
);

router.post(
  "/products",
  requireAuth,
  asyncHandler(async (req, res) => {
    const {
      name,
      shortdescription,
      description,
      price,
      stockquantity,
      category,
      sku,
      weight,
      dimensions,
      material,
      isactive,
      isfeatured,
      isbestseller,
      images,
    } = req.body;

    // Generate unique ID and slug from name
    const productId =
      "prod-" + Date.now() + "-" + Math.random().toString(36).substr(2, 9);
    const slug = generateSlug(name);

    // Insert product
    const productResult = await query(
      `INSERT INTO products (
      id, name, slug, shortdescription, description, price, stockquantity, 
      category, sku, weight, dimensions, material, isactive, isfeatured, 
      isbestseller, createdat
    ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, NOW()) 
    RETURNING *`,
      [
        productId,
        name,
        slug,
        shortdescription,
        description,
        price,
        stockquantity || 0,
        category,
        sku,
        weight,
        dimensions,
        material,
        isactive !== false,
        isfeatured || false,
        isbestseller || false,
      ]
    );

    const product = productResult.rows[0];

    // Insert images with color variants if provided
    if (images && Array.isArray(images) && images.length > 0) {
      for (let i = 0; i < images.length; i++) {
        const img = images[i];
        await query(
          `INSERT INTO product_images (
          product_id, image_url, color_variant, color_code, alt_text, display_order, is_primary, variant_price, variant_stock
        ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
          [
            product.id,
            img.image_url,
            img.color_variant || null,
            img.color_code || null,
            img.alt_text || name,
            img.display_order || i,
            img.is_primary || i === 0,
            img.variant_price || null,
            img.variant_stock || 0,
          ]
        );
      }
    }

    // Fetch complete product with images
    const completeProduct = await query(
      `SELECT p.*, 
            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
            ) FILTER (WHERE pi.id IS NOT NULL) as images
     FROM products p
     LEFT JOIN product_images pi ON pi.product_id = p.id
     WHERE p.id = $1
     GROUP BY p.id`,
      [product.id]
    );

    sendSuccess(
      res,
      {
        product: completeProduct.rows[0],
        message: "Product created successfully",
      },
      HTTP_STATUS.CREATED
    );
  })
);

router.put(
  "/products/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    console.log("=== UPDATE PRODUCT API CALLED ===");
    console.log("Product ID:", req.params.id);
    console.log("Request body:", JSON.stringify(req.body, null, 2));

    const {
      name,
      shortdescription,
      description,
      price,
      stockquantity,
      category,
      sku,
      weight,
      dimensions,
      material,
      isactive,
      isfeatured,
      isbestseller,
      images,
    } = req.body;

    console.log("Images to save:", images);

    // Generate slug if name is provided
    const slug = name ? generateSlug(name) : null;

    // Build dynamic update query
    const updates = [];
    const values = [];
    let paramIndex = 1;

    if (name !== undefined) {
      updates.push(`name = $${paramIndex++}`);
      values.push(name);
      updates.push(`slug = $${paramIndex++}`);
      values.push(slug);
    }
    if (shortdescription !== undefined) {
      updates.push(`shortdescription = $${paramIndex++}`);
      values.push(shortdescription);
    }
    if (description !== undefined) {
      updates.push(`description = $${paramIndex++}`);
      values.push(description);
    }
    if (price !== undefined) {
      updates.push(`price = $${paramIndex++}`);
      values.push(price);
    }
    if (stockquantity !== undefined) {
      updates.push(`stockquantity = $${paramIndex++}`);
      values.push(stockquantity);
    }
    if (category !== undefined) {
      updates.push(`category = $${paramIndex++}`);
      values.push(category);
    }
    if (sku !== undefined) {
      updates.push(`sku = $${paramIndex++}`);
      values.push(sku);
    }
    if (weight !== undefined) {
      updates.push(`weight = $${paramIndex++}`);
      values.push(weight);
    }
    if (dimensions !== undefined) {
      updates.push(`dimensions = $${paramIndex++}`);
      values.push(dimensions);
    }
    if (material !== undefined) {
      updates.push(`material = $${paramIndex++}`);
      values.push(material);
    }
    if (isactive !== undefined) {
      updates.push(`isactive = $${paramIndex++}`);
      values.push(isactive);
    }
    if (isfeatured !== undefined) {
      updates.push(`isfeatured = $${paramIndex++}`);
      values.push(isfeatured);
    }
    if (isbestseller !== undefined) {
      updates.push(`isbestseller = $${paramIndex++}`);
      values.push(isbestseller);
    }

    updates.push(`updatedat = NOW()`);
    values.push(req.params.id);

    const updateQuery = `UPDATE products SET ${updates.join(
      ", "
    )} WHERE id = $${paramIndex} RETURNING *`;
    const result = await query(updateQuery, values);

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

    console.log("Product updated in database:", result.rows[0].id);

    // Update images if provided
    if (images && Array.isArray(images)) {
      console.log("Updating images, count:", images.length);

      // Delete existing images for this product
      const deleteResult = await query(
        "DELETE FROM product_images WHERE product_id = $1",
        [req.params.id]
      );
      console.log("Deleted existing images, count:", deleteResult.rowCount);

      // Insert new images
      for (let i = 0; i < images.length; i++) {
        const img = images[i];
        console.log(
          `Inserting image ${i + 1}/${images.length}:`,
          img.image_url
        );

        await query(
          `INSERT INTO product_images (
          product_id, image_url, color_variant, color_code, alt_text, display_order, is_primary, variant_price, variant_stock
        ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
          [
            req.params.id,
            img.image_url,
            img.color_variant || null,
            img.color_code || null,
            img.alt_text || result.rows[0].name,
            img.display_order || i,
            img.is_primary || i === 0,
            img.variant_price || null,
            img.variant_stock || 0,
          ]
        );
      }
      console.log("All images inserted successfully");
    } else {
      console.log("No images to update");
    }

    // Fetch complete product with images
    const completeProduct = await query(
      `SELECT p.*, 
            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
            ) FILTER (WHERE pi.id IS NOT NULL) as images
     FROM products p
     LEFT JOIN product_images pi ON pi.product_id = p.id
     WHERE p.id = $1
     GROUP BY p.id`,
      [req.params.id]
    );

    console.log("Final product with images:", completeProduct.rows[0]);
    console.log("=== PRODUCT UPDATE COMPLETE ===");

    // Invalidate product cache
    invalidateProductCache();

    sendSuccess(res, {
      product: completeProduct.rows[0],
      message: "Product updated successfully",
    });
  })
);

router.delete(
  "/products/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    // Product images will be deleted automatically via CASCADE
    const deleted = await deleteById("products", req.params.id);
    if (!deleted) {
      return sendNotFound(res, "Product");
    }
    sendSuccess(res, { message: "Product deleted successfully" });
  })
);

// Portfolio Projects CRUD
router.get(
  "/portfolio/projects",
  requireAuth,
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT id, title, description, imageurl, category, isactive, createdat FROM portfolioprojects ORDER BY createdat DESC"
    );
    sendSuccess(res, { projects: result.rows });
  })
);

router.get(
  "/portfolio/projects/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const project = await getById("portfolioprojects", req.params.id);
    if (!project) {
      return sendNotFound(res, "Project");
    }
    sendSuccess(res, { project });
  })
);

router.post(
  "/portfolio/projects",
  requireAuth,
  asyncHandler(async (req, res) => {
    const { title, description, category, isactive, imageurl } = req.body;
    const result = await query(
      `INSERT INTO portfolioprojects (title, description, category, isactive, imageurl, createdat)
     VALUES ($1, $2, $3, $4, $5, NOW()) RETURNING *`,
      [title, description, category, isactive !== false, imageurl || null]
    );
    sendSuccess(
      res,
      {
        project: result.rows[0],
        message: "Project created successfully",
      },
      HTTP_STATUS.CREATED
    );
  })
);

router.put(
  "/portfolio/projects/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const { title, description, category, isactive, imageurl } = req.body;
    const result = await query(
      `UPDATE portfolioprojects 
     SET title = $1, description = $2, category = $3, isactive = $4, imageurl = $5, updatedat = NOW()
     WHERE id = $6 RETURNING *`,
      [
        title,
        description,
        category,
        isactive !== false,
        imageurl || null,
        req.params.id,
      ]
    );

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

    sendSuccess(res, {
      project: result.rows[0],
      message: "Project updated successfully",
    });
  })
);

router.delete(
  "/portfolio/projects/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const deleted = await deleteById("portfolioprojects", req.params.id);
    if (!deleted) {
      return sendNotFound(res, "Project");
    }
    sendSuccess(res, { message: "Project deleted successfully" });
  })
);

// Blog Posts CRUD
router.get(
  "/blog",
  requireAuth,
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT id, title, slug, excerpt, ispublished, createdat FROM blogposts ORDER BY createdat DESC"
    );
    sendSuccess(res, { posts: result.rows });
  })
);

router.get(
  "/blog/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const post = await getById("blogposts", req.params.id);
    if (!post) {
      return sendNotFound(res, "Blog post");
    }
    sendSuccess(res, { post });
  })
);

router.post(
  "/blog",
  requireAuth,
  asyncHandler(async (req, res) => {
    const {
      title,
      slug,
      excerpt,
      content,
      metatitle,
      metadescription,
      ispublished,
    } = req.body;
    const result = await query(
      `INSERT INTO blogposts (title, slug, excerpt, content, metatitle, metadescription, ispublished, createdat)
     VALUES ($1, $2, $3, $4, $5, $6, $7, NOW()) RETURNING *`,
      [
        title,
        slug,
        excerpt,
        content,
        metatitle,
        metadescription,
        ispublished || false,
      ]
    );
    sendSuccess(
      res,
      {
        post: result.rows[0],
        message: "Blog post created successfully",
      },
      HTTP_STATUS.CREATED
    );
  })
);

router.put(
  "/blog/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const {
      title,
      slug,
      excerpt,
      content,
      metatitle,
      metadescription,
      ispublished,
    } = req.body;
    const result = await query(
      `UPDATE blogposts 
     SET title = $1, slug = $2, excerpt = $3, content = $4, metatitle = $5, 
         metadescription = $6, ispublished = $7, updatedat = NOW()
     WHERE id = $8 RETURNING *`,
      [
        title,
        slug,
        excerpt,
        content,
        metatitle,
        metadescription,
        ispublished || false,
        req.params.id,
      ]
    );

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

    sendSuccess(res, {
      post: result.rows[0],
      message: "Blog post updated successfully",
    });
  })
);

router.delete(
  "/blog/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const deleted = await deleteById("blogposts", req.params.id);
    if (!deleted) {
      return sendNotFound(res, "Blog post");
    }
    sendSuccess(res, { message: "Blog post deleted successfully" });
  })
);

// Custom Pages CRUD
router.get(
  "/pages",
  requireAuth,
  asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT id, title, slug, ispublished, createdat FROM pages ORDER BY createdat DESC"
    );
    sendSuccess(res, { pages: result.rows });
  })
);

router.get(
  "/pages/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const page = await getById("pages", req.params.id);
    if (!page) {
      return sendNotFound(res, "Page");
    }
    sendSuccess(res, { page });
  })
);

router.post(
  "/pages",
  requireAuth,
  asyncHandler(async (req, res) => {
    const {
      title,
      slug,
      content,
      contenthtml,
      metatitle,
      metadescription,
      ispublished,
      pagedata,
    } = req.body;

    // Generate readable ID from slug
    const pageId = `page-${slug}`;

    const result = await query(
      `INSERT INTO pages (id, title, slug, content, pagecontent, metatitle, metadescription, ispublished, isactive, pagedata, createdat)
     VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, NOW()) RETURNING *`,
      [
        pageId,
        title,
        slug,
        content,
        contenthtml || content,
        metatitle,
        metadescription,
        ispublished !== false,
        ispublished !== false,
        pagedata ? JSON.stringify(pagedata) : null,
      ]
    );
    sendSuccess(
      res,
      {
        page: result.rows[0],
        message: "Page created successfully",
      },
      HTTP_STATUS.CREATED
    );
  })
);

router.put(
  "/pages/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const {
      title,
      slug,
      content,
      contenthtml,
      metatitle,
      metadescription,
      ispublished,
      pagedata,
    } = req.body;
    const result = await query(
      `UPDATE pages 
     SET title = $1, slug = $2, content = $3, pagecontent = $4, metatitle = $5, 
         metadescription = $6, ispublished = $7, isactive = $8, pagedata = $9, updatedat = NOW()
     WHERE id = $10 RETURNING *`,
      [
        title,
        slug,
        content,
        contenthtml || content,
        metatitle,
        metadescription,
        ispublished !== false,
        ispublished !== false,
        pagedata ? JSON.stringify(pagedata) : null,
        req.params.id,
      ]
    );

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

    sendSuccess(res, {
      page: result.rows[0],
      message: "Page updated successfully",
    });
  })
);

router.delete(
  "/pages/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const deleted = await deleteById("pages", req.params.id);
    if (!deleted) {
      return sendNotFound(res, "Page");
    }
    sendSuccess(res, { message: "Page deleted successfully" });
  })
);

// Settings Management
const settingsHandler = (key) => ({
  get: asyncHandler(async (req, res) => {
    const result = await query(
      "SELECT settings FROM site_settings WHERE key = $1",
      [key]
    );
    const settings = result.rows.length > 0 ? result.rows[0].settings : {};
    sendSuccess(res, { settings });
  }),
  post: asyncHandler(async (req, res) => {
    const settings = req.body;
    await query(
      `INSERT INTO site_settings (key, settings, updatedat)
       VALUES ($1, $2, NOW())
       ON CONFLICT (key) DO UPDATE SET settings = $2, updatedat = NOW()`,
      [key, JSON.stringify(settings)]
    );
    sendSuccess(res, { message: `${key} settings saved successfully` });
  }),
});

// Homepage Settings
const homepageSettings = settingsHandler("homepage");
router.get("/homepage/settings", requireAuth, homepageSettings.get);
router.post("/homepage/settings", requireAuth, homepageSettings.post);

// General Settings
const generalSettings = settingsHandler("general");
router.get("/settings", requireAuth, generalSettings.get);
router.post("/settings", requireAuth, generalSettings.post);

// Menu Management
router.get(
  "/menu",
  requireAuth,
  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 || [] : [];
    sendSuccess(res, { items });
  })
);

router.post(
  "/menu",
  requireAuth,
  asyncHandler(async (req, res) => {
    const { items } = req.body;
    await query(
      `INSERT INTO site_settings (key, settings, updatedat)
     VALUES ('menu', $1, NOW())
     ON CONFLICT (key) DO UPDATE SET settings = $1, updatedat = NOW()`,
      [JSON.stringify({ items })]
    );
    sendSuccess(res, { message: "Menu saved successfully" });
  })
);

// ==================== TEAM MEMBERS CRUD ====================

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

// Get single team member
router.get(
  "/team-members/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const result = await query("SELECT * FROM team_members WHERE id = $1", [
      req.params.id,
    ]);
    if (result.rows.length === 0) {
      return sendNotFound(res, "Team member");
    }
    sendSuccess(res, { teamMember: result.rows[0] });
  })
);

// Create team member
router.post(
  "/team-members",
  requireAuth,
  asyncHandler(async (req, res) => {
    const { name, position, bio, image_url, display_order } = req.body;

    if (!name || !position) {
      return sendError(
        res,
        "Name and position are required",
        HTTP_STATUS.BAD_REQUEST
      );
    }

    const result = await query(
      `INSERT INTO team_members (name, position, bio, image_url, display_order, updated_at) 
       VALUES ($1, $2, $3, $4, $5, CURRENT_TIMESTAMP) 
       RETURNING *`,
      [name, position, bio || null, image_url || null, display_order || 0]
    );

    sendSuccess(
      res,
      {
        teamMember: result.rows[0],
        message: "Team member created successfully",
      },
      HTTP_STATUS.CREATED
    );
  })
);

// Update team member
router.put(
  "/team-members/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const { name, position, bio, image_url, display_order } = req.body;

    if (!name || !position) {
      return sendError(
        res,
        "Name and position are required",
        HTTP_STATUS.BAD_REQUEST
      );
    }

    const result = await query(
      `UPDATE team_members 
       SET name = $1, position = $2, bio = $3, image_url = $4, display_order = $5, updated_at = CURRENT_TIMESTAMP
       WHERE id = $6 
       RETURNING *`,
      [name, position, bio, image_url, display_order || 0, req.params.id]
    );

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

    sendSuccess(res, {
      teamMember: result.rows[0],
      message: "Team member updated successfully",
    });
  })
);

// Delete team member
router.delete(
  "/team-members/:id",
  requireAuth,
  asyncHandler(async (req, res) => {
    const result = await query(
      "DELETE FROM team_members WHERE id = $1 RETURNING *",
      [req.params.id]
    );

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

    sendSuccess(res, { message: "Team member deleted successfully" });
  })
);

module.exports = router;
