//
//  Firework+JsEvent.swift
//  react-native-firework-sdk
//
//  Created by Jeff on 2021/12/21.
//

import FireworkVideo
import Foundation

extension FireworkVideoSDKError {
    var jsErrorName: String {
        switch self {
        case .missingAppID:
            return "missingAppID"
        case .missingPublisherID:
            return "missingPublisherID"
        case .authenticationFailure:
            return "authenticationFailure"
        default:
            return "unknow"
        }
    }
}

extension VideoPlaybackDetails {
    var jsObject: [String: Any] {
        var result: [String: Any] = [
            "videoId": videoID,
            "duration": duration,
            "playerSize": [
                "width": playerSize.width,
                "height": playerSize.height
            ],
            "hasCTA": hasCTA,
            "progress": progress,
            // Always emit hashtags, as an empty array when the video has none, so the JS side
            // gets a consistent array like it does on Android.
            "hashtags": hashtags
        ]

        // Only emit the optional strings when they actually have a value, so the JS side
        // sees `undefined` rather than an empty string, which is what Android does.
        let optionalValues: [String: String?] = [
            "caption": caption,
            "badge": badge,
            "ctaActionType": ctaActionType,
            "ctaActionURL": ctaActionURL,
            "feedId": feedId,
            "videoType": videoType?.rawValue,
            "liveStreamStatus": liveStreamStatus?.rawValue
        ]

        for (key, value) in optionalValues {
            if let value = value, !value.isEmpty {
                result[key] = value
            }
        }

        return result
    }
}

extension VideoFeedError {
    var jsObject: [String: String] {
        var error: [String: String] = [:]
        switch self {
        case .contentSourceError(let sourceError):
            error = [
                "name": "contentSourceError",
                "reason": sourceError.failureReason ?? "Content source error"
            ]
        case .videoShareError(let shareError):
            error = [
                "name": "videoShareError",
                "reason": shareError.failureReason ?? "Video share error"
            ]
        case .unknownError(let unknownError):
            error = ["name": "unknownError", "reason": unknownError.localizedDescription]
        default:
            error = ["name": "unknownError", "reason": "Unknown error"]
        }

        return error
    }
}

extension FeedEventDetails {
    var jsObject: [String: Any] {
        var result: [String: Any] = [
            "index": index,
            "id": id,
            "duration": duration,
            "feedId": feedId
        ]

        if let title = caption {
            result["title"] = title
        }

        if let videoTypeValue = videoType?.rawValue {
            result["videoType"] = videoTypeValue
        }

        if let liveStreamStatusValue = liveStreamStatus?.rawValue {
            result["liveStreamStatus"] = liveStreamStatusValue
        }

        var sourceStr: String = ""
        switch source {
        case .discover:
            sourceStr = "discover"
        case .channel(let channelID):
            sourceStr = "channel"
            result["channel"] = channelID
        case .channelPlaylist(let channelID, let playlistID):
            sourceStr = "playlist"
            result["channel"] = channelID
            result["playlist"] = playlistID
        case .playlistGroup(groupID: let playlistGroupID):
            sourceStr = "playlistGroup"
            result["playlistGroup"] = playlistGroupID
        case .dynamicContent(let channelID, let parameters):
            sourceStr = "dynamicContent"
            result["channel"] = channelID
            result["dynamicContentParameters"] = parameters
        case .hashtagPlaylist(let channelID, let hashtagFilterExpression):
            sourceStr = "hashtagPlaylist"
            result["channel"] = channelID
            result["hashtagFilterExpression"] = hashtagFilterExpression
        default:
            break
        }

        result["source"] = sourceStr

        return result
    }
}

extension LiveStreamEventDetails {
    var jsObject: [String: Any] {
        var result: [String: Any] = [
            "id": videoID,
            "feedId": feedID,
            "video": video.jsObject
        ]

        if let videoTypeValue = video.videoType?.rawValue {
            result["videoType"] = videoTypeValue
        }

        if let liveStreamStatusValue = status?.rawValue {
            result["liveStreamStatus"] = liveStreamStatusValue
        }

        return result
    }
}

extension LiveStreamMessageDetails {
    var jsObject: [String: Any] {
        return [
            "messageId": messageID,
            "username": username,
            "text": text
        ]
    }
}

extension StoryBlockError {
    var jsObject: [String: String] {
        var error: [String: String] = [:]
        switch self {
        case .contentSourceError(let sourceError):
            error = [
                "name": "contentSourceError",
                "reason": sourceError.failureReason ?? "Content source error"
            ]
        case .videoShareError(let shareError):
            error = [
                "name": "videoShareError",
                "reason": shareError.failureReason ?? "Video share error"
            ]
        case .unknownError(underlyingError: let unknownError):
            error = ["name": "unknownError", "reason": unknownError.localizedDescription]
        default:
            error = ["name": "unknownError", "reason": "Unknown error"]
        }

        return error
    }
}

extension SelectedProductVariant {
    var jsObject: [String: Any] {
        return [
            "url": url?.absoluteString ?? "",
            "productId": productID,
            "unitId": unitID
        ]
    }
}
