const {
  addBaseUrlToImages,
  getFullImageUrl,
} = require("../utils/imageHelper");
const Home = require("../models/home");
const Blog = require("../models/blog");
const writeAuditLog = require("../audit/writeAuditLog");
const diffObject = require("../audit/diffObject");
const AUDIT_ACTIONS = require("../constants/auditAction");

// Các hàm hỗ trợ
const getHomeDoc = async () => Home.findOne().sort({ updatedAt: -1 });
const getAllHomeDocs = async () => Home.find().sort({ updatedAt: -1 });
const getHomeData = async () => (await getHomeDoc())?.toObject() || {};
const getOrCreateHomeDoc = async () => {
  let doc = await getHomeDoc();

  if (!doc) {
    doc = new Home(getDefaultHomeData());
  }

  return doc;
};

const hasMeaningfulValue = (value) =>
  typeof value === "string" && value.trim().length > 0;

const getMeaningfulHeroSlides = (hero = {}) => {
  if (!Array.isArray(hero.slides)) return [];

  return hero.slides.filter((slide = {}) => {
    return (
      hasMeaningfulValue(slide.title) ||
      hasMeaningfulValue(slide.subtitle) ||
      hasMeaningfulValue(slide.description) ||
      hasMeaningfulValue(slide.heroImage) ||
      hasMeaningfulValue(slide.videoUrl) ||
      hasMeaningfulValue(slide.primaryButton?.label) ||
      hasMeaningfulValue(slide.primaryButton?.href) ||
      hasMeaningfulValue(slide.secondaryButton?.label) ||
      hasMeaningfulValue(slide.secondaryButton?.href)
    );
  });
};

const scoreHeroSlides = (slides = []) =>
  slides.reduce((score, slide = {}) => {
    return (
      score +
      (slide.title || "").trim().length * 3 +
      (slide.subtitle || "").trim().length +
      (slide.description || "").trim().length * 2 +
      (slide.primaryButton?.label || "").trim().length +
      (slide.primaryButton?.href || "").trim().length +
      (slide.secondaryButton?.label || "").trim().length +
      (slide.secondaryButton?.href || "").trim().length +
      (hasMeaningfulValue(slide.heroImage) ? 20 : 0) +
      (hasMeaningfulValue(slide.videoUrl) ? 12 : 0)
    );
  }, 0);

const scoreHeroData = (hero = {}) => {
  const slides = getMeaningfulHeroSlides(hero);

  if (slides.length > 0) {
    return scoreHeroSlides(slides) + slides.length * 30;
  }

  return (
    (hero.title || "").trim().length * 3 +
    (hero.subtitle || "").trim().length +
    (hero.description || "").trim().length * 2 +
    (hero.primaryButton?.label || "").trim().length +
    (hero.primaryButton?.href || "").trim().length +
    (hero.secondaryButton?.label || "").trim().length +
    (hero.secondaryButton?.href || "").trim().length +
    (hasMeaningfulValue(hero.heroImage) ? 20 : 0) +
    (hasMeaningfulValue(hero.videoUrl) ? 12 : 0)
  );
};

const getPreferredHeroData = (docs = []) => {
  const heroes = docs
    .map((doc) => doc?.hero)
    .filter(Boolean);

  if (!heroes.length) return {};

  return heroes.reduce((bestHero, currentHero) => {
    return scoreHeroData(currentHero) > scoreHeroData(bestHero)
      ? currentHero
      : bestHero;
  }, heroes[0]);
};

const normalizeStoredImagePath = (imagePath) => {
  if (!imagePath || typeof imagePath !== "string") return "";

  const raw = imagePath.trim();
  if (!raw) return "";

  const knownPrefixes = ["/uploads/", "/assets/", "/img/"];

  for (const prefix of knownPrefixes) {
    const index = raw.indexOf(prefix);
    if (index >= 0) {
      return raw.slice(index);
    }
  }

  if (raw.startsWith("/")) {
    return raw;
  }

  return `/${raw}`;
};

const getDefaultFloatingContactData = () => ({
  enabled: true,
  position: "bottom-right",
  panelTitle: "Do you need any additional advice or support?",
  brand: {
    imageSrc: "/assets/img/logo/black-logo.svg",
    imageAlt: "HAI Learning",
  },
  trigger: {
    imageSrc: "",
    icon: "fa-comments",
  },
  actions: [
    {
      id: "facebook",
      platform: "facebook",
      enabled: true,
      label: "Message via Facebook",
      subtitle: "facebook.com/hailearning.edu.vn",
      href: "https://www.facebook.com/hailearning.edu.vn/",
      iconImage: "/uploads/home/floating-contact/Facebook_Logo_Primary.webp",
      iconType: "iconClass",
      iconClass: "fa-brands fa-facebook-messenger",
      iconText: "",
      order: 1,
    },
    {
      id: "zalo",
      platform: "zalo",
      enabled: true,
      label: "Message via Zalo",
      subtitle: "zalo.me/84961834040",
      href: "https://zalo.me/84961834040",
      iconImage: "/uploads/home/floating-contact/Icon_of_Zalo.svg.webp",
      iconType: "iconText",
      iconClass: "",
      iconText: "Zalo",
      order: 2,
    },
  ],
});

const normalizeFloatingContactData = (payload = {}) => {
  const defaults = getDefaultFloatingContactData();
  const brand = payload.brand || {};
  const trigger = payload.trigger || {};
  const hasProvidedActions = Array.isArray(payload.actions);
  const rawActions = hasProvidedActions ? payload.actions : [];

  const actions = rawActions
    .map((action, index) => ({
      id: String(action.id || `${action.platform || "action"}-${index + 1}`),
      platform: String(action.platform || "").trim(),
      enabled: action.enabled !== false,
      label: String(action.label || "").trim(),
      subtitle: String(action.subtitle || "").trim(),
      href: String(action.href || "").trim(),
      iconImage: normalizeStoredImagePath(String(action.iconImage || "").trim()),
      iconType: action.iconType === "iconText" ? "iconText" : "iconClass",
      iconClass: String(action.iconClass || "").trim(),
      iconText: String(action.iconText || "").trim(),
      order: Number.isFinite(Number(action.order)) ? Number(action.order) : index + 1,
    }))
    .filter((action) => {
      return (
        action.platform ||
        action.label ||
        action.subtitle ||
        action.href ||
        action.iconImage ||
        action.iconClass ||
        action.iconText
      );
    })
    .sort((a, b) => a.order - b.order)
    .map((action, index) => ({
      ...action,
      order: index + 1,
    }));

  return {
    enabled: payload.enabled !== false,
    position: payload.position || defaults.position,
    panelTitle: String(payload.panelTitle || defaults.panelTitle).trim(),
    brand: {
      imageSrc: normalizeStoredImagePath(
        String(brand.imageSrc || defaults.brand.imageSrc).trim(),
      ),
      imageAlt: String(brand.imageAlt || defaults.brand.imageAlt).trim(),
    },
    trigger: {
      imageSrc: normalizeStoredImagePath(
        String(trigger.imageSrc || "").trim(),
      ),
      icon: String(trigger.icon || defaults.trigger.icon).trim() || defaults.trigger.icon,
    },
    actions: hasProvidedActions ? actions : defaults.actions,
  };
};

const getDefaultHomeData = () => ({
  hero: {
    backgroundImage: "",
    slides: [],
    title: "",
    subtitle: "",
    description: "",
    heroImage: "",
    videoUrl: "",
    primaryButton: {},
    secondaryButton: {},
  },
  whyChooseUs: {
    heading: "",
    subheading: "",
    description: "",
    highlightWord: "",
    mainImage: "",
    secondaryImage: "",
    items: [],
    features: [],
    ctaButton: {},
  },
  visaSolutions: { heading: "", subheading: "", items: [] },
  visaCountries: {
    heading: "",
    subheading: "",
    description: "",
    countries: [],
    ctaButton: {},
  },
  testimonials: {
    heading: "",
    subheading: "",
    videoUrl: "",
    videoThumbnail: "",
    items: [],
  },
  videoGallery: { heading: "", videoUrl: "", thumbnail: "" },
  faq: {
    heading: "",
    subheading: "",
    description: "",
    ctaButton: {},
    items: [],
  },
  achievements: { heading: "", subheading: "", items: [] },
  partners: { visaConsultancy: { items: [] }, brands: { items: [] } },
  blogPreview: {
    heading: "Latest Insights & Updates",
    subheading: "Visa Tips & Guides",
    ctaButton: { label: "View All Articles", href: "/blog" },
    items: [],
    selectedBlogIds: [], // Array of manually selected blog IDs
  },
  floatingContact: getDefaultFloatingContactData(),
});

// Admin: Xem trang quản lý
exports.index = async (req, res) => {
  try {
    let data = await getHomeData();
    const defaults = getDefaultHomeData();

    // Merge dữ liệu mặc định cho tất cả các phần
    const sections = Object.keys(defaults);
    sections.forEach((s) => {
      data[s] = data[s] || defaults[s];
    });
    data.floatingContact = normalizeFloatingContactData(data.floatingContact);

    const frontendUrl = process.env.FRONTEND_URL || "http://localhost:3000";
    const backendUrl = `${req.protocol}://${req.get("host")}`;

    // Lấy tất cả blog để chọn trong CMS
    const allBlogs = await Blog.find({ status: "published" })
      .sort({ createdAt: -1 })
      .lean();

    return res.render("admin/home/index", {
      layout: "layouts/main",
      title: "Home Management",
      data,
      allBlogs,
      frontendUrl,
      backendUrl,
      getFullImageUrl,
      currentPath: req.path,
      user: req.session.user,
    });
  } catch (err) {
    console.error("Home index error:", err);
    req.flash("error_msg", "Error loading home data");
    return req.session.save(() => res.redirect("/admin/dashboard"));
  }
};

// Admin: Cập nhật dữ liệu (tập trung vào achievements, partners; các phần khác giữ nguyên nếu không có dữ liệu mới)
exports.update = async (req, res) => {
  try {
    const sections = [
      "hero",
      "whyChooseUs",
      "visaSolutions",
      "visaCountries",
      "testimonials",
      "videoGallery",
      "faq",
      "achievements",
      "partners",
      "blogPreview",
      "floatingContact",
    ];

    let doc = await getHomeDoc();
    const beforeData = doc ? JSON.parse(JSON.stringify(doc.toObject())) : {};

    if (!doc) {
      doc = new Home({});
    }

    let hasChanges = false;
    const updatedSections = [];

    for (const section of sections) {
      if (req.body[section]) {
        try {
          const payload = JSON.parse(req.body[section]);
          // Gán trực tiếp vào doc, Mongoose sẽ tự check schema
          doc[section] =
            section === "floatingContact"
              ? normalizeFloatingContactData(payload)
              : payload;
          doc.markModified(section);
          hasChanges = true;
          updatedSections.push(section);
        } catch (e) {
          console.error(`Invalid JSON for ${section}:`, e);
        }
      }
    }

    if (!hasChanges) {
      req.flash("info_msg", "No changes were made");
      return req.session.save(() => res.redirect("/admin/home"));
    }

    await doc.save();
    const afterData = JSON.parse(JSON.stringify(doc.toObject()));

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

    req.flash("success_msg", "Home page configuration has been updated!");
    return req.session.save(() => res.redirect("/admin/home"));
  } catch (err) {
    console.error("Home update error:", err);
    req.flash("error_msg", `Update error: ${err.message}`);
    return req.session.save(() => res.redirect("/admin/home"));
  }
};

exports.updateFloatingContact = async (req, res) => {
  try {
    const payload =
      typeof req.body?.floatingContact === "string"
        ? JSON.parse(req.body.floatingContact)
        : req.body?.floatingContact || req.body;

    const doc = await getOrCreateHomeDoc();
    const beforeData = JSON.parse(JSON.stringify(doc.toObject()));

    doc.floatingContact = normalizeFloatingContactData(payload);
    doc.markModified("floatingContact");
    await doc.save();

    const afterData = JSON.parse(JSON.stringify(doc.toObject()));
    const changes = diffObject(beforeData, afterData);

    if (changes.length > 0) {
      await writeAuditLog({
        model: "Home",
        documentId: doc._id,
        action: AUDIT_ACTIONS.UPDATE_HOME,
        before: beforeData,
        after: afterData,
        changes,
        req,
      });
    }

    return res.status(200).json({
      success: true,
      message: "Floating contact updated successfully",
      floatingContact: doc.floatingContact,
    });
  } catch (err) {
    console.error("Floating contact update error:", err);
    return res.status(500).json({
      success: false,
      error: err.message || "Failed to update floating contact",
    });
  }
};

// Public API// API lấy danh sách blog cho CMS
exports.apiGetBlogs = async (req, res) => {
  try {
    const blogs = await Blog.find({ status: "published" })
      .sort({ createdAt: -1 })
      .select("title slug featuredImage author publishedAt")
      .lean();
    res.json(blogs);
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
};
exports.api = async (req, res) => {
  try {
    const docs = await getAllHomeDocs();
    let data = docs[0]?.toObject() || {};
    const baseUrl = `${req.protocol}://${req.get("host")}`;

    if (docs.length > 1) {
      data.hero = getPreferredHeroData(docs.map((doc) => doc.toObject()));
    }

    // === Xử lý Blog Preview động ===
    const blogPreview = data.blogPreview || {};
    let blogs = [];

    // Nếu có chọn blog cụ thể
    if (blogPreview.selectedBlogIds && blogPreview.selectedBlogIds.length > 0) {
      blogs = await Blog.find({
        _id: { $in: blogPreview.selectedBlogIds },
        status: "published",
      }).lean();

      // Sắp xếp theo thứ tự đã chọn trong selectedBlogIds
      blogs.sort((a, b) => {
        return (
          blogPreview.selectedBlogIds.indexOf(a._id.toString()) -
          blogPreview.selectedBlogIds.indexOf(b._id.toString())
        );
      });
    }

    // Nếu không chọn hoặc chọn nhưng không đủ, lấy thêm 3 bài mới nhất (hoặc bù vào)
    if (blogs.length === 0) {
      blogs = await Blog.find({ status: "published" })
        .sort({ createdAt: -1 })
        .limit(3)
        .lean();
    }

    // Map dữ liệu blog sang format mà frontend mong đợi
    blogPreview.items = blogs.map((blog) => ({
      title: blog.title,
      excerpt: blog.excerpt,
      category: blog.category && blog.category[0] ? blog.category[0] : "Visa",
      date: blog.publishedAt || blog.createdAt,
      author: {
        name: blog.author || "Admin",
        avatar: "", // Frontend đang tự xử lý hoặc dùng logo hệ thống
      },
      comments: blog.commentsCount || 0,
      link: `/blog/${blog.slug}`,
      thumbnail: blog.featuredImage,
    }));

    data.blogPreview = blogPreview;
    data.floatingContact = normalizeFloatingContactData(data.floatingContact);
    // ===============================

    const processed = addBaseUrlToImages(data, baseUrl);
    return res.json(processed);
  } catch (err) {
    console.error("Home API error:", err);
    return res.status(500).json({ error: "Error loading home data" });
  }
};
