import Foundation
import GenAPI

public enum FeatureIcon: String, Codable, Equatable {
    case check = "check"
    case lock = "lock"
}

public struct FeatureRowResponse: Codable, Equatable {
    public var featureName: LocalizedTextResponse
    public var values: [Value]

    public enum Value: Codable, Equatable {
        case iconFeatureValueResponse(IconFeatureValueResponse)
        case textFeatureValueResponse(TextFeatureValueResponse)

        public init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            if let value = try? container.decode(IconFeatureValueResponse.self) {
                self = .iconFeatureValueResponse(value)
            } else if let value = try? container.decode(TextFeatureValueResponse.self) {
                self = .textFeatureValueResponse(value)
            } else {
                throw DecodingError.dataCorruptedError(
                    in: container,
                    debugDescription: "Data could not be decoded as any of the expected types (IconFeatureValueResponse, TextFeatureValueResponse)."
                )
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            switch self {
            case .iconFeatureValueResponse(let value): try container.encode(value)
            case .textFeatureValueResponse(let value): try container.encode(value)
            }
        }
    }

    public init(featureName: LocalizedTextResponse, values: [Value]) {
        self.featureName = featureName
        self.values = values
    }

    init(_ remote: GenAPI.FeatureRowResponse) {
        self.featureName = LocalizedTextResponse(remote.featureName)
        self.values = remote.values.map { remoteValue in
            switch remoteValue {
            case .iconFeatureValueResponse(let value):
                return .iconFeatureValueResponse(IconFeatureValueResponse(value))
            case .textFeatureValueResponse(let value):
                return .textFeatureValueResponse(TextFeatureValueResponse(value))
            }
        }
    }
}

public struct IconFeatureValueResponse: Codable, Equatable {
    enum CodingKeys: String, CodingKey {
        case icon
    }

    public var icon: FeatureIcon?

    public init(icon: FeatureIcon?) {
        self.icon = icon
    }

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let iconString = try container.decode(String.self, forKey: .icon)
        self.icon = FeatureIcon(rawValue: iconString)
    }

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(icon?.rawValue ?? "", forKey: .icon)
    }

    init(_ remote: GenAPI.IconFeatureValueResponse) {
        self.icon = FeatureIcon(rawValue: remote.icon)
    }
}

public struct TextFeatureValueResponse: Codable, Equatable {
    public var text: String

    public init(text: String) {
        self.text = text
    }

    init(_ remote: GenAPI.TextFeatureValueResponse) {
        self.text = remote.text
    }
}

public struct LocalizedTextResponse: Codable, Equatable {
    public var text: String

    public init(text: String) {
        self.text = text
    }

    init(_ remote: GenAPI.LocalizedTextResponse) {
        self.text = remote.text
    }
}
