const { DataTypes, Op } = require("sequelize");
const sequelize = require("../../config/sequelize");

const path = require("path");
const fs = require("fs");
const { categoryModel } = require("./categoryModel");

const uploadDir = "uploads/blog_images";
const blogPostModel = sequelize.define(
  "blog_post",
  {
    section: { type: DataTypes.INTEGER, allowNull: false, defaultValue: 1 },
    title: { type: DataTypes.STRING, allowNull: false },
    slug: { type: DataTypes.STRING, allowNull: false, unique: true },
    feature_image: { type: DataTypes.STRING, allowNull: true },
    image_alt: { type: DataTypes.STRING, allowNull: true },
    content: { type: DataTypes.TEXT, allowNull: false },
    category_id: { type: DataTypes.INTEGER, allowNull: false },
    is_featured: { type: DataTypes.BOOLEAN, defaultValue: false },
    is_active: { type: DataTypes.BOOLEAN, defaultValue: true },
    created_by: { type: DataTypes.INTEGER, allowNull: false },
  },
  {
    tableName: "blog_posts",
    underscored: true,
  }
);


// ✅ Add association
blogPostModel.belongsTo(categoryModel, {
  foreignKey: "category_id",
  as: "category_details"
});


const blogPost = {
  create: async (data) => {
    try {
      if (!data.title) return { error: "Post title is required." };
      if (!data.slug) return { error: "Post slug is required." };

      const exists = await blogPostModel.findOne({
        where: { slug: data.slug },
      });
      if (exists) return { error: "Post slug already exists." };

      const newPost = await blogPostModel.create(data);
      return newPost;
    } catch (err) {
      throw err;
    }
  },

  getAll: async (filters = {}) => {
    try {
      const posts = await blogPostModel.findAll({
        where: filters, 
        order: [["created_at", "DESC"]],
        include: [
          {
            model: categoryModel,
            as: "category_details",
          },
        ],

      });

      const baseUrl = process.env.BASE_URL || "http://localhost:3000";

      const enrichedPosts = posts.map((post) => {
        const postData = post.toJSON();

        if (
          postData.feature_image &&
          !postData.feature_image.startsWith("http")
        ) {
          postData.feature_image =
            baseUrl.replace(/\/$/, "") + postData.feature_image;
        }

        return postData;
      });

      return enrichedPosts;
    } catch (err) {
      throw err;
    }
  },

  getSingle: async (id) => {
    try {
      const post = await blogPostModel.findByPk(id 
        , {
          include: [
            {
              model: categoryModel,
              as: "category_details",
            },
          ],
        }
      );
      if (!post) return null;

      const postData = post.toJSON();

      const baseUrl = process.env.BASE_URL || "http://localhost:3000";

      if (
        postData.feature_image &&
        !postData.feature_image.startsWith("http")
      ) {
        postData.feature_image =
          baseUrl.replace(/\/$/, "") + postData.feature_image;
      }

      return postData;
    } catch (err) {
      throw err;
    }
  },

  getSinglebyslug: async (slug) => {
  try {
    const post = await blogPostModel.findOne({
      where: { slug: slug },
    });
    if (!post) return null;

    const postData = post.toJSON();

    const baseUrl = process.env.BASE_URL || "http://localhost:3000";

    if (
      postData.feature_image &&
      !postData.feature_image.startsWith("http")
    ) {
      postData.feature_image =
        baseUrl.replace(/\/$/, "") + postData.feature_image;
    }

    return postData;
  } catch (err) {
    throw err;
  }
},


  update: async (id, data) => {
    try {
      const record = await blogPostModel.findByPk(id);
      if (!record) return null;

      // -------- unique-slug check ----------
      if (data.slug && data.slug !== record.slug) {
        const dup = await blogPostModel.findOne({
          where: { slug: data.slug, id: { [Op.ne]: id } },
        });
        if (dup) return { error: "Post slug already exists." };
      }

      // -------- handle image replacement ----------
      if (data.feature_image && record.feature_image) {
        // remove leading slash so paths match
        const oldPath = path.join(
          process.cwd(),
          record.feature_image.startsWith("/")
            ? record.feature_image.slice(1)
            : record.feature_image
        );

        if (fs.existsSync(oldPath)) {
          fs.unlinkSync(oldPath);
        }
      }

      await blogPostModel.update(data, {
        where: { id },
        individualHooks: true,
      });

      return await blogPostModel.findByPk(id);
    } catch (err) {
      throw err;
    }
  },

  delete: async (id) => {
    try {
      const deleted = await blogPostModel.destroy({ where: { id } });
      if (!deleted) return null;
      return { message: "Post deleted successfully!" };
    } catch (err) {
      throw err;
    }
  },
};

module.exports = { blogPostModel, blogPost };
