const { addBaseUrlToImages } = require("../utils/imageHelper");
const Footer = require("../models/footer");
const writeAuditLog = require("../audit/writeAuditLog");
const diffObject = require("../audit/diffObject");
const AUDIT_ACTIONS = require("../constants/auditAction");

const isPlainObject = (value) =>
  value && typeof value === "object" && !Array.isArray(value);

const normalizeFooterImagePath = (value) => {
  if (!value || typeof value !== "string") return "";

  const trimmed = value.trim();
  if (!trimmed) return "";

  if (trimmed.startsWith("/uploads/footer/")) {
    return trimmed;
  }

  if (trimmed.startsWith("uploads/footer/")) {
    return `/${trimmed}`;
  }

  if (/^https?:\/\//i.test(trimmed)) {
    try {
      const parsed = new URL(trimmed);
      if (parsed.pathname.startsWith("/uploads/footer/")) {
        return parsed.pathname;
      }
    } catch (error) {
      console.warn("Failed to parse footer image URL:", trimmed, error.message);
    }
  }

  return trimmed;
};

const sanitizeFooterData = (data = {}) => {
  const sanitized = JSON.parse(JSON.stringify(data || {}));

  if (!sanitized.top) {
    return sanitized;
  }

  if (typeof sanitized.top.bgImage === "string") {
    sanitized.top.bgImage = normalizeFooterImagePath(sanitized.top.bgImage);
  }

  if (sanitized.top.logo && typeof sanitized.top.logo.src === "string") {
    sanitized.top.logo.src = normalizeFooterImagePath(sanitized.top.logo.src);
  }

  return sanitized;
};

const mergeFooterData = (currentValue, incomingValue) => {
  if (incomingValue === undefined) {
    return currentValue;
  }

  if (Array.isArray(incomingValue)) {
    return incomingValue;
  }

  if (isPlainObject(currentValue) && isPlainObject(incomingValue)) {
    const merged = { ...currentValue };

    Object.keys(incomingValue).forEach((key) => {
      merged[key] = mergeFooterData(currentValue[key], incomingValue[key]);
    });

    return merged;
  }

  return incomingValue;
};

// GET /api/footer - Public API cho website và CMS load dữ liệu
exports.getFooter = async (req, res) => {
  try {
    const footer = await Footer.getSingle();
    const processedData = addBaseUrlToImages(footer.toObject());

    res.json(processedData);
  } catch (error) {
    console.error("Error getting footer:", error);
    res.status(500).json({
      error: "Failed to get footer data",
    });
  }
};

// PUT /api/admin/footer - Update toàn bộ footer cho CMS
exports.updateFooter = async (req, res) => {
  try {
    let updateData = req.body;

    console.log("=== FOOTER UPDATE REQUEST RECEIVED ===");
    console.log("Raw body:", JSON.stringify(req.body, null, 2));

    // Nếu có footerJson, parse nó (tương tự Header logic)
    if (updateData.footerJson && typeof updateData.footerJson === "string") {
      try {
        const parsedData = JSON.parse(updateData.footerJson);
        console.log("✓ Parsed footerJson successfully:", parsedData);
        updateData = parsedData;
      } catch (e) {
        console.error("✗ Error parsing footerJson:", e.message);
        return res.status(400).json({
          success: false,
          message: "Invalid JSON in footerJson: " + e.message,
        });
      }
    }

    updateData = sanitizeFooterData(updateData);

    // Lấy footer hiện tại hoặc tạo mới (giống Header logic)
    let footer = await Footer.findOne();

    if (!footer) {
      console.log("No existing footer found, creating new one");
      footer = new Footer(updateData);
      await footer.save();
      console.log("✓ Footer created:", footer._id);
    } else {
      console.log("✓ Found existing footer:", footer._id);
      const mergedData = mergeFooterData(footer.toObject(), updateData);
      // Use set() so nested footer fields persist correctly in MongoDB
      footer.set(mergedData);
      await footer.save();
      console.log("✓ Footer updated successfully");
    }

    const processedData = addBaseUrlToImages(footer.toObject());

    console.log("Updated footer data:", JSON.stringify(processedData, null, 2));

    res.json({
      success: true,
      message: "Footer updated successfully",
      data: processedData,
    });
  } catch (error) {
    console.error("✗ Error updating footer:", error);
    res.status(500).json({
      success: false,
      error: "Failed to update footer: " + error.message,
    });
  }
};

// Render admin view (giữ lại cho UI hiện tại)
exports.index = async (req, res) => {
  try {
    const data = await Footer.getSingle();

    res.render("admin/footer/index", {
      title: "Footer Management",
      data: data.toObject(),
    });
  } catch (error) {
    console.error("Error in footer index:", error);
    req.flash("error_msg", "An error occurred while loading the page");
    res.redirect("/admin/dashboard");
  }
};

// Update method cho form hiện tại (giống Header pattern)
exports.update = async (req, res) => {
  try {
    let updateData = req.body;

    console.log("=== FOOTER FORM UPDATE REQUEST RECEIVED ===");
    console.log("Raw body:", JSON.stringify(req.body, null, 2));

    // Nếu có footerJson, parse nó (giống Header logic)
    if (updateData.footerJson && typeof updateData.footerJson === "string") {
      try {
        const parsedData = JSON.parse(updateData.footerJson);
        console.log("✓ Parsed footerJson successfully:", parsedData);
        updateData = parsedData;
      } catch (e) {
        console.error("✗ Error parsing footerJson:", e.message);
        req.flash("error_msg", "Invalid JSON in footerJson: " + e.message);
        return res.redirect("/admin/footer");
      }
    }

    updateData = sanitizeFooterData(updateData);

    // Lấy footer hiện tại hoặc tạo mới (giống Header)
    let footer = await Footer.findOne();

    // ✅ Capture BEFORE state
    const beforeData = footer
      ? JSON.parse(JSON.stringify(footer.toObject()))
      : {};

    if (!footer) {
      console.log("No existing footer found, creating new one");
      footer = new Footer(updateData);
      await footer.save();
      console.log("✓ Footer created:", footer._id);
      req.flash("success_msg", "Footer created successfully");
    } else {
      console.log("✓ Found existing footer:", footer._id);
      const mergedData = mergeFooterData(footer.toObject(), updateData);
      // Use set() so nested footer fields persist correctly in MongoDB
      footer.set(mergedData);
      await footer.save();

      // ✅ Capture AFTER state
      const afterData = JSON.parse(JSON.stringify(footer.toObject()));

      // ✅ AUDIT LOGGING - Footer Updated
      const changes = diffObject(beforeData, afterData);
      if (changes.length > 0) {
        await writeAuditLog({
          model: "Footer",
          documentId: footer._id,
          action: AUDIT_ACTIONS.UPDATE_FOOTER,
          before: beforeData,
          after: afterData,
          changes,
          req,
        });
      }

      console.log("✓ Footer updated successfully");
      req.flash("success_msg", "Footer updated successfully");
    }

    const activeTab = req.body.activeTab || "about";
    res.redirect(`/admin/footer?activeTab=${activeTab}`);
  } catch (err) {
    console.error("✗ Error updating footer:", err);
    req.flash("error_msg", err.message || "Error updating footer");
    res.redirect("/admin/footer");
  }
};

// Legacy API endpoints (giữ lại cho tương thích)
exports.api = exports.getFooter;
exports.getFooterData = async (req, res) => {
  try {
    const footer = await Footer.getSingle();
    res.json(footer.toObject());
  } catch (error) {
    console.error("Error getting footer data for admin:", error);
    res.status(500).json({
      error: "Failed to get footer data",
    });
  }
};
