const SellerUnivTopics = require("../../models/SellerUnivTopics");
const SellerUnivArticles = require("../../models/SellerUnivArticles");
const SellerUnivVideos = require("../../models/SellerUnivVideos");
const SellerUnivTopicVideosWatchHistory = require("../../models/SellerUnivVideosWatchHistory");
const Sequelize = require("sequelize");
const { generateRandomWords } = require("../../helpers/common");

exports.getTopics = async (req, res, next) => {
  const { page = 1, limit = 20 } = req.pagination;
  const { keyword = "" } = req.query;
  try {
    const whereClause = {
      status: true,
    };

    if (keyword !== "" || keyword !== null) {
      const topicWhere = {
        [Sequelize.Op.like]: `%${keyword}%`,
      };
      whereClause.topic_title = topicWhere;
    }

    const offset = (page - 1) * limit;

    const sellerTopicsPromise = SellerUnivTopics.findAll({
      where: whereClause,
      limit,
      offset,
    });

    const sellerTopicsCountPromise = SellerUnivTopics.count({
      where: whereClause,
      limit,
      offset,
    });

    const [sellerTopics, sellerTopicsCount] = await Promise.all([sellerTopicsPromise, sellerTopicsCountPromise]);

    const totalPages = Math.ceil(sellerTopicsCount / limit);
    const hasNextPage = (page - 1) * limit + sellerTopics.length < totalPages;
    const hasPreviousPage = page > 1;

    res.status(200).json({
      success: true,
      response: sellerTopics,
      pagination: {
        totalPages,
        currentPage: page,
        hasNextPage,
        hasPreviousPage,
      },
    });
  } catch (err) {
    next(err);
  }
};

exports.getTopicDetailByGuid = async (req, res, next) => {
  const { guid } = req.params;

  if (!guid) return res.status(400).json({ success: false, message: "Invalid GUID" });
  const whereClause = {
    status: true,
    Guid: guid,
  };

  try {
    const sellerTopic = await SellerUnivTopics.findOne({
      where: whereClause,
      include: [
        {
          model: SellerUnivArticles,
          as: "topic_articles",
        },
        {
          model: SellerUnivVideos,
          as: "topic_videos",
        },
      ],
    });

    if (!sellerTopic) return res.status(400).json({ success: false, message: "No results." });

    res.status(200).json({ success: true, response: sellerTopic });
  } catch (err) {
    next(err);
  }
};

exports.getArticleDetailById = async (req, res, next) => {
  const { articleId } = req.params;
  if (!articleId) return res.status(400).json({ success: false, message: "Invalid Id" });
  const whereClause = {
    status: true,
    id: articleId,
  };

  try {
    const article = await SellerUnivArticles.findOne({
      where: whereClause,
    });

    if (!article) return res.status(400).json({ success: false, message: "No results." });
    res.status(200).json({ success: true, response: article });
  } catch (err) {
    next(err);
  }
};

exports.getTopicVideosByTopicGuid = async (req, res, next) => {
  const { guid } = req.params;
  if (!guid) return res.status(400).json({ success: false, message: "Invalid GUID." });

  const whereClause = {
    status: true,
    Guid: guid,
  };

  try {
    const sellerVideos = await SellerUnivTopics.findOne({
      where: whereClause,
      attributes: ["id", "Guid"],
      include: [
        {
          model: SellerUnivVideos,
          as: "topic_videos",
          required: true,
        },
      ],
    });

    if (!sellerVideos) return res.status(400).json({ success: false, message: "No results." });
    res.status(200).json({ success: true, response: sellerVideos });
  } catch (err) {
    next(err);
  }
};

exports.getVideoDetailByID = async (req, res, next) => {
  const { videoId } = req.params;
  const { seller_id, seller_account_id } = req;
  if (!videoId) return res.status(400).json({ success: false, message: "Invalid Id" });

  try {
    const whereClause = {
      status: true,
      id: videoId,
    };

    const sellerVideoPromise = SellerUnivVideos.findOne({
      where: whereClause,
    });

    const sellerWatchHistoryPromise = SellerUnivTopicVideosWatchHistory.findAll({
      where: {
        seller_id: seller_id,
        seller_account_id: seller_account_id,
      },
    });

    const [sellerVideo, sellerWatchHistory] = await Promise.all([sellerVideoPromise, sellerWatchHistoryPromise]);

    if (!sellerVideo) return res.status(400).json({ success: false, message: "No results." });

    sellerVideo.views_count += 1;
    const sellerVideoWatchCounter = sellerVideo.save();
    const sellerWatchHistory_ = SellerUnivTopicVideosWatchHistory.create({
      seller_univ_topic_videos_id: videoId,
      seller_id,
      seller_account_id,
    });

    const history = await Promise.all([sellerVideoWatchCounter, sellerWatchHistory_]);

    res.status(200).json({ success: true, response: sellerVideo, have_watched: sellerWatchHistory.length > 0 });
  } catch (err) {
    next(err);
  }
};

// Development Purposes

function getRandomArrayElement(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

exports.createUnivTopics = async (req, res, next) => {
  try {
    const randomImgUrls = [
      "https://t4.ftcdn.net/jpg/05/72/82/85/360_F_572828530_ofzCYowQVnlOwkcoBJnZqT36klbJzWdn.jpg",
      "https://img.freepik.com/premium-photo/cool-wallpaper-landscape-background_915164-76494.jpg",
      "https://atd-blog.s3.us-east-2.amazonaws.com/wp-content/uploads/2022/05/16150415/4-cool-iphone-wallpapers-1024x576.webp",
      "https://img.freepik.com/premium-photo/aesthetic-mountain-synthwave-retrowave-wallpaper-with-cool-vibrant-neon-design_1272857-172958.jpg",
      "https://t4.ftcdn.net/jpg/08/56/45/37/360_F_856453743_fUD0l94ehJyTJIDUHFDxxFZRtflvCMq5.jpg",
    ];

    const randomVideoUrls = [
      "https://www.example.com/video1.mp4",
      "https://www.example.com/video2.mp4",
      "https://www.example.com/video3.mp4",
      "https://www.example.com/video4.mp4",
      "https://www.example.com/video5.mp4",
    ];

    const randomTopicTitle = generateRandomWords(10);
    const randomTopicDescription = generateRandomWords(500);
    const randomTopicImage = getRandomArrayElement(randomImgUrls);

    const demoTopic = await SellerUnivTopics.create({
      topic_title: randomTopicTitle.join(" "),
      topic_description: randomTopicDescription.join(" "),
      topic_image: randomTopicImage,
    });

    const numberOfArticles = Math.floor(Math.random() * 5) + 1;
    const numberOfVideos = Math.floor(Math.random() * 5) + 1;

    const demoArticlesPromises = [];
    for (let i = 0; i < numberOfArticles; i++) {
      const randomArticleTitle = generateRandomWords(10);
      const randomArticleDescription = generateRandomWords(500);
      const randomArticleContent = generateRandomWords(1500);

      demoArticlesPromises.push(
        SellerUnivArticles.create({
          seller_univ_topic_id: demoTopic.id,
          article_title: randomArticleTitle.join(" "),
          article_description: randomArticleDescription.join(" "),
          article_content: randomArticleContent.join(" "),
        })
      );
    }

    const demoVideosPromises = [];
    for (let i = 0; i < numberOfVideos; i++) {
      const randomVideoTitle = generateRandomWords(20);
      const randomVideoDescription = generateRandomWords(150);
      const randomVideoUrl = getRandomArrayElement(randomVideoUrls);
      const randomVideoThumbnail = getRandomArrayElement(randomImgUrls);

      demoVideosPromises.push(
        SellerUnivVideos.create({
          seller_univ_topic_id: demoTopic.id,
          video_title: randomVideoTitle.join(" "),
          video_description: randomVideoDescription.join(" "),
          video_filename: randomVideoUrl.split("/").pop(),
          video_url: randomVideoUrl,
          video_thumbnail: randomVideoThumbnail,
        })
      );
    }

    await Promise.all([...demoArticlesPromises, ...demoVideosPromises]);

    const sellerTopic = await SellerUnivTopics.findOne({
      where: {
        id: demoTopic.id,
      },
      include: [
        {
          model: SellerUnivArticles,
          as: "topic_articles",
        },
        {
          model: SellerUnivVideos,
          as: "topic_videos",
        },
      ],
    });
    res.status(200).json({ success: true, demo: sellerTopic });
  } catch (err) {
    next(err);
  }
};
