import DiscordKit

struct Actions {
    static func getUserFromMention(_ mention: MentionUser) -> String {
        mention.member?.nick ?? mention.global_name ?? mention.username
    }

    static func performAction(ctx: MessageCreate, client: ApiClient, resOpts: [String]) async throws {
        let author = "**\(ctx.member?.nick ?? ctx.author?.global_name ?? ctx.author?.username ?? "Zundamon")**"
        let dests = ctx.mentions.map(getUserFromMention).map({ "**\($0)**" })
        let orig: String
        let dest: String
        if let firstDest = dests.first {
            orig = "\(author)"
            dest = "\(firstDest)"
        } else {
            orig = "**Zundamon**"
            dest = "\(author)"
        }

        guard let res = resOpts.randomElement()?
            .replacingOccurrences(of: "{orig}", with: orig)
            .replacingOccurrences(of: "{dest}", with: dest)
        else { print("retOptions empty"); return }

        let retMsg = res

        try await client.createMessage(
            channelId: ctx.channel_id,
            payload: .init(
                embeds: [.init(description: retMsg)],
            )
        )
    }

    static let hugRes = (try? String(contentsOfFile: "resources/choices/hug.txt", encoding: .utf8))?
        .split(separator: "\n")
        .map({ $0.trimmingCharacters(in: .whitespacesAndNewlines) })

    static func hug(
        _ args: ArraySlice<String.SubSequence>,
        client: ApiClient,
        ctx: MessageCreate
    ) async throws {
        guard let hugRes = hugRes else { print("hug.txt not loaded"); return }
        let author = "**\(ctx.member?.nick ?? ctx.author?.global_name ?? ctx.author?.username ?? "Zundamon")**"
        let dests = ctx.mentions.map(getUserFromMention).map({ "**\($0)**" })

        let retMsg: String

        if dests.count > 1 {
            let groupHugs = [
                "{subjects} all huddled together.",
                "{subjects} hugged each other pairwise, generating a total of **{total}** hugs.",
                "{subjects} hugged each other at the same time in the same place (although I'm not sure how that works with the current understanding of spacetime).",
            ]

            let group = [author] + dests
            let total = String(group.count)
            let subjects = String(group.joined(separator: ", "))

            guard let res = groupHugs.randomElement()?
                .replacingOccurrences(of: "{subjects}", with: subjects)
                .replacingOccurrences(of: "{total}", with: total)
            else { print("groupHugs.randomElement() returned null"); return }

            retMsg = res
        } else {
            let orig: String
            let dest: String
            if let firstDest = dests.first {
                orig = "\(author)"
                dest = "\(firstDest)"
            } else {
                orig = "**Zundamon**"
                dest = "\(author)"
            }

            guard let res = hugRes.randomElement()?
                .replacingOccurrences(of: "{orig}", with: orig)
                .replacingOccurrences(of: "{dest}", with: dest)
            else { print("hug.txt empty"); return }

            retMsg = res
        }

        try await client.createMessage(
            channelId: ctx.channel_id,
            payload: .init(
                embeds: [.init(description: retMsg)],
            )
        )
    }

    static let patRes = (try? String(contentsOfFile: "resources/choices/pat.txt", encoding: .utf8))?
        .split(separator: "\n")
        .map({ $0.trimmingCharacters(in: .whitespacesAndNewlines) })

    static func pat(
        _ args: ArraySlice<String.SubSequence>,
        client: ApiClient,
        ctx: MessageCreate
    ) async throws {
        guard let patRes = patRes else { print("pat.txt not loaded"); return }
        try await performAction(ctx: ctx, client: client, resOpts: patRes)
    }
}
