import User from './User.js';
import Log from './Log.js';
import Club from './Club.js';
import UserClub from './UserClub.js';
import DiaryDate from './DiaryDates.js';
import Participant from './Participant.js';
import Member from './Member.js';
import Activity from './Activity.js';
import DiaryNote from './DiaryNote.js';
import { DiaryTag, MemberDiaryTag } from './DiaryTag.js';
import MemberNote from './MemberNote.js';
import DiaryDateTag from './DiaryDateTag.js';
import DiaryMemberNote from './DiaryMemberNote.js';
import DiaryMemberTag from './DiaryMemberTag.js';
import PredefinedActivity from './PredefinedActivity.js';
import DiaryMemberActivity from './DiaryMemberActivity.js';
import PredefinedActivityImage from './PredefinedActivityImage.js';
import DiaryDateActivity from './DiaryDateActivity.js';
import Match from './Match.js';
import League from './League.js';
import Team from './Team.js';
import ClubTeam from './ClubTeam.js';
import ClubTeamMember from './ClubTeamMember.js';
import TeamDocument from './TeamDocument.js';
import Season from './Season.js';
import Location from './Location.js';
import Group from './Group.js';
import GroupActivity from './GroupActivity.js';
import Tournament from './Tournament.js';
import TournamentGroup from './TournamentGroup.js';
import TournamentClass from './TournamentClass.js';
import TournamentMember from './TournamentMember.js';
import TournamentMatch from './TournamentMatch.js';
import TournamentResult from './TournamentResult.js';
import ExternalTournamentParticipant from './ExternalTournamentParticipant.js';
import TournamentPairing from './TournamentPairing.js';
import TournamentStage from './TournamentStage.js';
import TournamentStageAdvancement from './TournamentStageAdvancement.js';
import Accident from './Accident.js';
import UserToken from './UserToken.js';
import OfficialTournament from './OfficialTournament.js';
import OfficialCompetition from './OfficialCompetition.js';
import OfficialCompetitionMember from './OfficialCompetitionMember.js';
import MyTischtennis from './MyTischtennis.js';
import MyTischtennisUpdateHistory from './MyTischtennisUpdateHistory.js';
import MyTischtennisFetchLog from './MyTischtennisFetchLog.js';
import ApiLog from './ApiLog.js';
import MemberTransferConfig from './MemberTransferConfig.js';
import MemberContact from './MemberContact.js';
import MemberImage from './MemberImage.js';
import MemberOrder from './MemberOrder.js';
import MemberOrderHistory from './MemberOrderHistory.js';
import MemberGroupPhoto from './MemberGroupPhoto.js';
import BillingTemplate from './BillingTemplate.js';
import BillingTemplateField from './BillingTemplateField.js';
import BillingRun from './BillingRun.js';
import BillingDocument from './BillingDocument.js';
import BillingDocumentValue from './BillingDocumentValue.js';
import BillingUserSetting from './BillingUserSetting.js';
import ClubDocument from './ClubDocument.js';
import ClubDocumentVersion from './ClubDocumentVersion.js';
import ClubDocumentLink from './ClubDocumentLink.js';
import FriendlyMatch from './FriendlyMatch.js';
import FriendlyMatchShared from './FriendlyMatchShared.js';
import FriendlyMatchInvitation from './FriendlyMatchInvitation.js';
import MemberTtrHistory from './MemberTtrHistory.js';
import MemberPlayInterest from './MemberPlayInterest.js';
import ClickTtAccount from './ClickTtAccount.js';
import CalendarEvent from './CalendarEvent.js';
import TrainingCancellation from './TrainingCancellation.js';
import TrainingGroup from './TrainingGroup.js';
import MemberTrainingGroup from './MemberTrainingGroup.js';
import ClubDisabledPresetGroup from './ClubDisabledPresetGroup.js';
import TrainingTime from './TrainingTime.js';
import ClubVenue from './ClubVenue.js';
import ClubRequest from './ClubRequest.js';
import ClubRequestNote from './ClubRequestNote.js';
import ClubSepaMandate from './ClubSepaMandate.js';
import ClubPaymentClaim from './ClubPaymentClaim.js';
import ClubAccount from './ClubAccount.js';
import ClubAccountTransaction from './ClubAccountTransaction.js';
import ClubInvoiceParty from './ClubInvoiceParty.js';
import ClubInvoice from './ClubInvoice.js';
import ClubInvoiceItem from './ClubInvoiceItem.js';
import ClubTask from './ClubTask.js';
import ClubTaskSuppression from './ClubTaskSuppression.js';
import ClubRole from './ClubRole.js';
import ClubUserRole from './ClubUserRole.js';
import ClubCommunicationThread from './ClubCommunicationThread.js';
import ClubCommunicationMessage from './ClubCommunicationMessage.js';
import ClubCommunicationRecipient from './ClubCommunicationRecipient.js';
import ClubCommunicationDeliveryLog from './ClubCommunicationDeliveryLog.js';
import ClubCommunicationTemplate from './ClubCommunicationTemplate.js';
import ClubDistributionGroup from './ClubDistributionGroup.js';
import ClubDistributionGroupMember from './ClubDistributionGroupMember.js';
// Official tournaments relations
OfficialTournament.hasMany(OfficialCompetition, { foreignKey: 'tournamentId', as: 'competitions' });
OfficialCompetition.belongsTo(OfficialTournament, { foreignKey: 'tournamentId', as: 'tournament' });
// Official competition participations
OfficialCompetition.hasMany(OfficialCompetitionMember, { foreignKey: 'competitionId', as: 'members' });
OfficialCompetitionMember.belongsTo(OfficialCompetition, { foreignKey: 'competitionId', as: 'competition' });
OfficialTournament.hasMany(OfficialCompetitionMember, { foreignKey: 'tournamentId', as: 'competitionMembers' });
OfficialCompetitionMember.belongsTo(OfficialTournament, { foreignKey: 'tournamentId', as: 'tournament' });
Member.hasMany(OfficialCompetitionMember, { foreignKey: 'memberId', as: 'officialCompetitionEntries' });
OfficialCompetitionMember.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });

User.hasMany(Log, { foreignKey: 'userId' });
Log.belongsTo(User, { foreignKey: 'userId' });

User.belongsToMany(Club, { through: UserClub, foreignKey: 'userId' });
Club.belongsToMany(User, { through: UserClub, foreignKey: 'clubId' });

DiaryDate.belongsTo(Club, { foreignKey: 'clubId' });
Club.hasMany(DiaryDate, { foreignKey: 'clubId' });

DiaryDate.belongsToMany(Member, { through: Participant, as: 'participants', foreignKey: 'diaryDateId' });
Member.belongsToMany(DiaryDate, { through: Participant, as: 'diaryDates', foreignKey: 'memberId' });

// Explizite Assoziationen für Participant
Participant.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDate' });
Participant.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
DiaryDate.hasMany(Participant, { foreignKey: 'diaryDateId', as: 'participantList' });
Member.hasMany(Participant, { foreignKey: 'memberId', as: 'participantList' });

DiaryDate.hasMany(Activity, { as: 'activities', foreignKey: 'diaryDateId' });
Activity.belongsTo(DiaryDate, { as: 'diaryDate', foreignKey: 'diaryDateId' });

Member.hasMany(DiaryNote, { as: 'diaryNotes', foreignKey: 'memberId' });
DiaryNote.belongsTo(Member, { foreignKey: 'memberId' });

Member.hasMany(MemberNote, { as: 'memberNotes', foreignKey: 'memberId' });
MemberNote.belongsTo(Member, { foreignKey: 'memberId' });

DiaryDate.hasMany(DiaryNote, { as: 'diaryNotes', foreignKey: 'diaryDateId' });
DiaryNote.belongsTo(DiaryDate, { foreignKey: 'diaryDateId' });

Member.belongsToMany(DiaryTag, { through: MemberDiaryTag, as: 'tags', foreignKey: 'memberId' });
DiaryTag.belongsToMany(Member, { through: MemberDiaryTag, as: 'members', foreignKey: 'tagId' });

DiaryDate.belongsToMany(DiaryTag, { through: DiaryDateTag, as: 'diaryTags', foreignKey: 'diaryDateId' });
DiaryTag.belongsToMany(DiaryDate, { through: DiaryDateTag, as: 'diaryDates', foreignKey: 'tagId' });

DiaryDate.belongsToMany(Member, { through: DiaryMemberNote, as: 'noteMembers', foreignKey: 'diaryDateId' });
Member.belongsToMany(DiaryDate, { through: DiaryMemberNote, as: 'noteDates', foreignKey: 'memberId' });

DiaryTag.hasMany(DiaryMemberTag, { foreignKey: 'tagId', as: 'diaryMemberTags' });
DiaryMemberTag.belongsTo(DiaryTag, { foreignKey: 'tagId', as: 'tag' });

DiaryDate.hasMany(DiaryDateActivity, { foreignKey: 'diaryDateId', as: 'diaryDateActivities' });
DiaryDateActivity.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDate' });

PredefinedActivity.hasMany(DiaryDateActivity, { foreignKey: 'predefinedActivityId', as: 'predefinedActivities' });
DiaryDateActivity.belongsTo(PredefinedActivity, { foreignKey: 'predefinedActivityId', as: 'predefinedActivity' });
// DiaryMemberActivity links a Participant to a DiaryDateActivity
DiaryMemberActivity.belongsTo(DiaryDateActivity, { foreignKey: 'diaryDateActivityId', as: 'activity' });
DiaryDateActivity.hasMany(DiaryMemberActivity, { foreignKey: 'diaryDateActivityId', as: 'activityMembers' });
DiaryMemberActivity.belongsTo(Participant, { foreignKey: 'participantId', as: 'participant' });
Participant.hasMany(DiaryMemberActivity, { foreignKey: 'participantId', as: 'memberActivities' });
// PredefinedActivity Images
PredefinedActivity.hasMany(PredefinedActivityImage, { foreignKey: 'predefinedActivityId', as: 'images' });
PredefinedActivityImage.belongsTo(PredefinedActivity, { foreignKey: 'predefinedActivityId', as: 'predefinedActivity' });

Club.hasMany(Match, { foreignKey: 'clubId', as: 'matches' });
Match.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

League.hasMany(Match, { foreignKey: 'leagueId', as: 'leagueMatches' });
Match.belongsTo(League, { foreignKey: 'leagueId', as: 'leagueDetails' });

Team.hasMany(Match, { foreignKey: 'homeTeamId', as: 'homeMatches' });
Team.hasMany(Match, { foreignKey: 'guestTeamId', as: 'guestMatches' });
Match.belongsTo(Team, { foreignKey: 'homeTeamId', as: 'homeTeam' });
Match.belongsTo(Team, { foreignKey: 'guestTeamId', as: 'guestTeam' });

Club.hasMany(Team, { foreignKey: 'clubId', as: 'teams' });
Team.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

Club.hasMany(League, { foreignKey: 'clubId', as: 'leagues' });
League.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

Season.hasMany(League, { foreignKey: 'seasonId', as: 'leagues' });
League.belongsTo(Season, { foreignKey: 'seasonId', as: 'season' });

League.hasMany(Team, { foreignKey: 'leagueId', as: 'teams' });
Team.belongsTo(League, { foreignKey: 'leagueId', as: 'league' });

Season.hasMany(Team, { foreignKey: 'seasonId', as: 'teams' });
Team.belongsTo(Season, { foreignKey: 'seasonId', as: 'season' });

// ClubTeam relationships
Club.hasMany(ClubTeam, { foreignKey: 'clubId', as: 'clubTeams' });
ClubTeam.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

League.hasMany(ClubTeam, { foreignKey: 'leagueId', as: 'clubTeams' });
ClubTeam.belongsTo(League, { foreignKey: 'leagueId', as: 'league' });

Season.hasMany(ClubTeam, { foreignKey: 'seasonId', as: 'clubTeams' });
ClubTeam.belongsTo(Season, { foreignKey: 'seasonId', as: 'season' });
ClubTeam.hasMany(ClubTeamMember, { foreignKey: 'clubTeamId', as: 'lineupMembers' });
ClubTeamMember.belongsTo(ClubTeam, { foreignKey: 'clubTeamId', as: 'clubTeam' });
Member.hasMany(ClubTeamMember, { foreignKey: 'memberId', as: 'clubTeamAssignments' });
ClubTeamMember.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });

// TeamDocument relationships
ClubTeam.hasMany(TeamDocument, { foreignKey: 'clubTeamId', as: 'documents' });
TeamDocument.belongsTo(ClubTeam, { foreignKey: 'clubTeamId', as: 'clubTeam' });

Club.hasMany(ClubDocument, { foreignKey: 'clubId', as: 'documents' });
ClubDocument.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubDocument.hasMany(ClubDocumentVersion, { foreignKey: 'documentId', as: 'versions' });
ClubDocumentVersion.belongsTo(ClubDocument, { foreignKey: 'documentId', as: 'document' });
ClubDocument.hasMany(ClubDocumentLink, { foreignKey: 'documentId', as: 'links' });
ClubDocumentLink.belongsTo(ClubDocument, { foreignKey: 'documentId', as: 'document' });

Match.belongsTo(Location, { foreignKey: 'locationId', as: 'location' });
Location.hasMany(Match, { foreignKey: 'locationId', as: 'matches' });

User.belongsToMany(Club, { through: UserClub, foreignKey: 'userId' });
Club.belongsToMany(User, { through: UserClub, foreignKey: 'clubId' });

UserClub.belongsTo(User, { foreignKey: 'userId', as: 'user' });
User.hasMany(UserClub, { foreignKey: 'userId' });

UserClub.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Club.hasMany(UserClub, { foreignKey: 'clubId' });

Group.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDateGroup' });
DiaryDate.hasMany(Group, { foreignKey: 'diaryDateId', as: 'groupsDiaryDate' });

GroupActivity.belongsTo(DiaryDateActivity, { foreignKey: 'diaryDateActivity', as: 'activityGroupActivity' });
DiaryDateActivity.hasMany(GroupActivity, { foreignKey: 'diaryDateActivity', as: 'groupActivities' });

Group.hasOne(GroupActivity, { foreignKey: 'groupId', as: 'groupGroupActivity' });
GroupActivity.belongsTo(Group, { foreignKey: 'groupId', as: 'groupsGroupActivity' });

GroupActivity.belongsTo(PredefinedActivity, { foreignKey: 'customActivity', as: 'groupPredefinedActivity' });
PredefinedActivity.hasMany(GroupActivity, { foreignKey: 'predefinedActivityId', as: 'groupPredefinedActivities' });

DiaryTag.hasMany(DiaryDateTag, { foreignKey: 'tagId', as: 'diaryDateTags' });
DiaryDateTag.belongsTo(DiaryTag, { foreignKey: 'tagId', as: 'tag' });

DiaryMemberTag.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDates' });
DiaryDate.hasMany(DiaryMemberTag, { foreignKey: 'diaryDateId', as: 'diaryMemberTags' });

Tournament.belongsTo(Club, { foreignKey: 'clubId', as: 'tournamentclub' });
Club.hasMany(Tournament, { foreignKey: 'clubId', as: 'tournaments' });
 
TournamentGroup.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournaments' });
Tournament.hasMany(TournamentGroup, { foreignKey: 'tournamentId', as: 'tournamentGroups' });

// Tournament Stages
TournamentStage.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
Tournament.hasMany(TournamentStage, { foreignKey: 'tournamentId', as: 'stages' });

TournamentStageAdvancement.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
Tournament.hasMany(TournamentStageAdvancement, { foreignKey: 'tournamentId', as: 'stageAdvancements' });

TournamentMember.belongsTo(TournamentGroup, { 
    foreignKey: 'groupId', 
    targetKey: 'id', 
    as: 'group', 
    constraints: false 
});
TournamentGroup.hasMany(TournamentMember, { 
    foreignKey: 'groupId', 
    as: 'tournamentGroupMembers' 
});

TournamentMember.belongsTo(Member, { foreignKey: 'clubMemberId', as: 'member' });
Member.hasMany(TournamentMember, { foreignKey: 'clubMemberId', as: 'tournamentGroupMembers' });

TournamentMember.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
Tournament.hasMany(TournamentMember, { foreignKey: 'tournamentId', as: 'tournamentMembers' });
TournamentMember.belongsTo(TournamentClass, { 
    foreignKey: 'classId', 
    as: 'class', 
    constraints: false 
});
TournamentClass.hasMany(TournamentMember, { 
    foreignKey: 'classId', 
    as: 'members' 
});

TournamentMatch.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
Tournament.hasMany(TournamentMatch, { foreignKey: 'tournamentId', as: 'tournamentMatches' });

TournamentMatch.belongsTo(TournamentGroup, { foreignKey: 'groupId', as: 'group' });
TournamentGroup.hasMany(TournamentMatch, { foreignKey: 'groupId', as: 'tournamentMatches' });

TournamentMatch.hasMany(TournamentResult, {
  foreignKey: 'matchId',
  as: 'tournamentResults',
  onDelete: 'CASCADE',
  onUpdate: 'CASCADE'
});

TournamentResult.belongsTo(TournamentMatch, {
  foreignKey: 'matchId',
  as: 'match',
  onDelete: 'CASCADE',
  onUpdate: 'CASCADE'
});

TournamentMatch.belongsTo(TournamentMember, { foreignKey: 'player1Id', as: 'player1' });
TournamentMatch.belongsTo(TournamentMember, { foreignKey: 'player2Id', as: 'player2' });
TournamentMember.hasMany(TournamentMatch, { foreignKey: 'player1Id', as: 'player1Matches' });
TournamentMember.hasMany(TournamentMatch, { foreignKey: 'player2Id', as: 'player2Matches' });

// Tournament Classes
TournamentClass.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
Tournament.hasMany(TournamentClass, { foreignKey: 'tournamentId', as: 'classes' });

// External Tournament Participants
ExternalTournamentParticipant.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
Tournament.hasMany(ExternalTournamentParticipant, { foreignKey: 'tournamentId', as: 'externalParticipants' });
ExternalTournamentParticipant.belongsTo(TournamentGroup, { 
    foreignKey: 'groupId', 
    targetKey: 'id', 
    as: 'group', 
    constraints: false 
});
TournamentGroup.hasMany(ExternalTournamentParticipant, { 
    foreignKey: 'groupId', 
    as: 'externalGroupMembers' 
});
ExternalTournamentParticipant.belongsTo(TournamentClass, { 
    foreignKey: 'classId', 
    as: 'class', 
    constraints: false 
});
TournamentClass.hasMany(ExternalTournamentParticipant, { 
    foreignKey: 'classId', 
    as: 'externalParticipants' 
});

// Tournament Pairings
TournamentPairing.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
Tournament.hasMany(TournamentPairing, { foreignKey: 'tournamentId', as: 'pairings' });
TournamentPairing.belongsTo(TournamentClass, { foreignKey: 'classId', as: 'class' });
TournamentClass.hasMany(TournamentPairing, { foreignKey: 'classId', as: 'pairings' });
TournamentPairing.belongsTo(TournamentGroup, { 
    foreignKey: 'groupId', 
    as: 'group', 
    constraints: false 
});
TournamentGroup.hasMany(TournamentPairing, { 
    foreignKey: 'groupId', 
    as: 'pairings' 
});
TournamentPairing.belongsTo(TournamentMember, { 
    foreignKey: 'member1Id', 
    as: 'member1', 
    constraints: false 
});
TournamentPairing.belongsTo(TournamentMember, { 
    foreignKey: 'member2Id', 
    as: 'member2', 
    constraints: false 
});
TournamentPairing.belongsTo(ExternalTournamentParticipant, { 
    foreignKey: 'external1Id', 
    as: 'external1', 
    constraints: false 
});
TournamentPairing.belongsTo(ExternalTournamentParticipant, { 
    foreignKey: 'external2Id', 
    as: 'external2', 
    constraints: false 
});

Accident.belongsTo(Member, { foreignKey: 'memberId', as: 'members' });
Member.hasMany(Accident, { foreignKey: 'memberId', as: 'accidents' });

Accident.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDates' });
DiaryDate.hasMany(Accident, { foreignKey: 'diaryDateId', as: 'accidents' });

User.hasOne(MyTischtennis, { foreignKey: 'userId', as: 'myTischtennis' });
MyTischtennis.belongsTo(User, { foreignKey: 'userId', as: 'user' });

User.hasMany(MyTischtennisUpdateHistory, { foreignKey: 'userId', as: 'updateHistory' });
MyTischtennisUpdateHistory.belongsTo(User, { foreignKey: 'userId', as: 'user' });

User.hasMany(MyTischtennisFetchLog, { foreignKey: 'userId', as: 'fetchLogs' });
MyTischtennisFetchLog.belongsTo(User, { foreignKey: 'userId', as: 'user' });

User.hasMany(ApiLog, { foreignKey: 'userId', as: 'apiLogs' });
ApiLog.belongsTo(User, { foreignKey: 'userId', as: 'user' });

Club.hasOne(MemberTransferConfig, { foreignKey: 'clubId', as: 'memberTransferConfig' });
MemberTransferConfig.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

Member.hasMany(MemberContact, { foreignKey: 'memberId', as: 'contacts' });
MemberContact.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });

Member.hasMany(MemberImage, { foreignKey: 'memberId', as: 'images' });
MemberImage.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });

MemberOrder.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
Member.hasMany(MemberOrder, { foreignKey: 'memberId', as: 'orders' });

MemberOrder.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Club.hasMany(MemberOrder, { foreignKey: 'clubId', as: 'memberOrders' });

MemberOrder.hasMany(MemberOrderHistory, { foreignKey: 'memberOrderId', as: 'historyEntries' });
MemberOrderHistory.belongsTo(MemberOrder, { foreignKey: 'memberOrderId', as: 'order' });

MemberOrderHistory.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
Member.hasMany(MemberOrderHistory, { foreignKey: 'memberId', as: 'orderHistoryEntries' });

MemberOrderHistory.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Club.hasMany(MemberOrderHistory, { foreignKey: 'clubId', as: 'memberOrderHistoryEntries' });

// Billing
BillingTemplate.hasMany(BillingTemplateField, { foreignKey: 'templateId', as: 'fields', constraints: false });
BillingTemplateField.belongsTo(BillingTemplate, { foreignKey: 'templateId', as: 'template', constraints: false });

BillingTemplate.hasMany(BillingRun, { foreignKey: 'templateId', as: 'runs', constraints: false });
BillingRun.belongsTo(BillingTemplate, { foreignKey: 'templateId', as: 'template', constraints: false });

BillingRun.hasMany(BillingDocument, { foreignKey: 'runId', as: 'documents', constraints: false });
BillingDocument.belongsTo(BillingRun, { foreignKey: 'runId', as: 'run', constraints: false });

BillingDocument.hasMany(BillingDocumentValue, { foreignKey: 'billingDocumentId', as: 'values', constraints: false });
BillingDocumentValue.belongsTo(BillingDocument, { foreignKey: 'billingDocumentId', as: 'document', constraints: false });

// Training Groups
Club.hasMany(TrainingGroup, { foreignKey: 'clubId', as: 'trainingGroups' });
TrainingGroup.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

Member.belongsToMany(TrainingGroup, { 
    through: MemberTrainingGroup, 
    foreignKey: 'memberId', 
    otherKey: 'trainingGroupId',
    as: 'trainingGroups'
});
TrainingGroup.belongsToMany(Member, { 
    through: MemberTrainingGroup, 
    foreignKey: 'trainingGroupId', 
    otherKey: 'memberId',
    as: 'members'
});

// Club Disabled Preset Groups
Club.hasMany(ClubDisabledPresetGroup, { foreignKey: 'clubId', as: 'disabledPresetGroups' });
ClubDisabledPresetGroup.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

// Training Times
TrainingGroup.hasMany(TrainingTime, { foreignKey: 'trainingGroupId', as: 'trainingTimes' });
TrainingTime.belongsTo(TrainingGroup, { foreignKey: 'trainingGroupId', as: 'trainingGroup' });

// Friendly shared matches
FriendlyMatchShared.belongsTo(Club, { foreignKey: 'homeClubId', as: 'homeClub' });
FriendlyMatchShared.belongsTo(Club, { foreignKey: 'guestClubId', as: 'guestClub' });
Club.hasMany(FriendlyMatchShared, { foreignKey: 'homeClubId', as: 'homeSharedFriendlyMatches' });
Club.hasMany(FriendlyMatchShared, { foreignKey: 'guestClubId', as: 'guestSharedFriendlyMatches' });

FriendlyMatchShared.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser' });
User.hasMany(FriendlyMatchShared, { foreignKey: 'createdByUserId', as: 'createdSharedFriendlyMatches' });

// Friendly invitations
FriendlyMatchInvitation.belongsTo(Club, { foreignKey: 'fromClubId', as: 'fromClub' });
FriendlyMatchInvitation.belongsTo(Club, { foreignKey: 'toClubId', as: 'toClub' });
Club.hasMany(FriendlyMatchInvitation, { foreignKey: 'fromClubId', as: 'sentFriendlyMatchInvitations' });
Club.hasMany(FriendlyMatchInvitation, { foreignKey: 'toClubId', as: 'receivedFriendlyMatchInvitations' });

FriendlyMatchInvitation.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser' });
FriendlyMatchInvitation.belongsTo(User, { foreignKey: 'acceptedByUserId', as: 'acceptedByUser' });
User.hasMany(FriendlyMatchInvitation, { foreignKey: 'createdByUserId', as: 'createdFriendlyMatchInvitations' });
User.hasMany(FriendlyMatchInvitation, { foreignKey: 'acceptedByUserId', as: 'acceptedFriendlyMatchInvitations' });

FriendlyMatchShared.belongsTo(FriendlyMatchInvitation, {
    foreignKey: 'createdFromInvitationId',
    as: 'sourceInvitation',
    constraints: false,
});
FriendlyMatchInvitation.hasOne(FriendlyMatchShared, {
    foreignKey: 'createdFromInvitationId',
    as: 'createdSharedMatch',
    constraints: false,
});

Club.hasMany(ClubVenue, { foreignKey: 'clubId', as: 'venues' });
ClubVenue.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

Club.hasMany(ClubRequest, { foreignKey: 'clubId', as: 'clubRequests' });
ClubRequest.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubRequest.hasMany(ClubRequestNote, { foreignKey: 'clubRequestId', as: 'notes' });
ClubRequestNote.belongsTo(ClubRequest, { foreignKey: 'clubRequestId', as: 'request' });
User.hasMany(ClubRequest, { foreignKey: 'assignedUserId', as: 'assignedClubRequests' });
ClubRequest.belongsTo(User, { foreignKey: 'assignedUserId', as: 'assignedUser', constraints: false });
Member.hasMany(ClubRequest, { foreignKey: 'assignedMemberId', as: 'assignedRequests' });
ClubRequest.belongsTo(Member, { foreignKey: 'assignedMemberId', as: 'assignedMember', constraints: false });
User.hasMany(ClubRequestNote, { foreignKey: 'createdByUserId', as: 'clubRequestNotes' });
ClubRequestNote.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser', constraints: false });

Club.hasMany(ClubSepaMandate, { foreignKey: 'clubId', as: 'sepaMandates' });
ClubSepaMandate.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Member.hasMany(ClubSepaMandate, { foreignKey: 'memberId', as: 'sepaMandates' });
ClubSepaMandate.belongsTo(Member, { foreignKey: 'memberId', as: 'member', constraints: false });

Club.hasMany(ClubPaymentClaim, { foreignKey: 'clubId', as: 'paymentClaims' });
ClubPaymentClaim.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Member.hasMany(ClubPaymentClaim, { foreignKey: 'memberId', as: 'paymentClaims' });
ClubPaymentClaim.belongsTo(Member, { foreignKey: 'memberId', as: 'member', constraints: false });
ClubPaymentClaim.hasMany(ClubAccountTransaction, { foreignKey: 'paymentClaimId', as: 'transactions' });
ClubAccountTransaction.belongsTo(ClubPaymentClaim, { foreignKey: 'paymentClaimId', as: 'paymentClaim', constraints: false });

Club.hasMany(ClubAccount, { foreignKey: 'clubId', as: 'accounts' });
ClubAccount.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Club.hasMany(ClubAccountTransaction, { foreignKey: 'clubId', as: 'accountTransactions' });
ClubAccountTransaction.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubAccount.hasMany(ClubAccountTransaction, { foreignKey: 'accountId', as: 'transactions' });
ClubAccountTransaction.belongsTo(ClubAccount, { foreignKey: 'accountId', as: 'account' });

Club.hasMany(ClubInvoiceParty, { foreignKey: 'clubId', as: 'invoiceParties' });
ClubInvoiceParty.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });

Club.hasMany(ClubInvoice, { foreignKey: 'clubId', as: 'invoices' });
ClubInvoice.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubInvoice.belongsTo(ClubInvoiceParty, { foreignKey: 'partyId', as: 'party', constraints: false });
ClubInvoiceParty.hasMany(ClubInvoice, { foreignKey: 'partyId', as: 'invoices' });
ClubInvoice.belongsTo(ClubAccount, { foreignKey: 'accountId', as: 'account', constraints: false });
ClubAccount.hasMany(ClubInvoice, { foreignKey: 'accountId', as: 'invoices' });
User.hasMany(ClubInvoice, { foreignKey: 'createdByUserId', as: 'createdInvoices' });
ClubInvoice.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser', constraints: false });
ClubInvoice.hasMany(ClubAccountTransaction, { foreignKey: 'invoiceId', as: 'transactions' });
ClubAccountTransaction.belongsTo(ClubInvoice, { foreignKey: 'invoiceId', as: 'invoice', constraints: false });
User.hasMany(ClubAccountTransaction, { foreignKey: 'createdByUserId', as: 'createdAccountTransactions' });
ClubAccountTransaction.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser', constraints: false });

ClubInvoice.hasMany(ClubInvoiceItem, { foreignKey: 'invoiceId', as: 'items' });
ClubInvoiceItem.belongsTo(ClubInvoice, { foreignKey: 'invoiceId', as: 'invoice' });

Club.hasMany(ClubTask, { foreignKey: 'clubId', as: 'clubTasks' });
ClubTask.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
User.hasMany(ClubTask, { foreignKey: 'createdByUserId', as: 'createdClubTasks' });
ClubTask.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser', constraints: false });
User.hasMany(ClubTask, { foreignKey: 'assignedUserId', as: 'assignedClubTasksWork' });
ClubTask.belongsTo(User, { foreignKey: 'assignedUserId', as: 'assignedUser', constraints: false });
Club.hasMany(ClubTaskSuppression, { foreignKey: 'clubId', as: 'taskSuppressions' });
ClubTaskSuppression.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
User.hasMany(ClubTaskSuppression, { foreignKey: 'dismissedByUserId', as: 'dismissedTaskSuggestions' });
ClubTaskSuppression.belongsTo(User, { foreignKey: 'dismissedByUserId', as: 'dismissedByUser', constraints: false });

Club.hasMany(ClubRole, { foreignKey: 'clubId', as: 'clubRoles' });
ClubRole.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubRole.hasMany(ClubUserRole, { foreignKey: 'clubRoleId', as: 'assignments' });
ClubUserRole.belongsTo(ClubRole, { foreignKey: 'clubRoleId', as: 'role' });
Club.hasMany(ClubUserRole, { foreignKey: 'clubId', as: 'clubUserRoles' });
ClubUserRole.belongsTo(Club, { foreignKey: 'clubId', as: 'club', constraints: false });
User.hasMany(ClubUserRole, { foreignKey: 'userId', as: 'clubRoleAssignments' });
ClubUserRole.belongsTo(User, { foreignKey: 'userId', as: 'user', constraints: false });

Club.hasMany(ClubCommunicationThread, { foreignKey: 'clubId', as: 'communicationThreads' });
ClubCommunicationThread.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
User.hasMany(ClubCommunicationThread, { foreignKey: 'createdByUserId', as: 'createdCommunicationThreads' });
ClubCommunicationThread.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser', constraints: false });
ClubCommunicationThread.belongsTo(ClubDistributionGroup, { foreignKey: 'distributionGroupId', as: 'distributionGroup', constraints: false });
ClubDistributionGroup.hasMany(ClubCommunicationThread, { foreignKey: 'distributionGroupId', as: 'threads' });
ClubCommunicationThread.belongsTo(Member, { foreignKey: 'recipientMemberId', as: 'recipientMember', constraints: false });
Member.hasMany(ClubCommunicationThread, { foreignKey: 'recipientMemberId', as: 'communicationThreads' });

Club.hasMany(ClubCommunicationMessage, { foreignKey: 'clubId', as: 'communicationMessages' });
ClubCommunicationMessage.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubCommunicationThread.hasMany(ClubCommunicationMessage, { foreignKey: 'threadId', as: 'messages' });
ClubCommunicationMessage.belongsTo(ClubCommunicationThread, { foreignKey: 'threadId', as: 'thread' });
User.hasMany(ClubCommunicationMessage, { foreignKey: 'createdByUserId', as: 'createdCommunicationMessages' });
ClubCommunicationMessage.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser', constraints: false });
Club.hasMany(ClubCommunicationTemplate, { foreignKey: 'clubId', as: 'communicationTemplates' });
ClubCommunicationTemplate.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Club.hasMany(ClubCommunicationRecipient, { foreignKey: 'clubId', as: 'communicationRecipients' });
ClubCommunicationRecipient.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubCommunicationThread.hasMany(ClubCommunicationRecipient, { foreignKey: 'threadId', as: 'recipients' });
ClubCommunicationRecipient.belongsTo(ClubCommunicationThread, { foreignKey: 'threadId', as: 'thread' });
Member.hasMany(ClubCommunicationRecipient, { foreignKey: 'memberId', as: 'communicationRecipientEntries' });
ClubCommunicationRecipient.belongsTo(Member, { foreignKey: 'memberId', as: 'member', constraints: false });
Club.hasMany(ClubCommunicationDeliveryLog, { foreignKey: 'clubId', as: 'communicationDeliveryLogs' });
ClubCommunicationDeliveryLog.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubCommunicationThread.hasMany(ClubCommunicationDeliveryLog, { foreignKey: 'threadId', as: 'deliveryLogs' });
ClubCommunicationDeliveryLog.belongsTo(ClubCommunicationThread, { foreignKey: 'threadId', as: 'thread' });
ClubCommunicationRecipient.hasMany(ClubCommunicationDeliveryLog, { foreignKey: 'recipientId', as: 'deliveryLogs' });
ClubCommunicationDeliveryLog.belongsTo(ClubCommunicationRecipient, { foreignKey: 'recipientId', as: 'recipient', constraints: false });
User.hasMany(ClubCommunicationDeliveryLog, { foreignKey: 'createdByUserId', as: 'createdCommunicationDeliveryLogs' });
ClubCommunicationDeliveryLog.belongsTo(User, { foreignKey: 'createdByUserId', as: 'createdByUser', constraints: false });

Club.hasMany(ClubDistributionGroup, { foreignKey: 'clubId', as: 'distributionGroups' });
ClubDistributionGroup.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
ClubDistributionGroup.hasMany(ClubDistributionGroupMember, { foreignKey: 'groupId', as: 'memberships' });
ClubDistributionGroupMember.belongsTo(ClubDistributionGroup, { foreignKey: 'groupId', as: 'group' });
Member.hasMany(ClubDistributionGroupMember, { foreignKey: 'memberId', as: 'distributionGroupMemberships' });
ClubDistributionGroupMember.belongsTo(Member, { foreignKey: 'memberId', as: 'member', constraints: false });

export {
    User,
    Log,
    Club,
    UserClub,
    Member,
    DiaryDate,
    Participant,
    Activity,
    DiaryNote,
    DiaryTag,
    MemberDiaryTag,
    MemberNote,
    DiaryDateTag,
    DiaryMemberNote,
    DiaryMemberTag,
    PredefinedActivity,
    DiaryMemberActivity,
    PredefinedActivityImage,
    DiaryDateActivity,
    Match,
    League,
    Team,
    ClubTeam,
    ClubTeamMember,
    TeamDocument,
    Season,
    Location,
    Group,
    GroupActivity,
    Tournament,
    TournamentGroup,
    TournamentClass,
    TournamentMember,
    TournamentMatch,
    TournamentResult,
    ExternalTournamentParticipant,
    TournamentPairing,
    TournamentStage,
    TournamentStageAdvancement,
    Accident,
    UserToken,
    OfficialTournament,
    OfficialCompetition,
    OfficialCompetitionMember,
    MyTischtennis,
    MyTischtennisUpdateHistory,
    MyTischtennisFetchLog,
    ApiLog,
    MemberTransferConfig,
    MemberContact,
    MemberImage,
    MemberOrder,
    MemberOrderHistory,
    MemberGroupPhoto,
    BillingTemplate,
    BillingTemplateField,
    BillingRun,
    BillingDocument,
    BillingDocumentValue,
    BillingUserSetting,
    ClubDocument,
    ClubDocumentVersion,
    ClubDocumentLink,
    FriendlyMatch,
    FriendlyMatchShared,
    FriendlyMatchInvitation,
    MemberTtrHistory,
    MemberPlayInterest,
    ClickTtAccount,
    CalendarEvent,
    TrainingCancellation,
    TrainingGroup,
    MemberTrainingGroup,
    ClubDisabledPresetGroup,
    TrainingTime,
    ClubVenue,
    ClubRequest,
    ClubRequestNote,
    ClubSepaMandate,
    ClubPaymentClaim,
    ClubAccount,
    ClubAccountTransaction,
    ClubInvoiceParty,
    ClubInvoice,
    ClubInvoiceItem,
    ClubTask,
    ClubTaskSuppression,
    ClubRole,
    ClubUserRole,
    ClubCommunicationThread,
    ClubCommunicationMessage,
    ClubCommunicationRecipient,
    ClubCommunicationDeliveryLog,
    ClubCommunicationTemplate,
    ClubDistributionGroup,
    ClubDistributionGroupMember,
};
