package handler

import (
	"encoding/xml"
	"net/http"
	"time"

	"podstalk/store"
)

type RSSHandler struct {
	Store *store.Store
	Link  string
}

type rssFeed struct {
	XMLName  xml.Name   `xml:"rss"`
	Version  string     `xml:"version,attr"`
	ItunesNS string     `xml:"xmlns:itunes,attr"`
	Channel  rssChannel `xml:"channel"`
}

type rssChannel struct {
	Title       string          `xml:"title"`
	Link        string          `xml:"link"`
	Description string          `xml:"description"`
	Language    string          `xml:"language"`
	Author      string          `xml:"itunes:author,omitempty"`
	Image       *rssImage       `xml:"image,omitempty"`
	ItunesImage *rssItunesImage `xml:"itunes:image,omitempty"`
	Items       []rssItem       `xml:"item"`
}

type rssImage struct {
	URL   string `xml:"url"`
	Title string `xml:"title"`
	Link  string `xml:"link"`
}

type rssItunesImage struct {
	Href string `xml:"href,attr"`
}

type rssItem struct {
	Title       string          `xml:"title"`
	Description string          `xml:"description"`
	Enclosure   rssEnclosure    `xml:"enclosure"`
	PubDate     string          `xml:"pubDate"`
	GUID        string          `xml:"guid"`
	ItunesImage *rssItunesImage `xml:"itunes:image,omitempty"`
}

type rssEnclosure struct {
	URL    string `xml:"url,attr"`
	Length string `xml:"length,attr,omitempty"`
	Type   string `xml:"type,attr"`
}

func (h *RSSHandler) ServeRSS(w http.ResponseWriter, r *http.Request) {
	// Try path-based slug first: /rss/my-slug
	slug := r.PathValue("slug")
	if slug == "" {
		slug = r.URL.Query().Get("slug")
	}
	if slug == "" {
		slug = r.URL.Query().Get("user") // legacy
	}

	var user *store.User
	if slug != "" {
		user, _ = h.Store.UserBySlug(slug)
	}
	if user == nil {
		// legacy: try numeric user ID
		if idStr := r.URL.Query().Get("user"); idStr != "" {
			// already tried above, fall through
		}
	}
	if user == nil {
		http.Error(w, "podcast not found", http.StatusNotFound)
		return
	}

	episodes, err := h.Store.ListEpisodes(user.ID)
	if err != nil {
		http.Error(w, "failed to load episodes", http.StatusInternalServerError)
		return
	}

	title := user.PodcastTitle
	if title == "" {
		title = "Podstalk"
	}
	author := user.PodcastAuthor

	items := make([]rssItem, 0, len(episodes))
	for _, ep := range episodes {
		var itemImage *rssItunesImage
		epImage := ep.ImagePath
		if epImage == "" {
			epImage = user.PodcastImage
		}
		if epImage != "" {
			itemImage = &rssItunesImage{Href: h.fullURL(epImage)}
		}

		items = append(items, rssItem{
			Title:       ep.Title,
			Description: ep.Description,
			Enclosure: rssEnclosure{
				URL:  h.fullURL(ep.AudioPath),
				Type: "audio/mpeg",
			},
			PubDate:     ep.PublishedAt.Format(time.RFC1123Z),
			GUID:        h.fullURL(ep.AudioPath),
			ItunesImage: itemImage,
		})
	}

	var chanImage *rssImage
	var chanItunesImage *rssItunesImage
	if user.PodcastImage != "" {
		chanImage = &rssImage{
			URL:   h.fullURL(user.PodcastImage),
			Title: title,
			Link:  h.Link,
		}
		chanItunesImage = &rssItunesImage{Href: h.fullURL(user.PodcastImage)}
	}

	feed := rssFeed{
		Version:  "2.0",
		ItunesNS: "http://www.itunes.com/dtds/podcast-1.0.dtd",
		Channel: rssChannel{
			Title:       title,
			Link:        h.Link,
			Description: title,
			Language:    "en-us",
			Author:      author,
			Image:       chanImage,
			ItunesImage: chanItunesImage,
			Items:       items,
		},
	}

	w.Header().Set("Content-Type", "application/rss+xml; charset=utf-8")
	w.Write([]byte(xml.Header))
	enc := xml.NewEncoder(w)
	enc.Indent("", "  ")
	enc.Encode(feed)
}

func (h *RSSHandler) fullURL(path string) string {
	if path == "" {
		return ""
	}
	if h.Link == "" {
		return path
	}
	return h.Link + "/uploads/" + path
}
