//
//  MFCardV3ConfigTranslator.swift
//  MyfatoorahReactnative
//
//  Translates the reused JS `MFCardViewStyle` dictionary into the native V3
//  `MFCardConfigurationV3`. Decodes via the shared `MFCardViewStyle` Decodable
//  (MFRequestHelper.swift) so the same style object drives V2 and V3.
//

import Foundation
import UIKit
import MFSDK

enum MFCardV3ConfigTranslator {

    static func configuration(from dict: NSDictionary?) -> MFCardConfigurationV3 {
        var config = MFCardConfigurationV3()
        guard let dict = dict,
              let data = try? JSONSerialization.data(withJSONObject: dict, options: []),
              let style = try? JSONDecoder().decode(MFCardViewStyle.self, from: data) else {
            return config
        }

        // MARK: Top-level
        if let hide = style.hideCardIcons { config.hideCardIcons = hide }
        if let show = style.showCardholderName { config.showCardholderName = show }
        if let height = style.cardHeight { config.cardHeight = height }
        if let tokenHeight = style.tokenHeight { config.tokenHeight = tokenHeight }
        if let bg = style.backgroundColor { config.backgroundColor = MFHelper.getColor(number: bg) }
        // `Direction` has no V3 CSS field — it is consumed as `language` (rtl => arabic).
        config.language = (style.direction?.lowercased() == "rtl") ? .arabic : .english

        // MARK: Input
        if let input = style.input {
            if let value = input.color { config.input.color = MFHelper.getColor(number: value) }
            if let value = input.backgroundColor { config.input.backgroundColor = MFHelper.getColor(number: value) }
            if let value = input.borderColor { config.input.borderColor = MFHelper.getColor(number: value) }
            if let value = input.fontSize { config.input.fontSize = value }
            if let value = input.fontFamily { config.input.fontFamily = value }
            if let value = input.inputHeight { config.input.inputHeight = value }
            if let value = input.inputMargin { config.input.inputMargin = value }
            if let value = input.borderWidth { config.input.borderWidth = value }
            if let value = input.borderRadius { config.input.borderRadius = value }
            if let value = input.outerRadius { config.input.outerRadius = value }
            if let shadow = boxShadow(from: input.boxShadow) { config.input.boxShadow = shadow }
            if let placeHolder = input.placeHolder {
                if let value = placeHolder.holderName { config.input.placeholder.holderName = value }
                if let value = placeHolder.cardNumber { config.input.placeholder.cardNumber = value }
                if let value = placeHolder.expiryDate { config.input.placeholder.expiryDate = value }
                if let value = placeHolder.securityCode { config.input.placeholder.securityCode = value }
                // NOTE: PlaceHolder.Color has no V3 equivalent (placeholder is text-only) — dropped.
            }
        }

        // MARK: Label
        if let label = style.label {
            if let value = label.display { config.label.display = value }
            if let value = label.color { config.label.color = MFHelper.getColor(number: value) }
            if let value = label.fontSize { config.label.fontSize = value }
            if let value = label.fontFamily { config.label.fontFamily = value }
            if let value = label.fontWeight { config.label.fontWeight = fontWeight(value) }
            if let text = label.text {
                if let value = text.holderName { config.label.text.holderName = value }
                if let value = text.cardNumber { config.label.text.cardNumber = value }
                if let value = text.expiryDate { config.label.text.expiryDate = value }
                if let value = text.securityCode { config.label.text.securityCode = value }
            }
        }

        // MARK: Error (NOTE: Error.BorderWidth is ignored by the widget — not mapped.)
        if let error = style.error {
            if let value = error.borderColor { config.error.borderColor = MFHelper.getColor(number: value) }
            if let value = error.borderRadius { config.error.borderRadius = value }
            if let shadow = boxShadow(from: error.boxShadow) { config.error.boxShadow = shadow }
        }

        // MARK: Saved-card text ("Text" block)
        if let savedCardText = style.savedCardText {
            if let value = savedCardText.saveCardText { config.savedCardText.saveCard = value }
            if let value = savedCardText.addCardText { config.savedCardText.addCard = value }
            if let alert = savedCardText.deleteAlertText {
                if let value = alert.title { config.savedCardText.deleteAlert.title = value }
                if let value = alert.message { config.savedCardText.deleteAlert.message = value }
                if let value = alert.confirm { config.savedCardText.deleteAlert.confirm = value }
                if let value = alert.cancel { config.savedCardText.deleteAlert.cancel = value }
            }
        }

        return config
    }

    private static func boxShadow(from style: MFBoxShadowStyle?) -> MFBoxShadow? {
        guard let style = style else { return nil }
        let color = style.color.map { MFHelper.getColor(number: $0) } ?? .gray
        return MFBoxShadow(hOffset: style.hOffset ?? 0,
                           vOffset: style.vOffset ?? 0,
                           blur: style.blur ?? 0,
                           spread: style.spread ?? 0,
                           color: color)
    }

    // JS weight names ("Thin"…"Heavy") -> MFFontWeight. Mirrors MFCardView.swift's
    // toMFontWeight; the SDK's MFFontWeight(rawValue:) only accepts "100"…"900".
    private static func fontWeight(_ code: String) -> MFFontWeight {
        switch code {
        case "Thin": return .thin
        case "ExtraLight": return .extraLight
        case "Light": return .light
        case "Normal": return .normal
        case "Medium": return .medium
        case "SemiBold": return .semiBold
        case "Bold": return .bold
        case "ExtraBold": return .extraBold
        case "Heavy": return .heavy
        default: return .normal
        }
    }
}
