//
/*
 * Copyright (c) 2023 BWI GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import Foundation
import MatrixSDK

@objc class BWIAnalyticsHelper: NSObject {
    @objc static let shared = BWIAnalyticsHelper()
    
    private let serialQueue = DispatchQueue(label: "de.bwi.analyticshelper.serialQueue")
    
    @objc func getRoomDeviceCount(room: MXRoom, completion: @escaping(Int) -> ()) {
        // only ask for devices per room if a refresh is needed -> room.mxSession.crypto.devices is costly in large rooms. And even with that performance win don't do it on Mainthread
        serialQueue.async {
            if LazyRoomDevices.shared.areDevicesCurrent(room: room) {
                completion(LazyRoomDevices.shared.deviceCount(room: room))
                return
            }
            
            room.members { roomMembers in
                var noOfDevices = 0
                for member in roomMembers?.joinedMembers ?? [MXRoomMember]() {
                    noOfDevices += room.mxSession.crypto.devices(forUser: member.userId).count
                }
                LazyRoomDevices.shared.setDeviceCount(room: room, deviceCount: noOfDevices)
                completion(noOfDevices)
                
            } lazyLoadedMembers: { _ in
                completion(0)
            } failure: { error in
                MXLog.error("[RoomAnalyticsHelper] Failed loading room", context: error)
                completion(0)
            }
        }
    }
    
    @objc func getForwardingType(event: MXEvent) -> String? {
        guard let messageType: MXMessageType = event.messageType else {
            return nil
        }
        switch messageType {
        case .text:
            return "text"
        case .image:
            return "image"
        case .video:
            return "video"
        case .audio:
            if (event.content["org.matrix.msc2516.voice"] != nil) || (event.content["org.matrix.msc3245.voice"] != nil) {
                return "voice_message"
            } else {
                return "audio"
            }
        case .emote:
            return nil
        case .notice:
            return nil
        case .location:
            return "location"
        case .file:
            return "file"
        case .custom(_):
            return nil
        }
    }
    
    // MARK: custom dimensions
    
    @objc func dimensionForDeviceCount(_ deviceCount: Int) -> String {
        if deviceCount <= 0 {
            return "Undefiniert"
        }
        if deviceCount <= 10 {
            return "1 bis 10"
        }
        if deviceCount <= 100 {
            return "11 bis 100"
        }
        if deviceCount <= 200 {
            return "101 bis 200"
        }
        if deviceCount <= 500 {
            return "201 bis 500"
        }
        if deviceCount <= 1000 {
            return "501 bis 1000"
        }
        if deviceCount <= 2500 {
            return "1001 bis 2500"
        } else {
            return "mehr als 2500"
        }
    }
}
