//
//  Poll.swift
//  Pachyderm
//
//  Created by Shadowfacts on 4/25/21.
//  Copyright © 2021 Shadowfacts. All rights reserved.
//

import Foundation

public struct Poll: Codable, Sendable {
    public let id: String
    public let expiresAt: Date?
    public let expired: Bool
    public let multiple: Bool
    public let votesCount: Int
    public let votersCount: Int?
    public let voted: Bool?
    public let ownVotes: [Int]?
    public let options: [Option]
    public let emojis: [Emoji]
    
    public var effectiveExpired: Bool {
        expired || (expiresAt != nil && expiresAt! < Date())
    }
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decode(String.self, forKey: .id)
        self.expiresAt = try container.decodeIfPresent(Date.self, forKey: .expiresAt)
        self.expired = try container.decode(Bool.self, forKey: .expired)
        self.multiple = try container.decode(Bool.self, forKey: .multiple)
        self.votesCount = try container.decode(Int.self, forKey: .votesCount)
        self.votersCount = try container.decodeIfPresent(Int.self, forKey: .votersCount)
        self.voted = try container.decodeIfPresent(Bool.self, forKey: .voted)
        self.ownVotes = try container.decodeIfPresent([Int].self, forKey: .ownVotes)
        self.options = try container.decode([Poll.Option].self, forKey: .options)
        self.emojis = try container.decodeIfPresent([Emoji].self, forKey: .emojis) ?? []
    } 
    
    public static func vote(_ pollID: String, choices: [Int]) -> Request<Poll> {
        return Request<Poll>(method: .post, path: "/api/v1/polls/\(pollID)/votes", body: FormDataBody("choices" => choices, nil))
    }
    
    private enum CodingKeys: String, CodingKey {
        case id
        case expiresAt = "expires_at"
        case expired
        case multiple
        case votesCount = "votes_count"
        case votersCount = "voters_count"
        case voted
        case ownVotes = "own_votes"
        case options
        case emojis
    }
}

extension Poll {
    public struct Option: Codable, Sendable {
        public let title: String
        public let votesCount: Int?
        
        private enum CodingKeys: String, CodingKey {
            case title
            case votesCount = "votes_count"
        }
    }
}
