import { LessThan } from "typeorm";
import { AppDataSource } from "./data_source.js";
import Logging from "./log.js";
import { Feed } from "./models/Feed.js";
import { createHash } from "crypto";
import rss from "rss-parser";
import { Post } from "./models/Post.js";
import bot from "./telegram.js";

interface RSSFeed {
   title: string;
   language: string;
   description: string;
   copyright: string;

   items: RSSFeedItem[];
}

interface RSSFeedItem {
   title: string;
   link: string;
   content: string,
   contentSnippet: string;
   guid: string;
}

function calculateHash(item: RSSFeedItem) {
   let hash = createHash("sha512");
   if (item.content)
      hash.update(item.content);
   if (item.guid)
      hash.update(item.guid);
   if (item.title)
      hash.update(item.title);
   if (item.link)
      hash.update(item.link);
   if (item.contentSnippet)
      hash.update(item.contentSnippet);
   return hash.digest("hex");
}

async function checkFeed(feed: Feed) {
   Logging.info("Fetching feed: %s", feed.url);
   let data = await fetch(feed.url).then(res => res.text());
   Logging.info("Received Data");
   Logging.debug(data);

   const parser = new rss();
   Logging.info("Parsing feed");
   let feedData = await parser.parseString(data).catch(err => Logging.error(err)) as RSSFeed;
   Logging.info("Parsed feed");

   Logging.info("Checking for new items");


   for (let entry of feedData.items) {
      let hash = calculateHash(entry);
      let post = await AppDataSource.manager.findOne(Post, {
         where: {
            feed,
            hash
         }
      });
      if (!post) {
         post = AppDataSource.manager.create(Post, {
            feed,
            hash
         })

         const decode = (inp) => inp;

         feed.subscriber.map(async sub => {
            bot.telegram.sendMessage(
               sub.chatid,
               entry.guid + "\n" + decode(entry.title) + "\n\n" + decode(entry.contentSnippet)
            ).catch(err => Logging.error(err)).then(() => Logging.debug("Message Sent"))
         })

         await AppDataSource.manager.save(post);
      }
   }


   // Logging.debug(feedData.items.length, feedData.items.map(e => calculateHash(e)));
   // const newItems = feedData.items.filter(item => !feed.itemExists(item));

   // // Sending notifications
   // await sendFeedTelegraf(feed, newItems);

   // feed.addItems(newItems);
}

// const FEED_CHECK_INTERVAL = 1000 * 60 * 60;
const FEED_CHECK_INTERVAL = 1000 * 30;

export default async function checkFeeds() {
   while (true) {
      let feed = await AppDataSource.manager.findOne(Feed, {
         where: {
            lastCheck: LessThan(new Date(Date.now() - FEED_CHECK_INTERVAL))
         },
         relations: {
            subscriber: true
         }
      })

      if (!feed) {
         await new Promise(y => setTimeout(y, 1000));
         continue;
      }

      await checkFeed(feed);

      feed.lastCheck = new Date();
      await AppDataSource.manager.save(feed);
   }
}
