//
//  TiletModel.swift
//  MVMCoreUI
//
//  Created by Matt Bruce on 1/12/23.
//  Copyright © 2023 Verizon Wireless. All rights reserved.
//

import Foundation
import VDS

open class TileletModel: MoleculeModelProtocol {
    
    //--------------------------------------------------
    // MARK: - Properties
    //--------------------------------------------------
    public static var identifier: String = "tilelet"
    public var id: String = UUID().uuidString
    public var backgroundColor: Color?
    public var color: Tilelet.BackgroundColor
    public var padding: Tilelet.Padding
    public var aspectRatio: Tilelet.AspectRatio
    public var badge: Tilelet.BadgeModel?
    public var title: LabelModel?
    public var subTitle: LabelModel?
    public var descriptiveIcon: Tilelet.DescriptiveIcon?
    public var directionalIcon: Tilelet.DirectionalIcon?
    public var width: CGFloat?
    public var textWidth: CGFloat?
    public var textPercentage: CGFloat?
    public var action: ActionModelProtocol?
    
    private enum CodingKeys: String, CodingKey {
        case id
        case moleculeName
        case backgroundColor
        case color
        case padding
        case aspectRatio
        case badge
        case title
        case subTitle
        case descriptiveIcon
        case directionalIcon
        case width
        case textWidth
        case textPercentage
        case action
    }
    required public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString
        self.backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor)
        self.color = try container.decodeIfPresent(Tilelet.BackgroundColor.self, forKey: .color) ?? Tilelet.BackgroundColor.black
        self.padding = try container.decodeIfPresent(Tilelet.Padding.self, forKey: .padding) ?? Tilelet.Padding.small
        self.aspectRatio = try container.decodeIfPresent(Tilelet.AspectRatio.self, forKey: .aspectRatio) ?? Tilelet.AspectRatio.none
        self.badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge)
        self.title = try container.decodeIfPresent(LabelModel.self, forKey: .title)
        self.subTitle = try container.decodeIfPresent(LabelModel.self, forKey: .subTitle)
        self.descriptiveIcon = try container.decodeIfPresent(Tilelet.DescriptiveIcon.self, forKey: .descriptiveIcon)
        self.directionalIcon = try container.decodeIfPresent(Tilelet.DirectionalIcon.self, forKey: .directionalIcon)
        self.width = try container.decodeIfPresent(CGFloat.self, forKey: .width)
        self.textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth)
        self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage)
        action = try container.decodeModelIfPresent(codingKey: .action)
    }
    
    public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? {
        guard let title else { return nil }
        let attrs = title.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
        
        do {
            if let style = title.fontStyle {
                return .init(text: title.text,
                             textAttributes: attrs,
                             standardStyle: try style.vdsSubsetStyle())
            }

        } catch MVMCoreError.errorObject(let object) {
            MVMCoreLoggingHandler.shared()?.addError(toLog: object)
        } catch { }
        
        return .init(text: title.text, textAttributes: attrs)
    }
    
    public func subTitleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.SubTitleModel? {
        guard let subTitle else { return nil }
        let attrs = subTitle.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData)
        do {
            if let style = subTitle.fontStyle {
                return .init(text: subTitle.text,
                             otherStandardStyle: try style.vdsSubsetStyle(),
                             textAttributes: attrs)
            }
        } catch MVMCoreError.errorObject(let object) {
            MVMCoreLoggingHandler.shared()?.addError(toLog: object)
        } catch { }
        
        return .init(text: subTitle.text, textAttributes: attrs)
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(moleculeName, forKey: .moleculeName)
        try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
        try container.encodeIfPresent(color, forKey: .color)
        try container.encodeIfPresent(padding, forKey: .padding)
        try container.encodeIfPresent(aspectRatio, forKey: .aspectRatio)
        try container.encodeIfPresent(badge, forKey: .badge)
        try container.encodeIfPresent(title, forKey: .title)
        try container.encodeIfPresent(subTitle, forKey: .subTitle)
        try container.encodeIfPresent(descriptiveIcon, forKey: .descriptiveIcon)
        try container.encodeIfPresent(directionalIcon, forKey: .directionalIcon)
        try container.encodeIfPresent(width, forKey: .width)
        try container.encodeIfPresent(textWidth, forKey: .textWidth)
        try container.encodeIfPresent(textPercentage, forKey: .textPercentage)
        try container.encodeModelIfPresent(action, forKey: .action)
    }
}
