const db = require("../../db");
const path = require("path");
const fs = require("fs");
const { convertBufferFields } = require("../../utils/bufferUtils");

const StoryController = {
  createStory: async (req, res) => {
    try {
      const story = await db.PPStory.create(req.body);
      res.status(201).json({
        success: true,
        data: convertBufferFields(story),
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  getAllStories: async (req, res) => {
    try {
      const { page = 1, limit = 200, search, categoryId } = req.query;
      const offset = (page - 1) * limit;

      const where = {};
      if (search) {
        where.pps_title = { [db.Sequelize.Op.like]: `%${search}%` };
      }
      if (categoryId) {
        where.fk_ppa_id = categoryId;
      }

      const result = await db.PPStory.findAndCountAll({
        where,
        include: [
          {
            model: db.PPStoryData,
            as: "storyData",
            order: [["ppsd_order", "ASC"]],
          },
          {
            model: db.PPStoryCategory,
            as: "category",
          },
        ],
        order: [["pps_date_created", "DESC"]],
        limit: parseInt(limit),
        // offset: parseInt(offset),
      });

      res.json({
        success: true,
        data: result.rows.map(convertBufferFields),
        pagination: {
          total: result.count,
          pages: Math.ceil(result.count / limit),
          currentPage: parseInt(page),
          perPage: parseInt(limit),
        },
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  getStoryWithData: async (req, res) => {
    try {
      const story = await db.PPStory.findByPk(req.params.id, {
        include: [
          {
            model: db.PPStoryData,
            as: "storyData",
            order: [["ppsd_order", "ASC"]],
          },
          {
            model: db.PPStoryCategory,
            as: "category",
          },
        ],
      });

      if (!story) {
        return res.status(404).json({
          success: false,
          error: "Story not found",
        });
      }

      res.json({
        success: true,
        data: convertBufferFields(story),
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  getStoryImage: async (req, res) => {
    try {
      const filePath = path.join(
        __dirname,
        "../../uploads",
        req.params.filename
      );
      if (fs.existsSync(filePath)) {
        return res.sendFile(filePath);
      }
      res.status(404).send("Image not found");
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  addStoryData: async (req, res) => {
    try {
      const story = await db.PPStory.findByPk(req.params.id);
      if (!story) {
        return res.status(404).json({
          success: false,
          error: "Story not found",
        });
      }

      const createdData = await db.PPStoryData.create({
        ...req.body,
        fk_pps_id: req.params.id,
      });

      res.status(201).json({
        success: true,
        data: createdData,
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  updateStory: async (req, res) => {
    try {
      const [updated] = await db.PPStory.update(req.body, {
        where: { pps_id: req.params.id },
      });

      if (!updated) {
        return res.status(404).json({
          success: false,
          error: "Story not found",
        });
      }

      const updatedStory = await db.PPStory.findByPk(req.params.id, {
        include: [
          {
            model: db.PPStoryData,
            as: "storyData",
          },
          {
            model: db.PPStoryCategory,
            as: "category",
          },
        ],
      });

      res.json({
        success: true,
        data: convertBufferFields(updatedStory),
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  deleteStory: async (req, res) => {
    try {
      await db.sequelize.transaction(async (t) => {
        await db.PPStoryData.destroy({
          where: { fk_pps_id: req.params.id },
          transaction: t,
        });

        const deleted = await db.PPStory.destroy({
          where: { pps_id: req.params.id },
          transaction: t,
        });

        if (!deleted) {
          throw new Error("Story not found");
        }
      });

      res.json({
        success: true,
        message: "Story and all associated data deleted successfully",
      });
    } catch (error) {
      const status = error.message === "Story not found" ? 404 : 500;
      res.status(status).json({
        success: false,
        error: error.message,
      });
    }
  },

  // Category-related methods
  getAllCategories: async (req, res) => {
    try {
      const categories = await db.PPStoryCategory.findAll({
        where: { ppc_satus: 1 }, // Assuming 1 means active
        order: [["ppc_title", "ASC"]],
      });

      res.json({
        success: true,
        data: categories.map(convertBufferFields),
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  getCategoryById: async (req, res) => {
    try {
      const category = await db.PPStoryCategory.findByPk(req.params.id);
      if (!category) {
        return res.status(404).json({
          success: false,
          error: "Category not found",
        });
      }

      res.json({
        success: true,
        data: convertBufferFields(category),
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  createCategory: async (req, res) => {
    try {
      const category = await db.PPStoryCategory.create({
        ...req.body,
        ppc_created_date: new Date(),
      });
      res.status(201).json({
        success: true,
        data: convertBufferFields(category),
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  updateCategory: async (req, res) => {
    try {
      const [updated] = await db.PPStoryCategory.update(req.body, {
        where: { ppc_id: req.params.id },
      });

      if (!updated) {
        return res.status(404).json({
          success: false,
          error: "Category not found",
        });
      }

      const updatedCategory = await db.PPStoryCategory.findByPk(req.params.id);

      res.json({
        success: true,
        data: convertBufferFields(updatedCategory),
      });
    } catch (error) {
      res.status(500).json({
        success: false,
        error: error.message,
      });
    }
  },

  deleteCategory: async (req, res) => {
    try {
      await db.sequelize.transaction(async (t) => {
        // First check if there are any stories using this category
        const storiesCount = await db.PPStory.count({
          where: { fk_ppa_id: req.params.id },
          transaction: t,
        });

        if (storiesCount > 0) {
          throw new Error(
            "Cannot delete category because it has associated stories"
          );
        }

        const deleted = await db.PPStoryCategory.destroy({
          where: { ppc_id: req.params.id },
          transaction: t,
        });

        if (!deleted) {
          throw new Error("Category not found");
        }
      });

      res.json({
        success: true,
        message: "Category deleted successfully",
      });
    } catch (error) {
      const status = error.message === "Category not found" ? 404 : 500;
      res.status(status).json({
        success: false,
        error: error.message,
      });
    }
  },
};

module.exports = StoryController;
