package routes

import (
	"fmt"
	"path"
	"sort"
	"time"

	"git.matterlinux.xyz/Matter/website/lib"
	"git.matterlinux.xyz/Matter/website/log"
	"github.com/gofiber/fiber/v2"
	"github.com/gorilla/feeds"
)

func GetContent() ([]lib.Content, error) {
	var (
		contents []lib.Content
		err      error
	)

	if contents, err = lib.ListContent("news"); err != nil {
		return nil, err
	}

	sort.Slice(contents, func(i, j int) bool {
		time1, err := lib.TimeFromString(contents[i].Date)
		if err != nil {
			log.Error("Bad date while sorting: %s", err.Error())
			return false
		}

		time2, err := lib.TimeFromString(contents[j].Date)
		if err != nil {
			log.Error("Bad date while sorting: %s", err.Error())
			return false
		}

		return time1.After(time2)
	})

	return contents, nil
}

func GET_News(c *fiber.Ctx) error {
	contents, err := GetContent()

	if err != nil {
		log.Error("GetContent failed: %s", err.Error())
		return lib.RenderError(c, 500)
	}

	return c.Render("news", fiber.Map{
		"news": contents,
	})
}

func GET_New(c *fiber.Ctx) error {
	postid := c.Params("id")
	if len(postid) == 0 {
		return lib.RenderError(c, 404)
	}

	contents, err := lib.ListContent("news")
	if err != nil {
		log.Error("ListContent failed: %s", err.Error())
		return lib.RenderError(c, 500)
	}

	for _, con := range contents {
		if con.ID != postid {
			continue
		}

		con, err = lib.GetContent(con.Dir, con.Name)
		if err != nil {
			log.Error("ListContent failed: %s", err.Error())
			return lib.RenderError(c, 500)
		}

		return c.Render("post", fiber.Map{
			"title": con.Title,
			"post":  con,
		})
	}

	return lib.RenderError(c, 404)
}

func GET_NewsFeed(c *fiber.Ctx) error {
	var (
		feed_type string
		feed      *feeds.Feed
		contents  []lib.Content
		res       string
		err       error
	)

	feed_type = path.Base(c.Path())

	if contents, err = GetContent(); err != nil {
		log.Error("GetContent failed: %s", err.Error())
		return lib.RenderError(c, 500)
	}

	feed = &feeds.Feed{
		Title:       "MatterLinux | News",
		Link:        &feeds.Link{Href: "https://matterlinux.xyz/news"}, // lets hardcode this for now
		Description: "News regarding the MatterLinux project",
		Created:     time.Now(),
	}

	feed.Items = []*feeds.Item{}

	for _, con := range contents {
		parsed, err := time.Parse("02/01/06", con.Date)

		if err != nil {
			log.Error("Failed to parse post time (%s): %s", con.ID, err.Error())
			return lib.RenderError(c, 500)
		}

		feed.Items = append(feed.Items, &feeds.Item{
			Id:      con.ID,
			Title:   con.Title,
			Link:    &feeds.Link{Href: fmt.Sprintf("https://matterlinux.xyz/news/%s", con.ID)},
			Author:  &feeds.Author{Name: con.Author},
			Created: parsed,
			Content: con.Md,
		})
	}

	switch feed_type {
	case "feed.atom":
		if res, err = feed.ToAtom(); err != nil {
			log.Error("Failed to convert feed to atom: %s", err.Error())
			return lib.RenderError(c, 500)
		}

		c.Set("Content-Type", "application/atom+xml")
		return c.Send([]byte(res))

	case "feed.rss":
		if res, err = feed.ToRss(); err != nil {
			log.Error("Failed to convert feed to RSS: %s", err.Error())
			return lib.RenderError(c, 500)
		}

		c.Set("Content-Type", "application/rss+xml")
		return c.Send([]byte(res))

	case "feed.json":
		if res, err = feed.ToJSON(); err != nil {
			log.Error("Failed to convert feed to JSON: %s", err.Error())
			return lib.RenderError(c, 500)
		}

		c.Set("Content-Type", "application/feed+json")
		return c.Send([]byte(res))
	}

	log.Error("Cannot handle the feed type: %s", feed_type)
	return lib.RenderError(c, 404)
}
