/**
 * 이벤트 컨트롤러
 * 이벤트 관련 기능을 처리하는 컨트롤러
 */
const { Event, EventParticipant, Member, Club, EventScore, ClubMember, EventTeam, EventTeamMember } = require('../models');
const { Op } = require('sequelize');
const { sequelize } = require('../models');
const averageService = require('../services/averageService');

// 이벤트 목록 조회
exports.getAllEvents = async (req, res) => {
  try {
    const { clubId } = req.body;
    
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const events = await Event.findAll({
      where: { 
        clubId,
        status: { [Op.ne]: 'deleted' }
      },
      include: [
        {
          model: Club,
          attributes: ['id', 'name']
        },
        {
          model: EventParticipant,
          attributes: ['id', 'status', 'paymentStatus'],
          where: { 
            status: { [Op.ne]: 'canceled' }
          },
          required: false,
          include: [{
            model: Member,
            attributes: ['id', 'name', 'memberType', 'gender']
          }]
        }
      ],
      order: [['startDate', 'ASC']]
    });

    const formattedEvents = events.map(event => {
      const eventData = event.toJSON();
      return {
        ...eventData,
        participantCount: eventData.participants ? eventData.participants.length : 0,
        clubName: eventData.Club ? eventData.Club.name : ''
      };
    });
    
    res.json(formattedEvents);
  } catch (error) {
    console.error('이벤트 목록 조회 오류:', error);
    res.status(500).json({ message: '이벤트 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 특정 이벤트 조회
exports.getEventById = async (req, res) => {
  try {
    const eventId = req.params.id;
    
    if (!eventId) {
      return res.status(400).json({ message: '이벤트 ID가 필요합니다.' });
    }
    
    const event = await Event.findOne({
      where: {
        id: eventId,
        status: { [Op.ne]: 'deleted' }
      },
      include: [
        {
          model: Club,
          attributes: ['id', 'name', 'location']
        },
        {
          model: EventParticipant,
          attributes: ['id', 'status', 'paymentStatus'],
          where: { status: { [Op.ne]: 'canceled' } }, 
          required: false,
          include: [
            {
              model: Member,
              attributes: ['id', 'name'] 
            }
          ]
        }
      ]
    });
    
    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    const eventData = event.toJSON();
    
    // 참가자들의 동적 에버리지 계산
    if (eventData.participants && eventData.participants.length > 0) {
      const participantsWithDynamicAverage = await Promise.all(
        eventData.participants.map(async (participant) => {
          if (participant.Member && participant.Member.id) {
            try {
              const averageData = await averageService.calculateMemberAverageByClubSetting(
                participant.Member.id, 
                eventData.clubId
              );
              
              return {
                ...participant,
                Member: {
                  ...participant.Member,
                  average: averageData.average
                }
              };
            } catch (error) {
              console.error(`회원 ${participant.Member.id}의 에버리지 계산 오류:`, error);
              return {
                ...participant,
                Member: {
                  ...participant.Member,
                  average: 0
                }
              };
            }
          }
          return participant;
        })
      );
      
      eventData.participants = participantsWithDynamicAverage;
    }
    
    const formattedEvent = {
      ...eventData,
      participantCount: eventData.participants ? eventData.participants.length : 0,
      clubName: eventData.Club ? eventData.Club.name : ''
    };

    res.json(formattedEvent);
  } catch (error) {
    console.error('이벤트 조회 오류:', error);
    res.status(500).json({ message: '이벤트 정보를 가져오는 중 오류가 발생했습니다.' });
  }
};

// 새 이벤트 생성
exports.createEvent = async (req, res) => {
  try {
    const { 
      clubId,
      title,
      description,
      startDate,
      endDate,
      location,
      maxParticipants,
      eventType,
      participantFee,
      entryFee,
      fee,
      gameCount,
      laneCount,
      status 
    } = req.body;
    
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const club = await Club.findOne({
      where: { 
        id: clubId,
        status: 'active'
      }
    });

    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }
    const endDateVal = endDate ? new Date(endDate) : null;
        // 랜덤 해시 생성 함수
    const generateRandomHash = async () => {
      const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
      let hash;
      let exists = true;
      while (exists) {
        hash = Array.from({ length: 16 }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
        // 중복 체크
        exists = await Event.findOne({ where: { publicHash: hash } });
      }
      return hash;
    };

    const publicHash = await generateRandomHash();
    const accessPassword = req.body.accessPassword || null;

    // 금액 통합: 문자열("20000.00") 또는 숫자를 허용, 0은 유효값(무료), 빈값은 null 처리
    const hasFeeField = Object.prototype.hasOwnProperty.call(req.body, 'participantFee')
      || Object.prototype.hasOwnProperty.call(req.body, 'entryFee')
      || Object.prototype.hasOwnProperty.call(req.body, 'fee');
    let feeParsed = null;
    if (hasFeeField) {
      const feeRaw = fee ?? entryFee ?? participantFee;
      if (feeRaw === undefined || feeRaw === null || `${feeRaw}`.trim() === '') {
        feeParsed = null; // 명시적 빈값 => null 저장
      } else {
        const num = parseFloat(`${feeRaw}`);
        feeParsed = Number.isFinite(num) ? num : null;
      }
    } else {
      feeParsed = null; // 생성 시 미제공이면 null 유지
    }

    const event = await Event.create({
      clubId,
      title,
      description,
      startDate: startDate ? startDate : null,
      endDate: endDateVal,
      location,
      maxParticipants: maxParticipants || 0,
      eventType: eventType || 'regular',
      participantFee: feeParsed, // allowNull=true이므로 null 저장 허용
      gameCount: gameCount || 3,
      laneCount: laneCount || 1,
      status: status || 'active',
      publicHash,
      accessPassword
    });

    const createdEvent = await Event.findOne({
      where: { id: event.id },
      include: [
        {
          model: Club,
          attributes: ['id', 'name']
        }
      ]
    });

    res.status(201).json({
      message: '이벤트가 생성되었습니다.',
      event: {
        ...createdEvent.toJSON(),
        participantCount: 0,
        clubName: createdEvent.Club ? createdEvent.Club.name : ''
      }
    });
  } catch (error) {
    console.error('이벤트 생성 오류:', error);
    res.status(500).json({ message: '이벤트 생성 중 오류가 발생했습니다.' });
  }
};

// 공개 이벤트 조회 및 비밀번호 인증
exports.getEventByPublicHash = async (req, res) => {
  const { publicHash } = req.params;
  const { password } = req.body || {};

  try {
    // 1. 이벤트 조회
    const event = await Event.findOne({
      where: { publicHash },
      include: [{
        model: Club,
        attributes: ['id', 'name']
      }]
    });
    if (!event) return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    if (event.status === 'canceled') return res.status(403).json({ message: '취소된 이벤트입니다.' });

    // 2. 비밀번호 필요 여부 및 인증
    if (event.accessPassword) {
      if (!password) return res.status(401).json({ needPassword: true, message: '비밀번호 필요' });
      if (event.accessPassword !== password) return res.status(401).json({ needPassword: true, message: '비밀번호 불일치' });
    }

    // 3. 전체 회원 명단 추출 (clubId 사용, clubId는 응답에 포함 X)
    const allMembers = await Member.findAll({
      where: { clubId: event.clubId },
      attributes: [[sequelize.col('id'), 'memberId'], 'name', 'memberType', 'gender']
    });
    
    // 전체 회원의 동적 에버리지 계산
    const allMembersWithAverage = await Promise.all(
      allMembers.map(async (member) => {
        try {
          const averageData = await averageService.calculateMemberAverageByClubSetting(
            member.dataValues.memberId, 
            event.clubId
          );
          return {
            ...member.dataValues,
            average: averageData.average
          };
        } catch (error) {
          console.error(`회원 ${member.dataValues.memberId}의 에버리지 계산 오류:`, error);
          return {
            ...member.dataValues,
            average: 0
          };
        }
      })
    );
    console.log('allMembersWithAverage', allMembersWithAverage);

    // 4. 참가자 명단 추출 (참가자 테이블 + Member 조인)
    const participants = await EventParticipant.findAll({
      where: { eventId: event.id, status: { [Op.ne]: 'canceled' } },
      include: [
        { model: Member, attributes: [[sequelize.col('id'), 'memberId'], 'name', 'memberType', 'gender'] }
      ]
    });
    
    // 참가자들의 동적 에버리지 계산
    const participantsWithAverage = await Promise.all(
      participants.map(async (participant) => {
        if (participant.Member && participant.Member.dataValues.memberId) {
          try {
            const averageData = await averageService.calculateMemberAverageByClubSetting(
              participant.Member.dataValues.memberId, 
              event.clubId
            );
            
            // 기존 객체 복사
            const participantObj = {...participant.dataValues};
            participantObj.Member = {
              ...participant.Member.dataValues,
              average: averageData.average
            };
            
            return participantObj;
          } catch (error) {
            console.error(`참가자 회원 ${participant.Member.dataValues.memberId}의 에버리지 계산 오류:`, error);
            const participantObj = {...participant.dataValues};
            participantObj.Member = {
              ...participant.Member.dataValues,
              average: 0
            };
            return participantObj;
          }
        }
        return participant.dataValues;
      })
    );
    // 5. 참가 신청 가능 명단(아직 참가하지 않은 회원)
    // '취소'가 아닌 status가 하나라도 있으면 참가자로 간주 (중복 제거)
    const participantMemberIds = [
      ...new Set(
        participantsWithAverage
          .filter(p => p.status !== '취소')
          .map(p => parseInt(p.memberId))
      )
    ];
    const availableMembers = allMembersWithAverage.filter(m => !participantMemberIds.includes(parseInt(m.memberId)));
    // 6. 팀 정보 등 추가 조회 (기존 코드 유지)
    const teams = await EventTeam.findAll({
      where: { eventId: event.id },
      order: [['teamNumber', 'ASC']],
      include: [
        {
          model: EventTeamMember,
          include: [
            {
              model: EventParticipant,
              include: [{ model: Member, attributes: [[sequelize.col('id'), 'memberId'], 'name', 'memberType', 'gender', 'handicap'] }]
            }
          ]
        }
      ]
    });

    // 점수
    const scores = await EventScore.findAll({ where: { eventId: event.id } });

    // 팀별 그룹핑
    let teamList = [];
    if (teams.length > 0) {
      // 팀 리스트 처리
      const teamsWithMembers = [];
      for (const team of teams) {
        const membersWithAverage = [];
        for (const tm of (team.EventTeamMembers || [])) {
          const participant = tm.EventParticipant;
          const member = participant?.Member;
          const scoreObj = scores.find(s => s.participantId === participant?.id);
          
          // 회원의 동적 에버리지 계산
          let dynamicAverage = 0;
          if (member && member.memberId) {
            try {
              const averageData = await averageService.calculateMemberAverageByClubSetting(
                member.memberId, 
                event.clubId
              );
              dynamicAverage = averageData.average;
            } catch (error) {
              console.error(`팀 멤버 ${member.memberId}의 에버리지 계산 오류:`, error);
            }
          }
          
          membersWithAverage.push({
            participantId: participant?.id,
            memberId: member?.memberId,
            name: member?.name || `참가자 ${participant?.id}`,
            gender: member?.gender,
            memberType: member?.memberType,
            average: dynamicAverage,
            handicap: member?.handicap || 0,
            status: participant?.status,
            paymentStatus: participant?.paymentStatus,
            comment: participant?.comment,
            isGuest: member?.memberType === '게스트',
            score: scoreObj ? scoreObj.score : null
          });
        }
        
        teamsWithMembers.push({
          teamId: team.id,
          teamNumber: team.teamNumber,
          handicap: team.handicap,
          members: membersWithAverage
        });
      }
      
      teamList = teamsWithMembers;
    }

    // 참가자 리스트(팀 없는 경우)
    let participantList = [];
    // 참가자들의 동적 에버리지 계산
    participantList = participantsWithAverage.map(p => {
      const member = p.Member;
      const scoreObj = scores.find(s => s.participantId === p.id);
      return {
        participantId: p.id,
        memberId: p.memberId,
        name: member?.name || `참가자 ${p.id}`,
        gender: member?.gender,
        memberType: member?.memberType,
        handicap: member?.handicap || 0,
        average: member?.average || 0,  // 이미 participantsWithAverage에서 동적 계산된 값
        status: p.status,
        paymentStatus: p.paymentStatus,
        comment: p.comment,
        isGuest: member?.memberType === '게스트',
        score: scoreObj ? scoreObj.score : null
      };
    });
    // 반환 데이터
    res.json({
      clubName: event.Club.name,
      event: {
        id: event.id,
        title: event.title,
        description: event.description,
        eventType: event.eventType,
        startDate: event.startDate,
        endDate: event.endDate,
        location: event.location,
        gameCount: event.gameCount,
        registrationDeadline: event.registrationDeadline,
        maxParticipants: event.maxParticipants,
        participantFee: event.participantFee,
        status: event.status
      },
      teams: teamList,
      participants: participantList,
      availableMembers,
      needPassword: !!event.accessPassword
    });
  } catch (e) {
    console.error('공개 이벤트 조회 오류:', e);
    res.status(500).json({ message: '이벤트 정보를 가져오는 중 오류가 발생했습니다.' });
  }
};

// 공개 URL(publicHash) 재생성
exports.regeneratePublicHash = async (req, res) => {
  const { id } = req.params;
  try {
    const event = await Event.findOne({ where: { id } });
    if (!event) return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    // 랜덤 해시 생성 (중복 없는 값)
    const generateRandomHash = async () => {
      const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
      let hash;
      let exists = true;
      while (exists) {
        hash = Array.from({ length: 16 }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
        exists = await Event.findOne({ where: { publicHash: hash } });
      }
      return hash;
    };
    const newHash = await generateRandomHash();
    await event.update({ publicHash: newHash });
    res.json({ publicHash: newHash });
  } catch (e) {
    console.error('공개 URL 재생성 오류:', e);
    res.status(500).json({ message: '공개 URL 재생성 중 오류가 발생했습니다.' });
  }
};

// 공개 참가자 등록/수정
exports.registerPublicParticipant = async (req, res) => {
  const { publicHash } = req.params;
  const { participantId, memberId, status, paymentStatus, comment } = req.body || {};
  try {
    const event = await Event.findOne({ where: { publicHash } });
    if (!event) return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    if (event.status === '취소') return res.status(403).json({ message: '취소된 이벤트입니다.' });
    // 기존 참가자 있는지 검사(이름+연락처 기준)
    let member = await Member.findOne({ where: { id:memberId } });
    // if (!member) {
    //   member = await Member.create({ memberId, memberType: '일반' });
    // }
    let participant = await EventParticipant.findOne({ where: { id: participantId, memberId: member.id } });
    if (!participant) {
      participant = await EventParticipant.create({ eventId: event.id, memberId: member.id, comment, status, paymentStatus });
    } else {
      await participant.update({ comment, status, paymentStatus });
    }
    res.json({ message: '참가 신청/수정이 완료되었습니다.' });
  } catch (e) {
    console.error('공개 참가자 등록 오류:', e);
    res.status(500).json({ message: '참가 신청/수정 중 오류가 발생했습니다.' });
  }
};

// 공개 게스트 추가
exports.addPublicGuest = async (req, res) => {
  const { publicHash } = req.params;
  const { name, password } = req.body || {};
  try {
    const event = await Event.findOne({ where: { publicHash } });
    if (!event) return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    if (event.status === '취소') return res.status(403).json({ message: '취소된 이벤트입니다.' });
    if (event.accessPassword) {
      if (!password || event.accessPassword !== password) return res.status(401).json({ message: '비밀번호가 올바르지 않습니다.' });
    }
    // 게스트 멤버 생성
    const member = await Member.create({ name, memberType: '게스트' });
    await EventParticipant.create({ eventId: event.id, memberId: member.id });
    res.json({ message: '게스트가 추가되었습니다.' });
  } catch (e) {
    console.error('공개 게스트 추가 오류:', e);
    res.status(500).json({ message: '게스트 추가 중 오류가 발생했습니다.' });
  }
};

// 공개 점수 수정
exports.updatePublicScore = async (req, res) => {
  const { publicHash } = req.params;
  const { participantId, score, password } = req.body || {};
  try {
    const event = await Event.findOne({ where: { publicHash } });
    if (!event) return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    if (event.status !== '준비' && event.status !== '활성') return res.status(403).json({ message: '점수 수정이 불가능한 상태입니다.' });
    if (event.accessPassword) {
      if (!password || event.accessPassword !== password) return res.status(401).json({ message: '비밀번호가 올바르지 않습니다.' });
    }
    let eventScore = await EventScore.findOne({ where: { eventId: event.id, participantId } });
    if (!eventScore) {
      eventScore = await EventScore.create({ eventId: event.id, participantId, score });
    } else {
      await eventScore.update({ score });
    }
    res.json({ message: '점수가 저장되었습니다.' });
  } catch (e) {
    console.error('공개 점수 수정 오류:', e);
    res.status(500).json({ message: '점수 저장 중 오류가 발생했습니다.' });
  }
};

// 이벤트 정보 업데이트
exports.updateEvent = async (req, res) => {
  try {
    const { 
      clubId,
      title,
      description,
      startDate,
      location,
      maxParticipants,
      eventType,
      participantFee,
      entryFee,
      fee,
      gameCount,
      laneCount,
      status,
      registrationDeadline,
      publicHash,
      accessPassword
    } = req.body;
    const eventId = req.body.id;
    let endDate = req.body.endDate;
    if (!eventId || !clubId) {
      return res.status(400).json({ message: '이벤트 ID와 클럽 ID가 필요합니다.' });
    }

    const event = await Event.findOne({
      where: {
        id: eventId,
        clubId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    if(endDate == 'Invalid Date') {
      endDate = null;
    }
    // 금액 통합: 문자열("20000.00") 또는 숫자를 허용, 0은 유효값(무료), 빈값은 null 처리
    const hasFeeField = Object.prototype.hasOwnProperty.call(req.body, 'participantFee')
      || Object.prototype.hasOwnProperty.call(req.body, 'entryFee')
      || Object.prototype.hasOwnProperty.call(req.body, 'fee');
    let feeParsed = undefined; // 업데이트에서 undefined면 필드 미변경
    if (hasFeeField) {
      const feeRaw = fee ?? entryFee ?? participantFee;
      if (feeRaw === undefined || feeRaw === null || `${feeRaw}`.trim() === '') {
        feeParsed = null; // 명시적 빈값 => null로 클리어
      } else {
        const num = parseFloat(`${feeRaw}`);
        feeParsed = Number.isFinite(num) ? num : null;
      }
    }

    const updateData = {
      title,
      description,
      startDate: startDate ? startDate : event.startDate,
      endDate: endDate || null,
      location,
      maxParticipants: maxParticipants || event.maxParticipants,
      eventType: eventType || event.eventType || 'regular',
      ...(feeParsed !== undefined ? { participantFee: feeParsed } : {}),
      gameCount: gameCount || event.gameCount,
      laneCount: laneCount || event.laneCount,
      status: status || event.status || 'active',
      registrationDeadline: registrationDeadline || event.registrationDeadline,
      publicHash: publicHash || event.publicHash,
      accessPassword: accessPassword || null
    };
    await event.update(updateData);

    const updatedEvent = await Event.findOne({
      where: { id: eventId },
      include: [
        {
          model: Club,
          attributes: ['id', 'name']
        },
        {
          model: EventParticipant,
          attributes: ['id', 'status'],
          where: { 
            status: { [Op.ne]: 'canceled' }
          },
          required: false
        }
      ]
    });

    if (!updatedEvent) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    res.json({
      message: '이벤트가 수정되었습니다.',
      event: {
        ...updatedEvent.toJSON(),
        participantCount: updatedEvent.participants ? updatedEvent.participants.length : 0,
        clubName: updatedEvent.Club ? updatedEvent.Club.name : ''
      }
    });
  } catch (error) {
    console.error('이벤트 수정 오류:', error);
    res.status(500).json({ message: '이벤트 수정 중 오류가 발생했습니다.' });
  }
};

// 이벤트 삭제 (소프트 삭제: 숨김 처리)
exports.deleteEvent = async (req, res) => {
  try {
    const eventId = req.params.id;
    const { clubId } = req.body;

    console.log(eventId, clubId, req.body, req.params);
    if (!eventId || !clubId) {
      return res.status(400).json({ message: '이벤트 ID와 클럽 ID가 필요합니다.' });
    }

    const event = await Event.findOne({
      where: {
        id: eventId,
        clubId,
        status: { [Op.ne]: 'deleted' }
      },
      include: [
        {
          model: Club,
          attributes: ['id', 'name']
        }
      ]
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    // 참가자 소프트 삭제(취소 상태로 표시)
    await EventParticipant.update(
      { status: 'canceled' },
      { 
        where: { 
          eventId,
          status: { [Op.ne]: 'canceled' }
        }
      }
    );

    // 이벤트 숨김 처리(표준 상태값 사용)
    await event.update({ status: 'deleted' });

    res.json({ 
      message: '이벤트가 숨김(소프트 삭제)되었습니다.',
      event: {
        id: event.id,
        title: event.title,
        clubId: event.clubId,
        clubName: event.Club ? event.Club.name : ''
      }
    });
  } catch (error) {
    console.error('이벤트 삭제 오류:', error);
    res.status(500).json({ message: '이벤트 삭제 중 오류가 발생했습니다.' });
  }
};

// 이벤트 완전 삭제 (하드 삭제): 팀배정, 점수, 참가자, 팀, 이벤트 순서로 물리 삭제
exports.deleteEventPermanently = async (req, res) => {
  try {
    const eventId = Number(req.params.id);
    const { clubId } = req.body || {};
    const cid = Number(clubId);

    if (!eventId || !cid) {
      return res.status(400).json({ message: '이벤트 ID와 클럽 ID가 필요합니다.' });
    }

    await sequelize.transaction(async (t) => {
      const event = await Event.findOne({ where: { id: eventId, clubId: cid }, transaction: t });
      if (!event) {
        throw new Error('이벤트를 찾을 수 없습니다.');
      }

      // 팀멤버 삭제
      const teams = await EventTeam.findAll({ where: { eventId }, transaction: t });
      const teamIds = teams.map((tm) => tm.id);
      if (teamIds.length > 0) {
        await EventTeamMember.destroy({ where: { eventTeamId: teamIds }, transaction: t });
      }

      // 점수 삭제
      await EventScore.destroy({ where: { eventId }, transaction: t });

      // 참가자 삭제
      await EventParticipant.destroy({ where: { eventId }, transaction: t });

      // 팀 삭제
      await EventTeam.destroy({ where: { eventId }, transaction: t });

      // 이벤트 삭제
      await Event.destroy({ where: { id: eventId, clubId: cid }, transaction: t });
    });

    res.json({ message: '이벤트 및 관련 데이터가 완전히 삭제되었습니다.' });
  } catch (error) {
    console.error('이벤트 완전 삭제 오류:', error);
    res.status(500).json({ message: '이벤트 완전 삭제 중 오류가 발생했습니다.' });
  }
};

// 이벤트 점수 조회
exports.getEventScores = async (req, res) => {
  try {
    const eventId = req.params.id;
    
    if (!eventId) {
      return res.status(400).json({ message: '이벤트 ID가 필요합니다.' });
    }

    // 이벤트 존재 여부 확인
    const event = await Event.findOne({
      where: { 
        id: eventId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    const scores = await EventScore.findAll({
      where: { eventId },
      include: [
        {
          model: EventParticipant,
          attributes: ['id', 'status'],
          include: [{
            model: Member,
            attributes: ['id', 'name']
          }]
        }
      ],
      order: [
        ['gameNumber', 'ASC'],
        ['score', 'DESC']
      ]
    });

    return res.status(200).json(scores);
  } catch (error) {
    console.error('점수 조회 오류:', error);
    res.status(500).json({ message: '점수 조회 중 오류가 발생했습니다.' });
  }
};

// 점수 등록
exports.addEventScore = async (req, res) => {
  try {
    const eventId = req.params.id;
    const { 
      participantId,
      gameNumber,
      score,
      handicap = 0
    } = req.body;
    
    if (!eventId || !participantId || !gameNumber || score === undefined) {
      return res.status(400).json({ 
        message: '이벤트 ID, 참가자 ID, 게임 번호, 점수가 필요합니다.' 
      });
    }

    // 이벤트 존재 여부 확인
    const event = await Event.findOne({
      where: {
        id: eventId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    // 참가자 확인
    const participant = await EventParticipant.findOne({
      where: {
        id: participantId,
        eventId,
        status: { [Op.ne]: 'canceled' }
      }
    });

    if (!participant) {
      return res.status(400).json({ message: '이벤트 참가자가 아닙니다.' });
    }

    // 게임 번호 유효성 검사
    if (gameNumber < 1 || gameNumber > event.gameCount) {
      return res.status(400).json({ 
        message: `게임 번호는 1부터 ${event.gameCount}까지만 입력 가능합니다.` 
      });
    }

    // 점수 유효성 검사
    if (score < 0 || score > 300) {
      return res.status(400).json({ 
        message: '점수는 0에서 300 사이여야 합니다.' 
      });
    }

    // 동일한 게임의 점수가 이미 있는지 확인
    const existingScore = await EventScore.findOne({
      where: {
        eventId,
        participantId,
        gameNumber
      }
    });

    if (existingScore) {
      return res.status(400).json({ 
        message: '해당 게임의 점수가 이미 등록되어 있습니다.' 
      });
    }

    // 점수 등록
    const totalScore = score + handicap;
    const newScore = await EventScore.create({
      eventId,
      participantId,
      gameNumber,
      score,
      handicap,
      totalScore
    });

    // 참가자 평균 점수 업데이트
    const allScores = await EventScore.findAll({
      where: {
        eventId,
        participantId
      }
    });

    const totalGames = allScores.length;
    const averageScore = Math.round(allScores.reduce((sum, s) => sum + s.score, 0) / totalGames);

    await participant.update({
      games: totalGames,
      average: averageScore
    });

    // 점수 등록 후 에버리지 캐시 무효화
    await averageService.invalidateMemberAverageCache(participant.memberId);
    
    res.status(201).json({
      message: '점수가 등록되었습니다.',
      score: {
        id: newScore.id,
        eventId: newScore.eventId,
        participantId: newScore.participantId,
        gameNumber: newScore.gameNumber,
        score: newScore.score,
        handicap: newScore.handicap,
        totalScore: newScore.totalScore,
        createdAt: newScore.createdAt
      }
    });
  } catch (error) {
    console.error('점수 등록 오류:', error);
    res.status(500).json({ message: '점수 등록 중 오류가 발생했습니다.' });
  }
};

// 점수 수정
exports.updateEventScore = async (req, res) => {
  try {
    const eventId = Number(req.params.id);
    const scoreId = Number(req.params.scoreId);
    const { 
      gameNumber,
      score,
      handicap = 0
    } = req.body;


    if (!eventId || !scoreId || !gameNumber || score === undefined || score === null) {
      return res.status(400).json({ 
        message: '이벤트 ID, 점수 ID, 게임 번호, 점수가 필요합니다.',
        received: { eventId, scoreId, gameNumber, score }
      });
    }

    // 점수 레코드 확인
    const scoreRecord = await EventScore.findOne({
      where: {
        id: scoreId,
        eventId
      }
    });

    // 점수 레코드가 없으면 참가자 ID를 가져와서 새로 생성
    if (!scoreRecord) {
      // 기존 점수에서 참가자 ID 가져오기
      const existingScore = await EventScore.findOne({
        where: { eventId },
        order: [['createdAt', 'DESC']]
      });

      if (!existingScore) {
        return res.status(404).json({ 
          message: '참가자 정보를 찾을 수 없습니다.' 
        });
      }

      // 새로운 게임 점수 생성
      const newScore = await EventScore.create({
        eventId,
        participantId: existingScore.participantId,
        gameNumber,
        score,
        handicap,
        totalScore: score + handicap
      });

      return res.json({
        message: '새로운 게임 점수가 등록되었습니다.',
        score: newScore
      });
    }

    // 기존 레코드 업데이트
    await scoreRecord.update({
      gameNumber,
      score,
      handicap,
      totalScore: score + handicap
    });

    // 캐시 무효화: participantId -> memberId로 변환 후 무효화 및 워밍업
    try {
      const ep = await EventParticipant.findOne({
        where: { id: scoreRecord.participantId },
        attributes: ['memberId'],
      });
      if (ep && ep.memberId) {
        await averageService.invalidateMemberAverageCache(ep.memberId);
        // clubId 조회 후 워밍업
        try {
          const ev = await Event.findOne({ where: { id: eventId }, attributes: ['clubId'] });
          if (ev && ev.clubId) {
            await averageService.calculateMemberAverageByClubSetting(ep.memberId, ev.clubId);
          }
        } catch (e2) {
          console.error('에버리지 워밍업 실패(updateEventScore):', e2);
        }
      }
    } catch (e) {
      console.error('에버리지 캐시 무효화 실패(updateEventScore):', e);
    }

    // 업데이트된 레코드 조회
    const updatedScore = await EventScore.findOne({
      where: {
        id: scoreId,
        eventId
      }
    });

    res.json({
      message: '점수가 수정되었습니다.',
      score: updatedScore
    });

  } catch (error) {
    console.error('점수 수정 오류:', error, JSON.stringify(error, Object.getOwnPropertyNames(error)));
    res.status(500).json({ 
      message: '점수 수정 중 오류가 발생했습니다.',
      error: error.message || error.toString() || error
    });
  }
};

// 점수 삭제
exports.deleteEventScore = async (req, res) => {
  try {
    const { eventId, clubId, scoreId } = req.body;
    
    if (!eventId || !clubId || !scoreId) {
      return res.status(400).json({ 
        message: '이벤트 ID, 클럽 ID, 점수 ID가 필요합니다.' 
      });
    }

    // 이벤트 존재 여부 확인
    const event = await Event.findOne({
      where: {
        id: eventId,
        clubId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    // 점수 존재 여부 확인
    const score = await EventScore.findOne({
      where: { 
        id: scoreId,
        eventId
      },
      include: [
        {
          model: EventParticipant,
          attributes: ['id', 'status'],
          include: [{
            model: Member,
            attributes: ['id', 'name']
          }]
        }
      ]
    });

    if (!score) {
      return res.status(404).json({ message: '점수를 찾을 수 없습니다.' });
    }

    await score.destroy();

    // 점수 삭제 시 해당 회원의 에버리지 캐시 무효화 및 워밍업
    try {
      const memberId = score.EventParticipant?.Member?.id;
      if (memberId) {
        await averageService.invalidateMemberAverageCache(memberId);
        console.log(`회원 ${memberId}의 에버리지 캐시 무효화 완료`);
        // clubId는 상단 검증 단계의 req.body에서 확보됨
        if (clubId) {
          try {
            await averageService.calculateMemberAverageByClubSetting(memberId, clubId);
          } catch (e2) {
            console.error('에버리지 워밍업 실패(deleteEventScore):', e2);
          }
        }
      }
    } catch (error) {
      console.error('에버리지 캐시 무효화 오류(deleteEventScore):', error);
    }

    res.json({
      message: '점수가 삭제되었습니다.',
      score: {
        id: score.id,
        userId: score.userId,
        userName: score.participant.Member ? score.participant.Member.name : '알 수 없음',
        gameNumber: score.gameNumber,
        frameNumber: score.frameNumber
      }
    });
  } catch (error) {
    console.error('점수 삭제 오류:', error);
    res.status(500).json({ message: '점수 삭제 중 오류가 발생했습니다.' });
  }
};

// 참가자의 모든 점수 삭제
exports.deleteParticipantScores = async (req, res) => {
  try {
    const eventId = Number(req.params.id);
    const participantId = Number(req.params.participantId);

    if (!eventId || !participantId) {
      return res.status(400).json({
        message: '이벤트 ID와 참가자 ID가 필요합니다.'
      });
    }

    // 삭제 전 memberId 조회 (캐시 무효화용)
    const ep = await EventParticipant.findOne({
      where: { id: participantId },
      attributes: ['memberId']
    });

    // 점수 삭제
    await EventScore.destroy({
      where: {
        eventId,
        participantId
      }
    });

    // 캐시 무효화: 해당 참가자의 회원 평균 캐시 제거 및 워밍업
    try {
      if (ep && ep.memberId) {
        await averageService.invalidateMemberAverageCache(ep.memberId);
        try {
          const ev = await Event.findOne({ where: { id: eventId }, attributes: ['clubId'] });
          if (ev && ev.clubId) {
            await averageService.calculateMemberAverageByClubSetting(ep.memberId, ev.clubId);
          }
        } catch (e2) {
          console.error('에버리지 워밍업 오류(deleteParticipantScores):', e2);
        }
      }
    } catch (e) {
      console.error('에버리지 캐시 무효화 오류(deleteParticipantScores):', e);
    }

    res.json({
      message: '점수가 삭제되었습니다.'
    });
  } catch (error) {
    console.error('점수 삭제 오류:', error);
    res.status(500).json({
      message: '점수 삭제 중 오류가 발생했습니다.'
    });
  }
};

// 이벤트 통계 조회
exports.getEventStats = async (req, res) => {
  try {
    const eventId = parseInt(req.params.id);
    const { clubId } = req.query;
    
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const stats = await EventScore.findAll({
      where: { eventId },
      attributes: [
        'userId',
        [sequelize.fn('AVG', sequelize.col('score')), 'averageScore'],
        [sequelize.fn('MAX', sequelize.col('score')), 'highScore'],
        [sequelize.fn('COUNT', sequelize.literal('CASE WHEN "isStrike" = true THEN 1 END')), 'strikeCount'],
        [sequelize.fn('COUNT', sequelize.literal('CASE WHEN "isSpare" = true THEN 1 END')), 'spareCount']
      ],
      include: [{
        model: EventParticipant,
        attributes: [],
        include: [{
          model: Member,
          attributes: ['name']
        }]
      }],
      group: ['userId', 'participant.id', 'participant.Member.id', 'participant.Member.name']
    });

    res.json(stats);
  } catch (error) {
    console.error('통계 조회 오류:', error);
    res.status(500).json({ message: '통계 조회 중 오류가 발생했습니다.' });
  }
};

// 캘린더용 이벤트 조회
exports.getCalendarEvents = async (req, res) => {
  try {
    const { clubId } = req.query;
    const { start, end } = req.query;
    
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const where = {
      clubId,
      status: { [Op.ne]: 'deleted' }
    };

    if (start && end) {
      where.startDate = {
        [Op.between]: [new Date(start), new Date(end)]
      };
    }

    const events = await Event.findAll({
      where,
      attributes: [
        'id',
        'title',
        'description',
        'startDate',
        'endDate',
        'location',
        'eventType',
        'status'
      ],
      order: [['startDate', 'ASC']]
    });

    const calendarEvents = events.map(event => ({
      id: event.id,
      title: event.title,
      start: event.startDate,
      end: event.endDate,
      description: event.description,
      location: event.location,
      eventType: event.eventType,
      status: event.status
    }));

    res.json(calendarEvents);
  } catch (error) {
    console.error('캘린더 이벤트 조회 오류:', error);
    res.status(500).json({ message: '캘린더 이벤트 조회 중 오류가 발생했습니다.' });
  }
};

// 이벤트 참가 신청
exports.registerForEvent = async (req, res) => {
  try {
    const eventId = parseInt(req.params.id);
    const { clubId } = req.query;
    const { userId, teamNumber } = req.body;
    
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const event = await Event.findOne({
      where: {
        id: eventId,
        clubId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    // 이미 등록된 참가자인지 확인
    const existingParticipant = await EventParticipant.findOne({
      where: {
        eventId,
        userId,
        status: { [Op.ne]: 'canceled' }
      }
    });

    if (existingParticipant) {
      return res.status(400).json({ message: '이미 등록된 참가자입니다.' });
    }

    const participant = await EventParticipant.create({
      eventId,
      userId,
      teamNumber,
      status: 'registered',
      registeredAt: new Date()
    });

    res.status(201).json(participant);
  } catch (error) {
    console.error('참가 신청 오류:', error);
    res.status(500).json({ message: '참가 신청 중 오류가 발생했습니다.' });
  }
};

// 참가자 제거
exports.removeParticipant = async (req, res) => {
  try {
    const { id: eventId, userId } = req.params;
    const { clubId } = req.query;
    
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const participant = await EventParticipant.findOne({
      where: {
        eventId,
        userId,
        status: { [Op.ne]: 'canceled' }
      },
      include: [{
        model: Event,
        where: {
          clubId,
          status: { [Op.ne]: 'deleted' }
        }
      }]
    });

    if (!participant) {
      return res.status(404).json({ message: '참가자를 찾을 수 없습니다.' });
    }

    await participant.update({ status: '취소' });
    res.json({ message: '참가자가 제거되었습니다.' });
  } catch (error) {
    console.error('참가자 제거 오류:', error);
    res.status(500).json({ message: '참가자 제거 중 오류가 발생했습니다.' });
  }
};

// 참가자 상태 업데이트
exports.updateParticipantStatus = async (req, res) => {
  try {
    const { id: eventId, userId } = req.params;
    const { clubId } = req.query;
    const { status, attendance, paymentStatus, paymentAmount } = req.body;
    
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const participant = await EventParticipant.findOne({
      where: {
        eventId,
        userId,
        status: { [Op.ne]: 'canceled' }
      },
      include: [{
        model: Event,
        where: {
          clubId,
          status: { [Op.ne]: 'deleted' }
        }
      }]
    });

    if (!participant) {
      return res.status(404).json({ message: '참가자를 찾을 수 없습니다.' });
    }

    await participant.update({
      status,
      attendance,
      paymentStatus,
      paymentAmount
    });

    res.json(participant);
  } catch (error) {
    console.error('참가자 상태 업데이트 오류:', error);
    res.status(500).json({ message: '참가자 상태 업데이트 중 오류가 발생했습니다.' });
  }
};

// 클럽별 이벤트 조회
exports.getEventsByClub = async (req, res) => {
  try {
    const clubId = parseInt(req.params.clubId);
    
    const events = await Event.findAll({
      where: {
        clubId,
        status: 'active'
      },
      order: [['startDate', 'ASC']]
    });
    
    res.json(events);
  } catch (error) {
    console.error('클럽별 이벤트 조회 오류:', error);
    res.status(500).json({ message: '클럽별 이벤트 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 사용자별 참가 이벤트 조회
exports.getUserEvents = async (req, res) => {
  try {
    const userId = req.user.id;
    
    const events = await Event.findAll({
      include: [
        {
          model: EventParticipant,
          where: { userId },
          attributes: []
        },
        {
          model: Club,
          attributes: ['id', 'name']
        }
      ],
      order: [['startDate', 'ASC']]
    });
    
    res.json(events);
  } catch (error) {
    console.error('사용자별 이벤트 조회 오류:', error);
    res.status(500).json({ message: '사용자별 이벤트 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 이벤트 참가자 목록 조회
exports.getEventParticipants = async (req, res) => {
  try {
    const { eventId, clubId } = req.body;
    
    if (!eventId || !clubId) {
      return res.status(400).json({ message: '이벤트 ID와 클럽 ID가 필요합니다.' });
    }

    // 이벤트 존재 여부 확인
    const event = await Event.findOne({
      where: {
        id: eventId,
        clubId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    const participants = await EventParticipant.findAll({
      where: {
        eventId,
        status: { [Op.ne]: 'canceled' }
      },
      include: [
        {
          model: Member,
          attributes: ['id', 'name', 'email', 'phone', 'memberType', 'gender', 'handicap']
        }
      ],
      order: [
        ['createdAt', 'ASC']
      ]
    });

    // 참가자들의 동적 에버리지 계산
    const participantsWithAverage = await Promise.all(
      participants.map(async (participant) => {
        const participantData = participant.toJSON();
        if (participantData.Member && participantData.Member.id) {
          try {
            const averageData = await averageService.calculateMemberAverageByClubSetting(
              participantData.Member.id, 
              clubId
            );
            
            return {
              ...participantData,
              Member: {
                ...participantData.Member,
                average: averageData.average
              }
            };
          } catch (error) {
            console.error(`회원 ${participantData.Member.id}의 에버리지 계산 오류:`, error);
            return {
              ...participantData,
              Member: {
                ...participantData.Member,
                average: 0
              }
            };
          }
        }
        return participantData;
      })
    );

    res.json({
      message: '참가자 목록 조회가 완료되었습니다.',
      participants: participantsWithAverage
    });
  } catch (error) {
    console.error('참가자 목록 조회 오류:', error);
    res.status(500).json({ message: '참가자 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 참가자 정보 핵심 update 함수 (중복 제거)
async function updateEventParticipantCore({ id, eventId, memberId, clubId, status, paymentStatus, comment }) {
  const [updatedCount] = await EventParticipant.update(
    { status, paymentStatus, comment },
    {
      where: {
        id,
        eventId,
        memberId
      }
    }
  );
  return updatedCount;
}

// 이벤트 참가자 등록 (이미 있으면 update, 없으면 create)
exports.addEventParticipant = async (req, res) => {
  try {
    const { 
      clubId,
      memberId,
      status,
      paymentStatus,
      comment
    } = req.body;
    const eventId = req.params.id;
    if (!eventId || !clubId || !memberId) {
      return res.status(400).json({ 
        message: '이벤트 ID, 클럽 ID, 사용자 ID가 필요합니다.' 
      });
    }

    // 이벤트 존재 여부 확인
    const event = await Event.findOne({
      where: {
        id: eventId,
        clubId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    // 클럽 회원 확인
    const member = await Member.findOne({
      where: {
        id: memberId,
        clubId,
        status: 'active'
      }
    });

    if (!member) {
      return res.status(400).json({ message: '클럽 회원이 아닙니다.' });
    }

    // 이미 참가 신청했는지 확인
    const existingParticipant = await EventParticipant.findOne({
      where: {
        eventId,
        memberId,
        status: { [Op.ne]: 'canceled' }
      }
    });

    // 입력 상태/결제값을 DB Enum에 맞추어 정규화
    const normalizeStatus = (s) => {
      if (!s) return undefined;
      const map = {
        '참가예정': 'pending',
        '참가확정': 'confirmed',
        '취소': 'canceled',
      };
      return ['pending', 'confirmed', 'canceled'].includes(s) ? s : (map[s] || undefined);
    };
    const normalizePayment = (p) => {
      if (!p) return undefined;
      const map = {
        '미납': 'unpaid',
        '납부완료': 'paid',
        '완납': 'paid',
      };
      return ['unpaid', 'paid'].includes(p) ? p : (map[p] || undefined);
    };

    const normStatus = normalizeStatus(status);
    const normPayment = normalizePayment(paymentStatus);

    let participant;
    let isUpdate = false;
    if (existingParticipant) {
      // 이미 있으면 update (핵심 update 함수 활용)
      await updateEventParticipantCore({
        id: existingParticipant.id,
        eventId,
        memberId,
        clubId,
        status: normStatus || existingParticipant.status,
        paymentStatus: normPayment || existingParticipant.paymentStatus,
        comment: comment || existingParticipant.comment
      });
      participant = await EventParticipant.findOne({
        where: { id: existingParticipant.id },
        include: [
          {
            model: Member,
            attributes: ['id', 'name']
          }
        ]
      });
      isUpdate = true;
    } else {
      // 없으면 create
      participant = await EventParticipant.create({
        eventId,
        memberId,
        status: normStatus || 'pending',
        paymentStatus: normPayment || 'unpaid',
        comment: comment || null,
        createdAt: new Date(),
        updatedAt: new Date()
      });
      participant = await EventParticipant.findOne({
        where: { id: participant.id },
        include: [
          {
            model: Member,
            attributes: ['id', 'name']
          }
        ]
      });
    }

    res.status(201).json({
      message: isUpdate ? '기존 참가자 정보를 수정했습니다.' : '참가자가 등록되었습니다.',
      participant
    });
  } catch (error) {
    console.error('참가자 등록/수정 오류:', error);
    res.status(500).json({ message: '참가자 등록/수정 중 오류가 발생했습니다.' });
  }
};

// 참가자 정보 수정
exports.updateEventParticipant = async (req, res) => {
  try {
    const eventId = req.params.id;
    const { id, clubId, memberId, status, paymentStatus, comment } = req.body;

    if (!eventId || !clubId || !memberId || !id) {
      return res.status(400).json({ message: '이벤트 ID, 클럽 ID, 사용자 ID가 필요합니다.' });
    }

    // 이벤트 존재 여부 확인
    const event = await Event.findOne({
      where: {
        id: eventId,
        clubId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    // 참가자 정보 수정
    const [updatedCount] = await EventParticipant.update(
      { status, paymentStatus, comment },
      {
        where: {
          id,
          eventId,
          memberId
        }
      }
    );

    if (updatedCount === 0) {
      return res.status(404).json({ message: '수정할 참가자 정보를 찾을 수 없습니다.' });
    }

    // 수정된 참가자 정보 조회
    const updatedParticipant = await EventParticipant.findOne({
      where: { id },
      include: [
        {
          model: Member,
          attributes: ['id', 'name', 'email', 'phone', 'memberType']
        }
      ]
    });

    res.json({
      message: '참가자 정보가 수정되었습니다.',
      participant: {
        ...updatedParticipant.toJSON(),
        userName: updatedParticipant.Member ? updatedParticipant.Member.name : '알 수 없음',
        userEmail: updatedParticipant.Member ? updatedParticipant.Member.email : '',
        userPhone: updatedParticipant.Member ? updatedParticipant.Member.phone : '',
        userType: updatedParticipant.Member ? updatedParticipant.Member.memberType : ''
      }
    });
  } catch (error) {
    console.error('참가자 정보 수정 오류:', error);
    res.status(500).json({ message: '참가자 정보 수정 중 오류가 발생했습니다.' });
  }
};

// [팀 생성 기능] 이벤트별 팀 목록 조회
exports.getEventTeams = async (req, res) => {
  try {
    const eventId = req.params.id;
    if (!eventId) {
      return res.status(400).json({ message: '이벤트 ID가 필요합니다.' });
    }
    const teams = await EventTeam.findAll({
      where: { eventId },
      include: [
        {
          model: EventTeamMember,
          include: [
            {
              model: EventParticipant,
              include: [{ model: Member }]
            }
          ]
        }
      ],
      order: [['teamNumber', 'ASC']]
    });
    const result = teams.map(team => ({
      id: team.id,
      teamNumber: team.teamNumber,
      handicap: team.handicap,
      members: (team.EventTeamMembers || [])
        .sort((a, b) => a.order - b.order)
        .map(tm => ({
          id: tm.eventParticipantId,
          name: tm.EventParticipant?.Member?.name || `참가자 ${tm.eventParticipantId}`,
          order: tm.order
        }))
    }));
    res.json({ teams: result });
  } catch (error) {
    console.error('팀 목록 조회 오류:', error);
    res.status(500).json({ message: '팀 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// [팀 생성 기능] 이벤트별 팀 배정 저장
exports.createOrUpdateEventTeams = async (req, res) => {
  const eventId = req.params.id;
  const { teams } = req.body; // [{teamNumber, handicap, members:[id]}]

  if (!eventId || !Array.isArray(teams)) {
    return res.status(400).json({ message: '이벤트 ID와 팀 정보가 필요합니다.' });
  }

  try {
    await sequelize.transaction(async (t) => {
      // 기존 팀 및 팀멤버 데이터 삭제
      await EventTeam.destroy({ where: { eventId }, transaction: t });
      await EventTeamMember.destroy({
        where: {}, // eventId로만 삭제하려면, eventTeamId로 팀 id 목록을 먼저 조회해서 삭제
        transaction: t
      });

      // 새 팀 및 팀멤버 데이터 저장
      for (const team of teams) {
        // 팀 생성
        const createdTeam = await EventTeam.create({
          eventId,
          teamNumber: team.teamNumber,
          handicap: team.handicap || 0
        }, { transaction: t });

        // 팀 멤버(순서 포함) 저장
        if (Array.isArray(team.members) && team.members.length > 0) {
          const teamMemberRows = team.members
            .filter(m => m.id != null)
            .map(m => ({
              eventTeamId: createdTeam.id,
              eventParticipantId: m.id,
              order: m.order ?? 1
            }));
          if (teamMemberRows.length > 0) {
            await EventTeamMember.bulkCreate(teamMemberRows, { transaction: t });
          }
        }
      }
    });
    res.json({ message: '팀 배정이 저장되었습니다.' });
  } catch (error) {
    console.error('팀 배정 저장 오류:', error);
    res.status(500).json({ message: '팀 배정 저장 중 오류가 발생했습니다.' });
  }
};

// 참가자 삭제 (소프트 삭제)
exports.deleteEventParticipant = async (req, res) => {
  try {
    const eventId = req.params.id;
    const { id } = req.body;
    
    if (!eventId || !id) {
      return res.status(400).json({ 
        message: '이벤트 ID, 참가자 ID가 필요합니다.' 
      });
    }

    // 이벤트 존재 여부 확인
    const event = await Event.findOne({
      where: {
        id: eventId,
        status: { [Op.ne]: 'deleted' }
      }
    });

    if (!event) {
      return res.status(404).json({ message: '이벤트를 찾을 수 없습니다.' });
    }

    // 참가자 존재 여부 확인
    const participant = await EventParticipant.findOne({
      where: {
        eventId,
        id,
        status: { [Op.ne]: 'canceled' }
      },
      include: [
        {
          model: Member,
          attributes: ['id', 'name', 'memberType']
        }
      ]
    });

    if (!participant) {
      return res.status(404).json({ message: '참가자를 찾을 수 없습니다.' });
    }

    // 참가자의 점수도 함께 삭제
    await EventScore.destroy({
      where: {
        eventId,
        participantId: id
      }
    });

    await participant.update({ status: '취소' });

    res.json({
      message: '참가자가 삭제되었습니다.',
      participant: {
        id: participant.id
      }
    });
  } catch (error) {
    console.error('참가자 삭제 오류:', error);
    res.status(500).json({ message: '참가자 삭제 중 오류가 발생했습니다.' });
  }
};
