import Combine
import Foundation

// MARK: - GroupMember

struct GroupMember: Identifiable {
    let id: String  // publicKey
    var title: String
    var username: String
    var isAdmin: Bool
    var isOnline: Bool
    var verified: Int
}

// MARK: - GroupInfoViewModel

@MainActor
final class GroupInfoViewModel: ObservableObject {
    let groupDialogKey: String

    @Published var groupTitle: String = ""
    @Published var groupDescription: String = ""
    @Published var members: [GroupMember] = []
    @Published var isAdmin: Bool = false
    @Published var isLoading: Bool = false
    @Published var isLeaving: Bool = false
    @Published var errorMessage: String?
    @Published var didLeaveGroup: Bool = false
    @Published var inviteString: String?

    private let groupService = GroupService.shared
    private let groupRepo = GroupRepository.shared

    init(groupDialogKey: String) {
        self.groupDialogKey = groupDialogKey
        loadLocalMetadata()
    }

    private func loadLocalMetadata() {
        let account = SessionManager.shared.currentPublicKey
        if let meta = groupRepo.groupMetadata(account: account, groupDialogKey: groupDialogKey) {
            groupTitle = meta.title
            groupDescription = meta.description
        }
    }

    func loadMembers() async {
        isLoading = true
        do {
            let memberKeys = try await groupService.requestMembers(groupDialogKey: groupDialogKey)
            let myKey = SessionManager.shared.currentPublicKey

            var resolved: [GroupMember] = []
            for (index, key) in memberKeys.enumerated() {
                let dialog = DialogRepository.shared.dialogs[key]
                resolved.append(GroupMember(
                    id: key,
                    title: dialog?.opponentTitle ?? String(key.prefix(12)),
                    username: dialog?.opponentUsername ?? "",
                    isAdmin: index == 0,
                    isOnline: dialog?.isOnline ?? false,
                    verified: dialog?.verified ?? 0
                ))
            }
            members = resolved
            isAdmin = memberKeys.first == myKey
        } catch {
            errorMessage = error.localizedDescription
        }
        isLoading = false
    }

    func leaveGroup() async {
        isLeaving = true
        do {
            try await groupService.leaveGroup(groupDialogKey: groupDialogKey)
            didLeaveGroup = true
        } catch {
            errorMessage = error.localizedDescription
        }
        isLeaving = false
    }

    func kickMember(publicKey: String) async {
        do {
            try await groupService.kickMember(groupDialogKey: groupDialogKey, memberPublicKey: publicKey)
            members.removeAll { $0.id == publicKey }
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    func generateInvite() {
        inviteString = groupService.generateInviteString(groupDialogKey: groupDialogKey)
    }
}
