
#warning("Add remaining header elements")
// <meta name="msapplication-TileColor" content="#da532c">
// <meta name="theme-color" content="#ffffff">
// <meta name="msapplication-config" content="/assets/icons/browserconfig.xml?v=1">

// TODO: Move to settings?
extension HeaderElement {

    static let swiperCssFileOrder = 41

    static let defaultCssFileOrder = 42

    static let audioPlayerCssOrder = 43

    static let imageCompareCssOrder = 44
}

enum HeaderElement {

    /// Order: 10-19
    case icon(file: FileResource, size: Int, rel: String)

    /// Order: From 40-99, lower numbers appear first
    case css(file: FileResource, order: Int)

    /// Order: 20-29
    case js(file: FileResource, defer: Bool)

    /// Order: 30-39
    case jsModule(FileResource)

    case author(String)

    case title(String)

    case description(String)

    case charset

    case viewport

    case robots

    var order: Int {
        switch self {
        case .charset:
            return 1
        case .robots:
            return 2
        case .viewport:
            return 3
        case .icon:
            return 10
        case .css(_, let order):
            return order
        case .js:
            return 20
        case .jsModule:
            return 30
        case .author:
            return 100
        case .title:
            return 101
        case .description:
            return 102
        }
    }

    var file: FileResource? {
        switch self {
        case .icon(let file, _, _):
            return file
        case .css(let file, _):
            return file
        case .js(let file, _):
            return file
        case .jsModule(let file):
            return file
        default:
            return nil
        }
    }
}

extension HeaderElement: Hashable {
    
}

extension HeaderElement: Comparable {

    static func < (lhs: HeaderElement, rhs: HeaderElement) -> Bool {
        lhs.order < rhs.order
    }
}

extension HeaderElement {

    var content: String {
        switch self {
        case .icon(let file, let size, let rel):
            return "<link rel='\(rel)' sizes='\(size)x\(size)' href='\(file.absoluteUrl)'>"
        case .css(let file, _):
            return "<link rel='stylesheet' href='\(file.absoluteUrl)' />"
        case .js(let file, let deferred):
            let deferText = deferred ? " defer" : ""
            return "<script src='\(file.absoluteUrl)'\(deferText)></script>"
        case .jsModule(let file):
            return "<script type='module' src='\(file.absoluteUrl)'></script>"
        case .author(let author):
            return "<meta name='author' content='\(author)'>"
        case .title(let title):
            return "<title>\(title)</title>"
        case .description(let description):
            return "<meta name='description' content=\"\(description)\">"
        case .charset:
            return "<meta charset='utf-8' />"
        case .viewport:
            return "<meta name='viewport' content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1' />"
        case .robots:
            return "<meta name='robots' content='noindex'>"
        }
    }
}

extension HeaderElement: CustomStringConvertible {

    var description: String {
        switch self {
        case .icon(let file, _, _):
            return file.description
        case .css(let file, _):
            return file.description
        case .js(let file, let deferred):
            return file.description + (deferred ? " (deferred)" : "")
        case .jsModule(let file):
            return file.description
        case .author:
            return "author"
        case .title:
            return "title"
        case .description:
            return "description"
        case .charset:
            return "charset"
        case .viewport:
            return "viewport"
        case .robots:
            return "robots"
        }
    }
}
