import Foundation

public struct ConfigValidator {

    public struct Result: Equatable {
        public let clientID: String
        public let clientToken: String
        public let workflowTemplateId: String?
        public let hasStagesArray: Bool

        public init(clientID: String,
                    clientToken: String,
                    workflowTemplateId: String?,
                    hasStagesArray: Bool) {
            self.clientID = clientID
            self.clientToken = clientToken
            self.workflowTemplateId = workflowTemplateId
            self.hasStagesArray = hasStagesArray
        }
    }

    // Canonical keys (mirrors Android & current iOS)
    public enum Key {
        public static let clientID = "clientID"
        public static let clientToken = "clientToken"
        public static let workflowTemplateId = "workflowTemplateId"
        public static let stages = "stages"
        public static let countries = "countries"
        public static let lookAndFeel = "lookAndFeel"
        public static let scheme = "scheme"
    }

    /// Validates presence and basic shape of the core fields.
    /// - Parameter raw: untrusted config from Flutter/host app
    /// - Returns: normalized `Result`
    /// - Throws: `ConfigurationError`
    public static func validate(_ raw: [String: Any]) throws -> Result {
        var issues: [String] = []

        // clientID
        guard let clientID = raw[Key.clientID] as? String, !clientID.isEmpty else {
            issues.append("Missing or empty '\(Key.clientID)'")
            throw ConfigurationError.validationFailed(issues)
        }

        // clientToken
        guard let clientToken = raw[Key.clientToken] as? String, !clientToken.isEmpty else {
            issues.append("Missing or empty '\(Key.clientToken)'")
            throw ConfigurationError.validationFailed(issues)
        }

        // workflowTemplateId (optional)
        let workflowId: String? = {
            if let v = raw[Key.workflowTemplateId] as? String, !v.isEmpty { return v }
            return nil
        }()

        // stages array (optional)
        let hasStagesArray: Bool = {
            guard let arr = raw[Key.stages] else { return false }
            if arr is [Any] { return true }
            // Wrong type but present
            issues.append("'\(Key.stages)' must be an array when provided")
            return false
        }()

        // Require either workflowTemplateId or stages
        if workflowId == nil && !hasStagesArray {
            issues.append("Provide either '\(Key.workflowTemplateId)' or a '\(Key.stages)' array")
            throw ConfigurationError.validationFailed(issues)
        }

        // If there were only soft issues, throw; otherwise succeed
        if !issues.isEmpty {
            throw ConfigurationError.validationFailed(issues)
        }

        return Result(clientID: clientID,
                      clientToken: clientToken,
                      workflowTemplateId: workflowId,
                      hasStagesArray: hasStagesArray)
    }
}
