//
//  PostVisibility.swift
//  TuskerPreferences
//
//  Created by Shadowfacts on 10/26/23.
//

import Foundation
import Pachyderm

public enum PostVisibility: Codable, Hashable, CaseIterable {
    case serverDefault
    case visibility(Visibility)
    
    public static var allCases: [PostVisibility] = [.serverDefault] + Visibility.allCases.map { .visibility($0) }
    
    public func resolved(withServerDefault serverDefault: Visibility?) -> Visibility {
        switch self {
        case .serverDefault:
            // If the server doesn't have a default visibility preference, we fallback to public.
            // This isn't ideal, but I don't want to add a separate preference for "Default Post Visibility Fallback" :/
            serverDefault ?? .public
        case .visibility(let vis):
            vis
        }
    }
    
    public func resolved(withServerDefault serverDefault: () async -> Visibility?) async -> Visibility {
        switch self {
        case .serverDefault:
            await serverDefault() ?? .public
        case .visibility(let vis):
            vis
        }
    }
    
    public var displayName: String {
        switch self {
        case .serverDefault:
            return "Account Default"
        case .visibility(let vis):
            return vis.displayName
        }
    }
    
    public var imageName: String? {
        switch self {
        case .serverDefault:
            return nil
        case .visibility(let vis):
            return vis.imageName
        }
    }
}

public enum ReplyVisibility: Codable, Hashable, CaseIterable {
    case sameAsPost
    case visibility(Visibility)
    
    public static var allCases: [ReplyVisibility] = [.sameAsPost] + Visibility.allCases.map { .visibility($0) }
    
    public func resolved(withServerDefault serverDefault: Visibility?) -> Visibility {
        switch self {
        case .sameAsPost:
            Preferences.shared.defaultPostVisibility.resolved(withServerDefault: serverDefault)
        case .visibility(let vis):
            vis
        }
    }
    
    public func resolved(withServerDefault serverDefault: () async -> Visibility?) async -> Visibility {
        switch self {
        case .sameAsPost:
            await Preferences.shared.defaultPostVisibility.resolved(withServerDefault: serverDefault)
        case .visibility(let vis):
            vis
        }
    }
    
    public var displayName: String {
        switch self {
        case .sameAsPost:
            return "Same as Default"
        case .visibility(let vis):
            return vis.displayName
        }
    }
    
    public var imageName: String? {
        switch self {
        case .sameAsPost:
            return nil
        case .visibility(let vis):
            return vis.imageName
        }
    }
}
