/*
 * FeedSubscription.vala
 * 
 * Represents a user's subscription to a feed with sync settings.
 * Following GNOME HIG naming conventions and Vala/GObject patterns.
 */

/**
 * HTTP Authentication credentials
 */
public struct RSSuper.HttpAuth {
    public string username { get; set; }
    public string password { get; set; }
    
    public HttpAuth(string username, string password) {
        this.username = username;
        this.password = password;
    }
}

/**
 * FeedSubscription - Represents a user's subscription to a feed
 */
public class RSSuper.FeedSubscription : Object {
    public string id { get; set; }
    public string url { get; set; }
    public string title { get; set; }
    public string? category { get; set; }
    public bool enabled { get; set; }
    public int fetch_interval { get; set; }
    public string created_at { get; set; }
    public string updated_at { get; set; }
    public string? last_fetched_at { get; set; }
    public string? next_fetch_at { get; set; }
    public string? error { get; set; }
    public string? http_auth_username { get; set; }
    public string? http_auth_password { get; set; }
    
    /**
     * Default constructor
     */
    public FeedSubscription() {
        this.id = "";
        this.url = "";
        this.title = "";
        this.enabled = true;
        this.fetch_interval = 60;
        this.created_at = "";
        this.updated_at = "";
    }
    
    /**
     * Constructor with initial values
     */
    public FeedSubscription.with_values(string id, string url, string title,
                                         int fetch_interval = 60,
                                         string? category = null, bool enabled = true,
                                         string? created_at = null, string? updated_at = null,
                                         string? last_fetched_at = null,
                                         string? next_fetch_at = null,
                                         string? error = null,
                                         string? http_auth_username = null,
                                         string? http_auth_password = null) {
        this.id = id;
        this.url = url;
        this.title = title;
        this.category = category;
        this.enabled = enabled;
        this.fetch_interval = fetch_interval;
        this.created_at = created_at ?? "";
        this.updated_at = updated_at ?? "";
        this.last_fetched_at = last_fetched_at;
        this.next_fetch_at = next_fetch_at;
        this.error = error;
        this.http_auth_username = http_auth_username;
        this.http_auth_password = http_auth_password;
    }
    
    /**
     * Get HTTP auth as struct
     */
    public HttpAuth? get_http_auth() {
        if (this.http_auth_username == null) {
            return null;
        }
        return HttpAuth(this.http_auth_username, this.http_auth_password ?? "");
    }
    
    /**
     * Set HTTP auth from struct
     */
    public void set_http_auth(HttpAuth? auth) {
        if (auth == null) {
            this.http_auth_username = null;
            this.http_auth_password = null;
        } else {
            this.http_auth_username = auth.username;
            this.http_auth_password = auth.password;
        }
    }
    
    /**
     * Check if subscription has an error
     */
    public bool has_error() {
        return this.error != null && this.error.length > 0;
    }
    
    /**
     * Serialize to JSON string
     */
    public string to_json_string() {
        var sb = new StringBuilder();
        sb.append("{");
        sb.append("\"id\":\"");
        sb.append(this.id);
        sb.append("\",\"url\":\"");
        sb.append(this.url);
        sb.append("\",\"title\":\"");
        sb.append(this.title);
        sb.append("\",\"enabled\":");
        sb.append(this.enabled ? "true" : "false");
        sb.append(",\"fetchInterval\":%d".printf(this.fetch_interval));
        sb.append(",\"createdAt\":\"");
        sb.append(this.created_at);
        sb.append("\",\"updatedAt\":\"");
        sb.append(this.updated_at);
        sb.append("\"");
        
        if (this.category != null) {
            sb.append(",\"category\":\"");
            sb.append(this.category);
            sb.append("\"");
        }
        if (this.last_fetched_at != null) {
            sb.append(",\"lastFetchedAt\":\"");
            sb.append(this.last_fetched_at);
            sb.append("\"");
        }
        if (this.next_fetch_at != null) {
            sb.append(",\"nextFetchAt\":\"");
            sb.append(this.next_fetch_at);
            sb.append("\"");
        }
        if (this.error != null) {
            sb.append(",\"error\":\"");
            sb.append(this.error);
            sb.append("\"");
        }
        if (this.http_auth_username != null) {
            sb.append(",\"httpAuth\":{\"username\":\"");
            sb.append(this.http_auth_username);
            sb.append("\"");
            if (this.http_auth_password != null) {
                sb.append(",\"password\":\"");
                sb.append(this.http_auth_password);
                sb.append("\"");
            }
            sb.append("}");
        }
        
        sb.append("}");
        return sb.str;
    }
    
    /**
     * Deserialize from JSON string
     */
    public static FeedSubscription? 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 FeedSubscription? 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("url") || 
            !obj.has_member("title") || !obj.has_member("createdAt") ||
            !obj.has_member("updatedAt")) {
            return null;
        }
        
        var subscription = new FeedSubscription();
        subscription.id = obj.get_string_member("id");
        subscription.url = obj.get_string_member("url");
        subscription.title = obj.get_string_member("title");
        
        if (obj.has_member("category")) {
            subscription.category = obj.get_string_member("category");
        }
        if (obj.has_member("enabled")) {
            subscription.enabled = obj.get_boolean_member("enabled");
        }
        if (obj.has_member("fetchInterval")) {
            subscription.fetch_interval = (int)obj.get_int_member("fetchInterval");
        }
        
        subscription.created_at = obj.get_string_member("createdAt");
        subscription.updated_at = obj.get_string_member("updatedAt");
        
        if (obj.has_member("lastFetchedAt")) {
            subscription.last_fetched_at = obj.get_string_member("lastFetchedAt");
        }
        if (obj.has_member("nextFetchAt")) {
            subscription.next_fetch_at = obj.get_string_member("nextFetchAt");
        }
        if (obj.has_member("error")) {
            subscription.error = obj.get_string_member("error");
        }
        if (obj.has_member("httpAuth")) {
            var auth_obj = obj.get_object_member("httpAuth");
            subscription.http_auth_username = auth_obj.get_string_member("username");
            if (auth_obj.has_member("password")) {
                subscription.http_auth_password = auth_obj.get_string_member("password");
            }
        }
        
        return subscription;
    }
    
    /**
     * Equality comparison
     */
    public bool equals(FeedSubscription? other) {
        if (other == null) {
            return false;
        }
        
        return this.id == other.id &&
               this.url == other.url &&
               this.title == other.title &&
               this.category == other.category &&
               this.enabled == other.enabled &&
               this.fetch_interval == other.fetch_interval &&
               this.created_at == other.created_at &&
               this.updated_at == other.updated_at &&
               this.last_fetched_at == other.last_fetched_at &&
               this.next_fetch_at == other.next_fetch_at &&
               this.error == other.error &&
               this.http_auth_username == other.http_auth_username &&
               this.http_auth_password == other.http_auth_password;
    }
}
