/*
 * FeedItem.vala
 * 
 * Represents a single RSS/Atom feed item (article, episode, etc.)
 * Following GNOME HIG naming conventions and Vala/GObject patterns.
 */

/**
 * Enclosure metadata for media attachments (podcasts, videos, etc.)
 */
public struct RSSuper.Enclosure {
    public string url { get; set; }
    public string item_type { get; set; }
    public string? length { get; set; }
    
    public Enclosure(string url, string type, string? length = null) {
        this.url = url;
        this.item_type = type;
        this.length = length;
    }
}

/**
 * FeedItem - Represents a single RSS/Atom entry
 */
public class RSSuper.FeedItem : Object {
    public string id { get; set; }
    public string title { get; set; }
    public string? link { get; set; }
    public string? description { get; set; }
    public string? content { get; set; }
    public string? author { get; set; }
    public string? published { get; set; }
    public string? updated { get; set; }
    public string[] categories { get; set; }
    public string? enclosure_url { get; set; }
    public string? enclosure_type { get; set; }
    public string? enclosure_length { get; set; }
    public string? guid { get; set; }
    public string? subscription_title { get; set; }
    
    /**
     * Default constructor
     */
    public FeedItem() {
        this.id = "";
        this.title = "";
        this.categories = {};
    }
    
    /**
     * Constructor with initial values
     */
    public FeedItem.with_values(string id, string title, string? link = null,
                                  string? description = null, string? content = null,
                                  string? author = null, string? published = null,
                                  string? updated = null, string[]? categories = null,
                                  string? enclosure_url = null, string? enclosure_type = null,
                                  string? enclosure_length = null, string? guid = null,
                                  string? subscription_title = null) {
        this.id = id;
        this.title = title;
        this.link = link;
        this.description = description;
        this.content = content;
        this.author = author;
        this.published = published;
        this.updated = updated;
        this.categories = categories;
        this.enclosure_url = enclosure_url;
        this.enclosure_type = enclosure_type;
        this.enclosure_length = enclosure_length;
        this.guid = guid;
        this.subscription_title = subscription_title;
    }
    
    /**
     * Get enclosure as struct
     */
    public Enclosure? get_enclosure() {
        if (this.enclosure_url == null) {
            return null;
        }
        return Enclosure(this.enclosure_url, this.enclosure_type ?? "", this.enclosure_length);
    }
    
    /**
     * Set enclosure from struct
     */
    public void set_enclosure(Enclosure? enclosure) {
        if (enclosure == null) {
            this.enclosure_url = null;
            this.enclosure_type = null;
            this.enclosure_length = null;
        } else {
            this.enclosure_url = enclosure.url;
            this.enclosure_type = enclosure_type;
            this.enclosure_length = enclosure.length;
        }
    }
    
    /**
     * Serialize to JSON string
     */
    public string to_json_string() {
        var sb = new StringBuilder();
        sb.append("{");
        sb.append("\"id\":\"");
        sb.append(this.id);
        sb.append("\",\"title\":\"");
        sb.append(this.title);
        sb.append("\"");
        
        if (this.link != null) {
            sb.append(",\"link\":\"");
            sb.append(this.link);
            sb.append("\"");
        }
        if (this.description != null) {
            sb.append(",\"description\":\"");
            sb.append(this.description);
            sb.append("\"");
        }
        if (this.content != null) {
            sb.append(",\"content\":\"");
            sb.append(this.content);
            sb.append("\"");
        }
        if (this.author != null) {
            sb.append(",\"author\":\"");
            sb.append(this.author);
            sb.append("\"");
        }
        if (this.published != null) {
            sb.append(",\"published\":\"");
            sb.append(this.published);
            sb.append("\"");
        }
        if (this.updated != null) {
            sb.append(",\"updated\":\"");
            sb.append(this.updated);
            sb.append("\"");
        }
        if (this.categories.length > 0) {
            sb.append(",\"categories\":[");
            for (var i = 0; i < this.categories.length; i++) {
                if (i > 0) sb.append(",");
                sb.append("\"");
                sb.append(this.categories[i]);
                sb.append("\"");
            }
            sb.append("]");
        }
        if (this.enclosure_url != null) {
            sb.append(",\"enclosure\":{\"url\":\"");
            sb.append(this.enclosure_url);
            sb.append("\"");
            if (this.enclosure_type != null) {
                sb.append(",\"type\":\"");
                sb.append(this.enclosure_type);
                sb.append("\"");
            }
            if (this.enclosure_length != null) {
                sb.append(",\"length\":\"");
                sb.append(this.enclosure_length);
                sb.append("\"");
            }
            sb.append("}");
        }
        if (this.guid != null) {
            sb.append(",\"guid\":\"");
            sb.append(this.guid);
            sb.append("\"");
        }
        if (this.subscription_title != null) {
            sb.append(",\"subscription_title\":\"");
            sb.append(this.subscription_title);
            sb.append("\"");
        }
        
        sb.append("}");
        return sb.str;
    }
    
    /**
     * Deserialize from JSON string (simple parser)
     */
    public static FeedItem? from_json_string(string json_string) {
        var parser = new Json.Parser();
        try {
            if (!parser.load_from_data(json_string)) {
                return null;
            }
        } catch (Error e) {
            warning("Failed to parse JSON: %s", e.message);
            return null;
        }
        
        return from_json_node(parser.get_root());
    }
    
    /**
     * Deserialize from Json.Node
     */
    public static FeedItem? from_json_node(Json.Node node) {
        if (node.get_node_type() != Json.NodeType.OBJECT) {
            return null;
        }
        
        var obj = node.get_object();
        
        if (!obj.has_member("id") || !obj.has_member("title")) {
            return null;
        }
        
        var item = new FeedItem();
        item.id = obj.get_string_member("id");
        item.title = obj.get_string_member("title");
        
        if (obj.has_member("link")) {
            item.link = obj.get_string_member("link");
        }
        if (obj.has_member("description")) {
            item.description = obj.get_string_member("description");
        }
        if (obj.has_member("content")) {
            item.content = obj.get_string_member("content");
        }
        if (obj.has_member("author")) {
            item.author = obj.get_string_member("author");
        }
        if (obj.has_member("published")) {
            item.published = obj.get_string_member("published");
        }
        if (obj.has_member("updated")) {
            item.updated = obj.get_string_member("updated");
        }
        if (obj.has_member("categories")) {
            var categories_array = obj.get_array_member("categories");
            var categories = new string[categories_array.get_length()];
            for (var i = 0; i < categories_array.get_length(); i++) {
                categories[i] = categories_array.get_string_element(i);
            }
            item.categories = categories;
        }
        if (obj.has_member("enclosure")) {
            var enclosure_obj = obj.get_object_member("enclosure");
            item.enclosure_url = enclosure_obj.get_string_member("url");
            if (enclosure_obj.has_member("type")) {
                item.enclosure_type = enclosure_obj.get_string_member("type");
            }
            if (enclosure_obj.has_member("length")) {
                item.enclosure_length = enclosure_obj.get_string_member("length");
            }
        }
        if (obj.has_member("guid")) {
            item.guid = obj.get_string_member("guid");
        }
        if (obj.has_member("subscription_title")) {
            item.subscription_title = obj.get_string_member("subscription_title");
        }
        
        return item;
    }
    
    /**
     * Equality comparison
     */
    public bool equals(FeedItem? other) {
        if (other == null) {
            return false;
        }
        
        return this.id == other.id &&
               this.title == other.title &&
               this.link == other.link &&
               this.description == other.description &&
               this.content == other.content &&
               this.author == other.author &&
               this.published == other.published &&
               this.updated == other.updated &&
               this.categories_equal(other.categories) &&
               this.enclosure_url == other.enclosure_url &&
               this.enclosure_type == other.enclosure_type &&
               this.enclosure_length == other.enclosure_length &&
               this.guid == other.guid &&
               this.subscription_title == other.subscription_title;
    }
    
    /**
     * Helper for category array comparison
     */
    private bool categories_equal(string[] other) {
        if (this.categories.length != other.length) {
            return false;
        }
        
        for (var i = 0; i < this.categories.length; i++) {
            if (this.categories[i] != other[i]) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Get a human-readable summary
     */
    public string get_summary() {
        return "%s by %s".printf(this.title, this.author ?? "Unknown");
    }
}
