import Foundation import SwiftUI @MainActor class ClubViewModel: ObservableObject { @Published var clubs: [Club] = [] @Published var selectedClub: Club? @Published var members: [ClubMember] = [] @Published var isLoading: Bool = false @Published var error: ClubError? @Published var filter: ClubFilter = ClubFilter() private let service: ClubServiceProtocol init(service: ClubServiceProtocol = ClubService()) { self.service = service } func fetchClubs() async { isLoading = true error = nil defer { isLoading = false } do { clubs = try await service.listClubs(filter: filter) } catch let error as ClubError { self.error = error } catch { print("Failed to fetch clubs: \(error)") } } func selectClub(id: String) async { isLoading = true error = nil defer { isLoading = false } do { let result = try await service.getClub(id: id) selectedClub = result.club members = result.members if let index = clubs.firstIndex(where: { $0.id == id }) { clubs[index] = result.club objectWillChange.send() } } catch let error as ClubError { self.error = error } catch { print("Failed to get club: \(error)") } } func createClub(request: CreateClubRequest) async -> Club? { isLoading = true error = nil defer { isLoading = false } do { let club = try await service.createClub(request: request) clubs.insert(club, at: 0) objectWillChange.send() return club } catch let error as ClubError { self.error = error return nil } catch { print("Failed to create club: \(error)") return nil } } func updateClub(id: String, request: UpdateClubRequest) async { isLoading = true error = nil defer { isLoading = false } do { let updatedClub = try await service.updateClub(id: id, request: request) if let index = clubs.firstIndex(where: { $0.id == id }) { clubs[index] = updatedClub objectWillChange.send() } if selectedClub?.id == id { selectedClub = updatedClub } } catch let error as ClubError { self.error = error } catch { print("Failed to update club: \(error)") } } func joinClub(id: String) async { do { try await service.joinClub(id: id) if let index = clubs.firstIndex(where: { $0.id == id }) { clubs[index].membershipStatus = .active clubs[index].memberCount += 1 objectWillChange.send() } } catch { print("Failed to join club: \(error)") } } func leaveClub(id: String) async { do { try await service.leaveClub(id: id) if let index = clubs.firstIndex(where: { $0.id == id }) { clubs[index].membershipStatus = .left clubs[index].memberCount = max(0, clubs[index].memberCount - 1) objectWillChange.send() } } catch { print("Failed to leave club: \(error)") } } func inviteMember(clubId: String, email: String) async { do { try await service.inviteMember(clubId: clubId, email: email) } catch { print("Failed to invite member: \(error)") } } func removeMember(clubId: String, memberId: String) async { do { try await service.removeMember(clubId: clubId, memberId: memberId) if let index = members.firstIndex(where: { $0.id == memberId }) { members.remove(at: index) if let clubIndex = clubs.firstIndex(where: { $0.id == clubId }) { clubs[clubIndex].memberCount = max(0, clubs[clubIndex].memberCount - 1) } objectWillChange.send() } } catch { print("Failed to remove member: \(error)") } } var publicClubs: [Club] { clubs.filter { $0.privacy == .publicPrivacy } } var userClubs: [Club] { clubs.filter { $0.membershipStatus == .active } } var pendingClubs: [Club] { clubs.filter { $0.membershipStatus == .pending } } var clubTypes: [ClubType] { ClubType.allCases } var privacyOptions: [ClubPrivacy] { ClubPrivacy.allCases } }