//
//  KLTFormat.swift
//  MyTatvaCare
//
//  Created by Nirav Ramani on 13/05/25.
//

import Foundation
import Foundation

class KLTFormat {

    // MARK: - Hex and Data Conversion

    static func dataWithHexString(_ hexString: String) -> Data? {
        guard hexString.count % 2 == 0 else { return nil }

        var data = Data()
        var index = hexString.startIndex
        for _ in 0..<hexString.count/2 {
            let nextIndex = hexString.index(index, offsetBy: 2)
            let byteString = hexString[index..<nextIndex]
            if let num = UInt8(byteString, radix: 16) {
                data.append(num)
            } else {
                return nil
            }
            index = nextIndex
        }
        return data
    }

    static func dataToHexString(_ data: Data, isReverse: Bool) -> String {
        let bytes = isReverse ? Data(data.reversed()) : data
        return bytes.map { String(format: "%02X", $0) }.joined()
    }

    func convertDataToHexStr(_ data: Data) -> String {
        return data.map { String(format: "%02x", $0) }.joined()
    }

    static func intToData(_ value: Int) -> Data {
        let bytes: [UInt8] = [UInt8((value >> 8) & 0xFF), UInt8(value & 0xFF)]
        return Data(bytes)
    }

    static func stringToData(_ string: String) -> Data {
        return Data(string.utf8)
    }

    static func dataToString(_ data: Data) -> String? {
        return String(data: data, encoding: .utf8)
    }

    static func getIntFromHexString(_ str: String) -> UInt64 {
        return UInt64(str, radix: 16) ?? 0
    }

    // MARK: - Date Handling

    static func getDateString() -> String {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_GB")
        formatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
        return formatter.string(from: Date())
    }

    static func getDate(from string: String) -> Date? {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_GB")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return formatter.date(from: string)
    }

    static func getEventDate(from string: String) -> Date? {
        return getDate(from: string)
    }

    static func getSystemDateTime() -> Data {
        var calendar = Calendar(identifier: .gregorian)
        calendar.locale = Locale(identifier: "en_GB")
        let now = Date()
        let dateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: now)

        var bytes = [UInt8]()
        bytes.append(UInt8((dateComponents.year ?? 0) >> 8))
        bytes.append(UInt8((dateComponents.year ?? 0) & 0xFF))
        bytes.append(UInt8(dateComponents.month ?? 0))
        bytes.append(UInt8(dateComponents.day ?? 0))
        bytes.append(UInt8(dateComponents.hour ?? 0))
        bytes.append(UInt8(dateComponents.minute ?? 0))
        bytes.append(UInt8(dateComponents.second ?? 0))

        return Data(bytes)
    }

    static func getSystemDateTimeCT5() -> Data {
        var calendar = Calendar(identifier: .gregorian)
        calendar.locale = Locale(identifier: "en_GB")
        let now = Date()
        let dateComponents = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: now)

        var bytes = [UInt8]()
        bytes.append(UInt8((dateComponents.year ?? 1900) - 1900))
        bytes.append(UInt8(dateComponents.month ?? 0))
        bytes.append(UInt8(dateComponents.day ?? 0))
        bytes.append(UInt8(dateComponents.hour ?? 0))
        bytes.append(UInt8(dateComponents.minute ?? 0))
        bytes.append(UInt8(dateComponents.second ?? 0))

        return Data(bytes)
    }

    // MARK: - Self Check Info Parsing

    static func handleSelfCheckInfo(_ hex: String) -> [Any] {
        var result: [Any] = []

        let voltageHex = String(hex.prefix(4))
        result.append(Double(getIntFromHexString(voltageHex)) * 0.1)

        let energyHex = String(hex[hex.index(hex.startIndex, offsetBy: 4)..<hex.index(hex.startIndex, offsetBy: 8)])
        result.append(Double(getIntFromHexString(energyHex)) * 0.1)

        for i in stride(from: 8, to: hex.count, by: 2) {
            let start = hex.index(hex.startIndex, offsetBy: i)
            let end = hex.index(start, offsetBy: 2)
            let substring = String(hex[start..<end])
            let temp = getIntFromHexString(substring)

            switch i - 8 {
            case 0:
                var temperature: Double = 0.0
                if (temp & 0x80) == 0 {
                    temperature = Double(temp)
                } else {
                    temperature = Double(temp - 0x80) + 0.5
                }
                result.append(temperature)

            case 2:
                result.append(temp)

            default:
                break
            }
        }

        return result
    }
}
