//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//

extension TSInfoMessage {
    static func makeForThreadMerge(
        mergedThread: TSContactThread,
        timestamp: UInt64 = MessageTimestampGenerator.sharedInstance.generateTimestamp(),
        previousE164: String?,
    ) -> TSInfoMessage {
        let infoMessageUserInfo: [InfoMessageUserInfoKey: Any] = if let previousE164 {
            [.threadMergePhoneNumber: previousE164]
        } else {
            [:]
        }

        return TSInfoMessage(
            thread: mergedThread,
            messageType: .threadMerge,
            timestamp: timestamp,
            infoMessageUserInfo: infoMessageUserInfo,
        )
    }
}

public extension TSInfoMessage {
    /// If this info message represents an E164/PNI -> ACI thread merge event,
    /// returns the "before" thread's E164.
    var threadMergePhoneNumber: String? {
        return infoMessageValue(forKey: .threadMergePhoneNumber)
    }

    func threadMergeDescription(tx: DBReadTransaction) -> String {
        let displayName = contactThreadDisplayName(tx: tx)
        if let phoneNumber = threadMergePhoneNumber {
            let formatString = OWSLocalizedString(
                "THREAD_MERGE_PHONE_NUMBER",
                comment: "A system event shown in a conversation when multiple conversations for the same person have been merged into one. The parameters are replaced with the contact's name (eg John Doe) and their phone number (eg +1 650 555 0100).",
            )
            let formattedPhoneNumber = PhoneNumber.bestEffortLocalizedPhoneNumber(e164: phoneNumber)
            return String.nonPluralLocalizedStringWithFormat(formatString, displayName, formattedPhoneNumber)
        } else {
            let formatString = OWSLocalizedString(
                "THREAD_MERGE_NO_PHONE_NUMBER",
                comment: "A system event shown in a conversation when multiple conversations for the same person have been merged into one. The parameter is replaced with the contact's name (eg John Doe).",
            )
            return String.nonPluralLocalizedStringWithFormat(formatString, displayName)
        }
    }

    private func contactThreadDisplayName(tx: DBReadTransaction) -> String {
        guard
            let contactThread = DependenciesBridge.shared.threadStore
                .fetchThread(uniqueId: uniqueThreadId, tx: tx) as? TSContactThread
        else {
            return CommonStrings.unknownUser
        }

        return SSKEnvironment.shared.contactManagerRef.displayName(
            for: contactThread.contactAddress,
            tx: tx,
        ).resolvedValue()
    }
}
