//
//  Card.swift
//  Pachyderm
//
//  Created by Shadowfacts on 9/9/18.
//  Copyright © 2018 Shadowfacts. All rights reserved.
//

import Foundation
import WebURL

public struct Card: Codable, Sendable {
    public let url: WebURL
    public let title: String
    public let description: String
    public let image: WebURL?
    public let kind: Kind
    public let authorName: String?
    public let authorURL: WebURL?
    public let providerName: String?
    public let providerURL: WebURL?
    public let html: String?
    public let width: Int?
    public let height: Int?
    public let blurhash: String?
    /// Only present when returned from the trending links endpoint
    public let history: [History]?
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        self.url = try container.decode(WebURL.self, forKey: .url)
        self.title = try container.decode(String.self, forKey: .title)
        self.description = try container.decode(String.self, forKey: .description)
        self.kind = try container.decode(Kind.self, forKey: .kind)
        self.image = try? container.decodeIfPresent(WebURL.self, forKey: .image)
        self.authorName = try? container.decodeIfPresent(String.self, forKey: .authorName)
        self.authorURL = try? container.decodeIfPresent(WebURL.self, forKey: .authorURL)
        self.providerName = try? container.decodeIfPresent(String.self, forKey: .providerName)
        self.providerURL = try? container.decodeIfPresent(WebURL.self, forKey: .providerURL)
        self.html = try? container.decodeIfPresent(String.self, forKey: .html)
        self.width = try? container.decodeIfPresent(Int.self, forKey: .width)
        self.height = try? container.decodeIfPresent(Int.self, forKey: .height)
        self.blurhash = try? container.decodeIfPresent(String.self, forKey: .blurhash)
        self.history = try? container.decodeIfPresent([History].self, forKey: .history)
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        
        try container.encode(url, forKey: .url)
        try container.encode(title, forKey: .title)
        try container.encode(description, forKey: .description)
        try container.encode(kind, forKey: .kind)
        try container.encode(image, forKey: .image)
        try container.encode(blurhash, forKey: .blurhash)
    }
    
    private enum CodingKeys: String, CodingKey {
        case url
        case title
        case description
        case image
        case kind = "type"
        case authorName = "author_name"
        case authorURL = "author_url"
        case providerName = "provider_name"
        case providerURL = "provider_url"
        case html
        case width
        case height
        case blurhash
        case history
    }
}

extension Card {
    public enum Kind: String, Codable, Sendable {
        case link
        case photo
        case video
        case rich
    }
}
