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

// 관리자 권한 체크 함수
const isAdmin = (user) => {
  return user && (user.role === 'admin' || user.role === 'superadmin');
};

// 클럽 선택
const allowedMemberTypes = ['owner', 'manager'];

exports.selectClub = async (req, res) => {
  try {
    const { clubId } = req.body;
    const userId = req.user && req.user.id;

    // 클럽 존재 여부 확인
    const club = await Club.findByPk(clubId);
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }

    // 관리자 여부 체크
    const isAdmin = req.user && (req.user.role === 'admin' || req.user.role === 'superadmin');
    let isClubManager = false;

    if (!isAdmin) {
      // Members 테이블에서 모임장/운영진 여부 확인
      const member = await Member.findOne({
        where: {
          clubId,
          userId,
          memberType: ['owner', 'manager']
        }
      });
      isClubManager = !!member;
    }

    if (!isAdmin && !isClubManager) {
      return res.status(403).json({ message: '해당 클럽에 대한 권한이 없습니다.' });
    }

    req.session.clubId = clubId;
    // console.log(`Session clubId: ${clubId}`);
    res.status(200).json({ message: '클럽을 선택했습니다.' });
  } catch (error) {
    console.error('클럽 선택 오류:', error);
    res.status(500).json({ message: '클럽을 선택하는 중 오류가 발생했습니다.' });
  }
};

// 모든 클럽 조회
exports.getAllClubs = async (req, res) => {
  try {
    const clubs = await Club.findAll({
      where: { status: 'active' },
      include: [
        {
          model: Member,
          where: { memberType: 'owner' },
          required: false,
          attributes: ['id', 'name', 'email', 'phone', 'memberType']
        }
      ],
      order: [['createdAt', 'DESC']]
    });
    
    const formattedClubs = clubs.map(club => {
      const clubData = club.toJSON();
      // 모임장 정보 추가
      const ownerMember = clubData.Members && clubData.Members.length > 0 ? clubData.Members[0] : null;
      
      return {
        ...clubData,
        ownerName: ownerMember ? ownerMember.name : '알 수 없음',
        ownerEmail: ownerMember ? ownerMember.email : '',
        ownerPhone: ownerMember ? ownerMember.phone : '',
        ownerMemberType: ownerMember ? ownerMember.memberType : ''
      };
    });
    
    res.json(formattedClubs);
  } catch (error) {
    console.error('클럽 목록 조회 오류:', error);
    res.status(500).json({ message: '클럽 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 특정 클럽 조회
exports.getClubById = async (req, res) => {
  try {
    const { clubId } = req.body;
    // console.log(`clubId: ${clubId}`);
    if (!clubId) {
      return res.status(400).json({ message: "유효하지 않은 클럽 ID입니다." });
    }

    const club = await Club.findByPk(clubId);
    // console.log(`club: ${club}`);
    if (club) {
      // 클럽 소유자 정보 조회
      const owner = await Member.findOne({where: {userId: club.ownerId}}, {
        attributes: ['name', 'email', 'memberType']
      });

      const clubData = club.toJSON();      
      const formattedClub = {
        ...clubData,
        ownerEmail: owner ? owner.email : '',
        ownerName: owner ? owner.name : '',
        ownerMemberType: owner ? owner.memberType : ''
      };

      res.json(formattedClub);
    } else {
      res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }
  } catch (error) {
    console.error('클럽 조회 오류:', error);
    res.status(500).json({ message: '클럽 정보를 가져오는 중 오류가 발생했습니다.' });
  }
};

// 새 클럽 생성
exports.createClub = async (req, res) => {
  try {
    const { name, location, description, averageCalculationPeriod } = req.body;
    
    // 필수 필드 검증
    if (!name) {
      return res.status(400).json({ message: '클럽 이름은 필수 항목입니다.' });
    }
    
    // 이메일로 사용자 조회
    const owner = await User.findOne({ where: { id: req.user.id } });
    
    if (!owner) {
      return res.status(404).json({ message: '해당 사용자를 찾을 수 없습니다.' });
    }
    
    // 클럽 생성
    const newClub = await Club.create({
      name,
      location,
      description,
      averageCalculationPeriod,
      ownerId: owner.id,
      memberCount: 1, // 모임장 포함
      status: 'active'
    });
    
    // 클럽 모임장을 클럽 멤버로 추가
    await Member.create({
      name: owner.name,
      gender: 'male',
      userId: owner.id,
      clubId: newClub.id,
      memberType: 'owner',
      joinDate: new Date(),
      status: 'active'
    });
    
    // 베이직 1개월 플랜 자동 추가
    try {
      // 베이직 플랜 조회 (ID가 1이라고 가정, 실제 환경에 맞게 조정 필요)
      const basicPlan = await require('../models').SubscriptionPlan.findOne({
        where: { name: 'Basic' }
      });
      
      if (basicPlan) {
        const startDate = new Date();
        const endDate = new Date();
        endDate.setFullYear(endDate.getFullYear() + 1); // 1년 추가
        
        await require('../models').ClubSubscription.create({
          clubId: newClub.id,
          planId: basicPlan.id,
          startDate,
          endDate,
          status: 'active',
          price: basicPlan.price || 0
        });
        
        console.log(`클럽 ${newClub.id}에 베이직 1개월 플랜 자동 추가됨`);
      } else {
        console.warn('베이직 플랜을 찾을 수 없어 자동 구독이 추가되지 않았습니다.');
      }
    } catch (subscriptionError) {
      console.error('자동 구독 추가 오류:', subscriptionError);
      // 구독 추가 실패해도 클럽 생성은 성공으로 처리
    }
    
    res.status(201).json(newClub);
  } catch (error) {
    console.error('클럽 생성 오류:', error);
    res.status(500).json({ message: '클럽을 생성하는 중 오류가 발생했습니다.' });
  }
};

// 클럽 정보 업데이트
exports.updateClub = async (req, res) => {
  try {
    const { clubId, name, location, description, contact, ownerEmail, status, femaleHandicap, ownerId, averageCalculationPeriod } = req.body;
    const club = await Club.findByPk(clubId);
    
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }
    
    // 모임장 변경 확인 (직접 ownerId를 전달받거나 이메일로 변경)
    let newOwnerId = club.ownerId;
    let ownerChanged = false;
    
    // ownerId가 직접 전달된 경우 (클럽 설정에서 모임장 선택)
    if (ownerId && ownerId !== club.ownerId) {
      newOwnerId = ownerId;
      ownerChanged = true;
    }
    
    // 클럽 정보 업데이트
    await club.update({
      name: name || club.name,
      location: location || club.location,
      description: description !== undefined ? description : club.description,
      contact: contact !== undefined ? contact : club.contact,
      status: status || club.status,
      femaleHandicap: femaleHandicap || club.femaleHandicap,
      averageCalculationPeriod: averageCalculationPeriod || club.averageCalculationPeriod,
      ownerId: newOwnerId
    });
    
    // 모임장이 변경된 경우 모임장 변경 메소드 호출
    if (ownerChanged) {
      try {
        // 모임장 변경 내부 메소드 호출
        await changeClubOwnerInternal(clubId, newOwnerId, ownerEmail);
      } catch (error) {
        throw error;
      }
    }
    
    res.json(club);
  } catch (error) {
    console.error('클럽 정보 업데이트 오류:', error);
    res.status(500).json({ message: '클럽 정보를 업데이트하는 중 오류가 발생했습니다.' });
  }
};

// 클럽 삭제
exports.deleteClub = async (req, res) => {
  try {
    const { clubId } = req.body;
    
    // 클럽 존재 여부 확인
    const club = await Club.findByPk(clubId);
    
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }
    
    // 소프트 삭제 (상태만 변경)
    await club.update({ status: 'inactive' });
    
    res.status(204).send();
  } catch (error) {
    console.error('클럽 삭제 오류:', error);
    res.status(500).json({ message: '클럽을 삭제하는 중 오류가 발생했습니다.' });
  }
};

// 클럽 기능 관리
exports.manageClubFeatures = async (req, res) => {
  try {
    const { clubId, features } = req.body;
    
    // 클럽 존재 여부 확인
    const club = await Club.findByPk(clubId);
    
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }
    
    // 클럽 기능 업데이트
    await club.update({ features });
    
    res.json({
      id: club.id,
      features: club.features,
      updatedAt: club.updatedAt
    });
  } catch (error) {
    console.error('클럽 기능 관리 오류:', error);
    res.status(500).json({ message: '클럽 기능을 업데이트하는 중 오류가 발생했습니다.' });
  }
};

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

    // 클럽 존재 여부 확인
    const club = await Club.findByPk(clubId);
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }

    const members = await Member.findAll({
      where: { 
        clubId,
        status: {
          [Op.ne]: 'deleted'
        }
      },
      order: [
        ['memberType', 'ASC'],
        ['name', 'ASC']
      ]
    });

    // 클럽 설정에 따른 에버리지 계산
    const membersWithAverage = await Promise.all(
      members.map(async (member) => {
        try {
          // 모든 회원에 대해 averageService 호출
          const averageData = await averageService.calculateMemberAverageByClubSetting(member.id, clubId);
          return {
            id: member.id,
            userId: member.userId || null,
            name: member.name,
            gender: member.gender,
            memberType: member.memberType,
            handicap: member.handicap,
            average: averageData.average,
            games: averageData.games,
            phone: member.phone,
            email: member.user ? member.user.email : member.email,
            joinDate: member.joinDate,
            status: member.status
          };
        } catch (error) {
          return {
            id: member.id,
            userId: member.userId || null,
            name: member.name,
            gender: member.gender,
            memberType: member.memberType,
            handicap: member.handicap,
            average: 0,
            games: 0,
            phone: member.phone,
            email: member.user ? member.user.email : member.email,
            joinDate: member.joinDate,
            status: member.status
          };
        }
      })
    );
    
    // 응답 데이터 형식화
    const formattedMembers = membersWithAverage;

    res.json(formattedMembers);
  } catch (error) {
    console.error('클럽 회원 목록 조회 오류:', error);
    res.status(500).json({ message: '클럽 회원 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 클럽 회원 추가
exports.addClubMember = async (req, res) => {
  try {
    const { clubId, userId, name, gender, memberType, email, phone, handicap, status } = req.body;

    if (!clubId || !name || !gender) {
      return res.status(400).json({ message: '필수 정보가 누락되었습니다.' });
    }

    const club = await Club.findByPk(clubId);
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }

    // 회원 생성
    const newMember = await Member.create({
      clubId,
      userId,
      name,
      gender,
      memberType: memberType || 'associate',
      email,
      phone,
      handicap,
      status: status || 'active'
    });

    // 클럽의 회원 수 업데이트
    const memberCount = await Member.count({ where: { clubId: clubId, status: 'active' } });
    await club.update({ memberCount });

    res.status(201).json(newMember);
  } catch (error) {
    console.error('클럽 회원 추가 오류:', error);
    res.status(500).json({ message: '회원을 추가하는 중 오류가 발생했습니다.' });
  }
};

// 클럽 회원 정보 수정
exports.updateClubMember = async (req, res) => {
  try {
    const { clubId, memberId, name, gender, memberType, email, phone, handicap, status, joinDate } = req.body;

    if (!clubId || !memberId) {
      return res.status(400).json({ message: '잘못된 클럽 또는 회원 ID입니다.' });
    }

    const member = await Member.findOne({
      where: { 
        id: memberId,
        clubId: clubId
      }
    });

    if (!member) {
      return res.status(404).json({ message: '회원을 찾을 수 없습니다.' });
    }
    
    // 모임장으로 변경 금지 - 모임장 변경은 별도 API로 처리
    if (memberType === 'owner' && member.memberType !== 'owner') {
      return res.status(403).json({ message: '모임장 변경은 클럽 설정에서만 가능합니다.' });
    }

    // 회원 정보 업데이트 (모임장 유지 또는 다른 유형으로 변경만 허용)
    await member.update({
      name: name !== undefined ? name : member.name,
      gender: gender !== undefined ? gender : member.gender,
      memberType: (member.memberType === 'owner' && memberType !== 'owner') ? 'owner' : (memberType !== undefined ? memberType : member.memberType),
      email: email !== undefined ? email : member.email,
      phone: phone !== undefined ? phone : member.phone,
      handicap: handicap !== undefined ? handicap : member.handicap,
      status: status !== undefined ? status : member.status,
      joinDate: joinDate !== undefined ? joinDate : member.joinDate
    });

    // 클럽의 회원 수 업데이트
    const club = await Club.findByPk(clubId);
    if (club) {
      const memberCount = await Member.count({ where: { clubId: clubId, status: 'active' } });
      await club.update({ memberCount });
    }

    res.json(member);
  } catch (error) {
    console.error('클럽 회원 정보 수정 오류:', error);
    res.status(500).json({ message: '회원 정보를 수정하는 중 오류가 발생했습니다.' });
  }
};

// 모임장 변경 내부 메소드
const changeClubOwnerInternal = async (clubId, newOwnerId, ownerEmail = null) => {
  // 트랜잭션 시작
  const t = await sequelize.transaction();
  
  try {
    // 기존 모임장을 운영진으로 변경
    await Member.update(
      { memberType: 'manager' },
      { 
        where: { 
          clubId: clubId,
          memberType: 'owner',
          status: 'active'
        },
        transaction: t
      }
    );
    
    // 새 모임장 확인 및 업데이트
    const newOwnerMember = await Member.findOne({
      where: {
        clubId: clubId,
        userId: newOwnerId,
        status: 'active'
      }
    });
    
    if (newOwnerMember) {
      // 기존 회원인 경우 모임장으로 변경
      await newOwnerMember.update({ memberType: 'owner' }, { transaction: t });
    } else {
      // 새로운 사용자 정보 가져오기
      const newOwnerUser = await User.findByPk(newOwnerId);
      if (!newOwnerUser) {
        await t.rollback();
        throw new Error('새 모임장 사용자 정보를 찾을 수 없습니다.');
      }

      // 새 회원으로 모임장 추가
      await Member.create({
        userId: newOwnerId,
        clubId: clubId,
        name: newOwnerUser.name || (ownerEmail ? ownerEmail.split('@')[0] : ''), // 이름이 없는 경우 이메일 아이디 사용
        gender: 'male', // 성별 정보가 없는 경우 기본값
        memberType: 'owner',
        joinDate: new Date(),
        status: 'active'
      }, { transaction: t });
    }
    
    // 트랜잭션 커밋
    await t.commit();
    return true;
  } catch (error) {
    // 오류 발생 시 트랜잭션 롤백
    await t.rollback();
    throw error;
  }
};

// 클럽 회원 삭제
exports.deleteClubMember = async (req, res) => {
  try {
    const { clubId, memberId } = req.body;

    if (!clubId || !memberId) {
      return res.status(400).json({ message: '잘못된 클럽 또는 회원 ID입니다.' });
    }

    const member = await Member.findOne({
      where: { 
        id: memberId,
        clubId: clubId
      }
    });

    if (!member) {
      return res.status(404).json({ message: '회원을 찾을 수 없습니다.' });
    }

    // 회원 상태를 deleted로 변경
    await member.update({ status: 'deleted' });

    // 클럽의 회원 수 감소
    const club = await Club.findByPk(clubId);
    if (club) {
      const memberCount = await Member.count({ where: { clubId: clubId, status: 'active' } });
      await club.update({ memberCount });
    }

    res.json({ message: '회원이 성공적으로 삭제되었습니다.' });
  } catch (error) {
    console.error('클럽 회원 삭제 오류:', error);
    res.status(500).json({ message: '회원을 삭제하는 중 오류가 발생했습니다.' });
  }
};

// 회원 통계 조회
exports.getMemberStats = async (req, res) => {
  try {
    const { clubId } = req.body;

    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const members = await Member.findAll({
      where: {
        clubId,
        status: 'active'
      }
    });

    const stats = {
      totalCount: members.length,
      regularCount: members.filter(m => m.memberType === 'regular').length,
      associateCount: members.filter(m => m.memberType === 'associate').length
    };

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

// 다음 모임 정보 여러 개 조회
exports.getNextMeetings = async (req, res) => {
  try {
    const { clubId } = req.body;
    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }
    // 오늘 이후의 예정된 모임 중 status가 active인 것 3개까지 오름차순 정렬
    const nextMeetings = await Event.findAll({
      where: {
        clubId,
        startDate: { [Op.gt]: new Date() },
        status: { [Op.or]: ['ready', 'active'] }
      },
      include: [{
        model: EventParticipant,
        where: {
          status: { [Op.ne]: 'canceled' }
        },
        required: false
      }],
      order: [['startDate', 'ASC']],
      limit: 3
    });
    const meetings = nextMeetings.map(meeting => ({
      date: meeting.startDate,
      participantsCount: meeting.EventParticipants ? meeting.EventParticipants.length : 0,
      title: meeting.title,
      location: meeting.location
    }));
    res.json(meetings);
  } catch (error) {
    console.error('다음 모임 정보(여러 개) 조회 오류:', error);
    res.status(500).json({ message: '다음 모임 정보를 가져오는 중 오류가 발생했습니다.' });
  }
};

// 최근 모임 정보 조회
exports.getLastMeeting = async (req, res) => {
  try {
    const { clubId } = req.body;

    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const lastMeeting = await Event.findOne({
      where: {
        clubId,
        startDate: { [Op.lt]: new Date() },
        status: 'active'
      },
      include: [{
        model: EventParticipant,
        where: {
          status: { [Op.ne]: 'canceled' }
        },
        required: false
      }],
      order: [['startDate', 'DESC']]
    });

    if (!lastMeeting) {
      return res.json(null);
    }

    const meetingData = {
      date: lastMeeting.startDate,
      participantsCount: lastMeeting.EventParticipants ? lastMeeting.EventParticipants.length : 0,
      title: lastMeeting.title,
      games: lastMeeting.gameCount || 0
    };

    res.json(meetingData);
  } catch (error) {
    console.error('최근 모임 정보 조회 오류:', error);
    res.status(500).json({ message: '최근 모임 정보를 가져오는 중 오류가 발생했습니다.' });
  }
};

// 점수 통계 조회
exports.getScoreStats = async (req, res) => {
  try {
    const { clubId } = req.body;

    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    // 최근 3개월 내의 이벤트 점수만 집계
    const threeMonthsAgo = new Date();
    threeMonthsAgo.setMonth(threeMonthsAgo.getMonth() - 3);

    const events = await Event.findAll({
      where: {
        clubId,
        startDate: { [Op.gte]: threeMonthsAgo },
        status: 'active'
      },
      include: [{
        model: EventParticipant,
        include: [{
          model: EventScore
        }]
      }]
    });

    let allScores = [];
    let totalGames = 0;

    events.forEach(event => {
      (event.EventParticipants || []).forEach(participant => {
        if (participant.EventScores && participant.EventScores.length > 0) {
          allScores = allScores.concat(participant.EventScores.map(score => score.score));
          totalGames += participant.EventScores.length;
        }
      });
    });

    const stats = {
      topGame: allScores.length > 0 ? Math.max(...allScores) : 0,
      averageScore: allScores.length > 0 ? Math.round(allScores.reduce((a, b) => a + b, 0) / allScores.length) : 0,
      totalGames: totalGames
    };

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

// 상위 회원 목록 조회
exports.getTopMembers = async (req, res) => {
  try {
    const { clubId } = req.body;

    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }
    
    // 클럽 설정 가져오기
    const club = await Club.findByPk(clubId);
    if (!club) {
      return res.status(404).json({ message: '클럽을 찾을 수 없습니다.' });
    }

    // 활동 회원들 전체 조회 (games 컬럼 제거)
    const members = await Member.findAll({
      where: {
        clubId,
        status: 'active'
      },
      attributes: ['id', 'name', 'handicap', 'memberType'],
      limit: 100 // 충분히 넉넉하게 조회
    });

    // 각 회원별 실제 게임 수 집계 (EventScore → EventParticipant 조인)
    const memberIds = members.map(m => m.id);
    // 1. 회원별 EventParticipant 조회
    const participants = await EventParticipant.findAll({
      where: { memberId: memberIds },
      attributes: ['id', 'memberId']
    });
    const participantIdToMemberId = {};
    participants.forEach(p => { participantIdToMemberId[p.id] = p.memberId; });
    // 2. EventScore에서 참가자별 점수 조회
    const scores = await EventScore.findAll({
      where: { participantId: Object.keys(participantIdToMemberId) },
      attributes: ['participantId']
    });
    // 3. memberId별로 게임수 카운트
    const gamesMap = {};
    scores.forEach(s => {
      const memberId = participantIdToMemberId[s.participantId];
      gamesMap[memberId] = (gamesMap[memberId] || 0) + 1;
    });

    // 1게임 이상 플레이한 회원만 필터링
    const filteredMembers = members.filter(m => (gamesMap[m.id] || 0) > 0);

    // 각 회원의 에버리지 계산
    const membersWithAverage = await Promise.all(
      filteredMembers.map(async (member) => {
        try {
          const averageData = await averageService.calculateMemberAverageByClubSetting(member.id, clubId);
          return {
            ...member.toJSON(),
            games: gamesMap[member.id] || 0,
            average: averageData.average
          };
        } catch (error) {
          console.error(`회원 ${member.id}의 에버리지 계산 오류:`, error);
          return {
            ...member.toJSON(),
            games: gamesMap[member.id] || 0,
            average: 0
          };
        }
      })
    );
    
    // 에버리지로 정렬하고 상위 5명만 반환
    const topMembers = membersWithAverage
      .sort((a, b) => b.average - a.average)
      .slice(0, 5);

    res.json(topMembers);
  } catch (error) {
    console.error('상위 회원 목록 조회 오류:', error);
    res.status(500).json({ message: '상위 회원 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 최근 모임 목록 조회
exports.getRecentMeetings = async (req, res) => {
  try {
    const { clubId } = req.body;

    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const recentMeetings = await Event.findAll({
      where: {
        clubId,
        status: { [Op.notIn]: ['canceled', 'deleted'] },
        startDate: { [Op.lt]: new Date() }
      },
      include: [{
        model: EventParticipant,
        where: {
          status: { [Op.ne]: 'canceled' }
        },
        required: false
      }],
      order: [['startDate', 'DESC']],
      limit: 5
    });
    const formattedMeetings = recentMeetings.map(meeting => ({
      date: meeting.startDate,
      title: meeting.title,
      participantsCount: meeting.EventParticipants ? meeting.EventParticipants.length : 0,
      games: meeting.gameCount || 0
    }));

    res.json(formattedMeetings);
  } catch (error) {
    console.error('최근 모임 목록 조회 오류:', error);
    res.status(500).json({ message: '최근 모임 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 사용자 클럽 목록 조회
exports.getUserClubs = async (req, res) => {
  try {
    const { userId } = req.body;
    // admin이면 모든 클럽을, 아니면 자신의 클럽만 조회
    const hasAdminAccess = isAdmin(req.user);

    const queryOptions = {
      where: { status: 'active' }
    };

    // admin이 아닌 경우에만 Member 조건 추가
    if (!hasAdminAccess) {
      queryOptions.include = [{
        model: Member,
        where: {
          userId: userId
        },
        attributes: ['memberType']
      }];
    }

    // order 옵션 추가
    queryOptions.order = [['createdAt', 'DESC']];
    const clubs = await Club.findAll(queryOptions);

    // 응답 데이터 가공
    const formattedClubs = clubs.map(club => {
      const clubData = club.toJSON();
      let memberType = '';

      // admin이 아닌 경우에만 Members가 있음
      if (!hasAdminAccess && clubData.Members && clubData.Members.length > 0) {
        memberType = clubData.Members[0].memberType;
      } else if (hasAdminAccess) {
        memberType = 'admin';
      }

      return {
        id: clubData.id,
        name: clubData.name,
        location: clubData.location,
        memberType
      };
    });

    res.json(formattedClubs);
  } catch (error) {
    console.error('클럽 목록 조회 오류:', error);
    res.status(500).json({ message: '클럽 목록을 가져오는 중 오류가 발생했습니다.' });
  }
};

// 클럽 통계 조회
exports.getStatistics = async (req, res) => {
  try {
    const { clubId, days } = req.body;

    if (!clubId) {
      return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
    }

    const startDate = new Date();
    startDate.setDate(startDate.getDate() - (days || 90)); // 기본값: 90일

    // 1. 회원 통계
    const members = await Member.findAll({
      where: {
        clubId,
        status: 'active'
      }
    });

    // 2. 이벤트 및 참가자 통계
    const events = await Event.findAll({
  where: {
    clubId,
    startDate: { [Op.gte]: startDate },
    status: 'active'
  },
  include: [
    {
      model: EventTeam,
      include: [
        {
          model: EventTeamMember,
          include: [
            {
              model: EventParticipant,
              include: [
                { model: Member },
                { model: EventScore }
              ]
            }
          ]
        }
      ]
    },
    {
      model: EventParticipant,
      include: [{ model: EventScore }]
    }
  ]
});

    // 3. 점수 데이터 수집 (EventParticipants, EventScores 기준)
    let allScores = [];
    let totalParticipants = 0;
    let totalGames = 0;

    events.forEach(event => {
      if (event.EventParticipants) {
        totalParticipants += event.EventParticipants.length;
        event.EventParticipants.forEach(participant => {
          if (participant.EventScores) {
            allScores = allScores.concat(participant.EventScores.map(score => score.score));
            totalGames += participant.EventScores.length;
          }
        });
      }
    });

    // 4. 점수 분포 계산
    const scoreDistribution = Array(10).fill(0);
    allScores.forEach(score => {
      const index = Math.floor(score / 30);
      if (index >= 0 && index < 10) {
        scoreDistribution[index]++;
      }
    });

    // 5. 참석률 추이 계산 (EventParticipants 기준)
    const attendanceTrend = events.map(event => ({
      date: event.startDate,
      attendance: Math.round(((event.EventParticipants ? event.EventParticipants.length : 0) / members.length) * 100)
    }));

    // 6. 회원 순위 계산
    const activeMembers = await Member.findAll({
      where: {
        clubId,
        status: 'active'
      },
      attributes: ['id', 'name', 'handicap', 'memberType'],
      limit: 20 // 에버리지 계산을 위해 여유있게 가져오기
    });
    
    // 각 회원의 에버리지 계산
    const membersWithAverage = await Promise.all(
      activeMembers.map(async (member) => {
        try {
          const averageData = await averageService.calculateMemberAverageByClubSetting(member.id, clubId);
          return {
            ...member.toJSON(),
            average: averageData.average,
            games: averageData.games,
          };
        } catch (error) {
          console.error(`회원 ${member.id}의 에버리지 계산 오류:`, error);
          return {
            ...member.toJSON(),
            average: 0,
            games: 0,
          };
        }
      })
    );
    
    // 에버리지로 정렬하고 상위 10명만 반환
    const memberRankings = membersWithAverage
      .sort((a, b) => b.average - a.average)
      .slice(0, 10);

    // 각 회원의 참석률 계산
    const memberAttendance = {};
    events.forEach(event => {
      if (Array.isArray(event.participants)) {
        event.participants.forEach(participant => {
          memberAttendance[participant.memberId] = memberAttendance[participant.memberId] || { attended: 0, total: 0 };
          memberAttendance[participant.memberId].attended++;
          memberAttendance[participant.memberId].total = events.length;
        });
      }
    });

    const rankingsWithAttendance = memberRankings.map(member => ({
      ...member,
      attendance: memberAttendance[member.id] 
        ? Math.round(memberAttendance[member.id].attended / memberAttendance[member.id].total * 100)
        : 0
    }));

    // 7. 모임별 통계
    const meetingStats = events.map(event => ({
      date: event.startDate,
      title: event.title,
      participants: event.EventParticipants ? event.EventParticipants.length : 0,
      games: event.gameCount || 0,
      averageScore: event.EventParticipants && event.EventParticipants.length > 0
        ? Math.round(
            event.EventParticipants.reduce(
              (sum, p) =>
                sum +
                (p.EventScores && p.EventScores.length > 0
                  ? p.EventScores.reduce((s, score) => s + score.score, 0) / p.EventScores.length
                  : 0),
              0
            ) / event.EventParticipants.length
          )
        : 0
    }));

    // 8. 추가 통계 계산
    // 1. 회원별 최고/최저/총점
    const memberScoreStats = await Promise.all(
      members.map(async member => {
        let scores = [];
        events.forEach(event => {
          if (event.EventParticipants) {
            event.EventParticipants.forEach(participant => {
              if (participant.memberId === member.id && participant.EventScores) {
                scores = scores.concat(participant.EventScores.map(s => s.score));
              }
            });
          }
        });
        return {
          memberId: member.id,
          name: member.name,
          maxScore: scores.length > 0 ? Math.max(...scores) : 0,
          minScore: scores.length > 0 ? Math.min(...scores) : 0,
          totalScore: scores.reduce((a, b) => a + b, 0)
        };
      })
    );

    // 2. 모임별 최고/최저/평균점수
    const meetingScoreStats = events.map(event => {
      let scores = [];
      if (event.EventParticipants) {
        event.EventParticipants.forEach(participant => {
          if (participant.EventScores) {
            scores = scores.concat(participant.EventScores.map(s => s.score));
          }
        });
      }
      return {
        eventId: event.id,
        title: event.title,
        maxScore: scores.length > 0 ? Math.max(...scores) : 0,
        minScore: scores.length > 0 ? Math.min(...scores) : 0,
        avgScore: scores.length > 0 ? Math.round(scores.reduce((a, b) => a + b, 0) / scores.length) : 0
      };
    });

    // 4. 참가자 수 변화 추이
    const participantTrend = events.map(event => ({
      date: event.startDate,
      participantCount: event.EventParticipants ? event.EventParticipants.length : 0
    }));

    // 5. 회원별 모임 참가 횟수
    const memberAttendanceStats = members.map(member => ({
      memberId: member.id,
      name: member.name,
      attendCount: events.reduce((cnt, event) =>
        cnt + (event.EventParticipants ? event.EventParticipants.filter(p => p.memberId === member.id).length : 0), 0)
    }));

    // 6. 팀별 통계 (이벤트별 팀별 평균점수/최고점/참가자수)
    let teamStats = [];
    events.forEach(event => {
      (event.EventTeams || []).forEach(team => {
        let scores = [];
        let members = [];
        (team.EventTeamMembers || []).forEach(tm => {
          const participant = tm.EventParticipant;
          if (participant && participant.EventScores) {
            scores = scores.concat(participant.EventScores.map(s => s.score));
          }
          if (participant && participant.Member) {
            members.push({
              id: participant.Member.id,
              name: participant.Member.name,
              participantId: participant.id
            });
          }
        });
        teamStats.push({
          eventId: event.id,
          teamId: team.id,
          teamNumber: team.teamNumber,
          handicap: team.handicap,
          memberCount: members.length,
          participantCount: members.length, // 참가자수 필드 명시적으로 추가
          members,
          avgScore: scores.length > 0 ? Math.round(scores.reduce((a, b) => a + b, 0) / scores.length) : 0,
          maxScore: scores.length > 0 ? Math.max(...scores) : 0
        });
      });
    });

    // 7. 핸디캡 변화 추이 (회원별, 모임별)
    const handicapTrend = members.map(member => {
      const trend = events.map(event => {
        let handicaps = [];
        if (event.EventParticipants) {
          event.EventParticipants.forEach(participant => {
            if (participant.memberId === member.id && participant.EventScores) {
              handicaps = handicaps.concat(participant.EventScores.map(s => s.handicap));
            }
          });
        }
        return {
          eventId: event.id,
          date: event.startDate,
          avgHandicap: handicaps.length > 0 ? Math.round(handicaps.reduce((a, b) => a + b, 0) / handicaps.length) : 0
        };
      });
      return {
        memberId: member.id,
        name: member.name,
        trend
      };
    });

    // 8. 응답 데이터 구성
    const response = {
      summary: {
        totalMembers: members.length,
        activeMembers: membersWithAverage.filter(m => (m.games || 0) > 0).length,
        averageAttendance: events.length > 0 
          ? Math.round(totalParticipants / (events.length * members.length) * 100)
          : 0,
        highestGame: allScores.length > 0 ? Math.max(...allScores) : 0,
        averageScore: allScores.length > 0 
          ? Math.round(allScores.reduce((a, b) => a + b, 0) / allScores.length)
          : 0,
        totalGames: totalGames,
        totalMeetings: events.length,
        averageParticipants: events.length > 0 
          ? Math.round(totalParticipants / events.length)
          : 0,
        averageGamesPerMeeting: events.length > 0 
          ? Math.round(totalGames / events.length)
          : 0,
        averageHandicap: members.length > 0 
          ? Math.round(members.reduce((sum, m) => sum + m.handicap, 0) / members.length)
          : 0,
        highestHandicap: members.length > 0 
          ? Math.max(...members.map(m => m.handicap))
          : 0,
        lowestHandicap: members.length > 0 
          ? Math.min(...members.map(m => m.handicap))
          : 0
      },
      scoreDistribution: scoreDistribution.map((count, index) => ({
        range: `${index * 30}-${(index + 1) * 30 - 1}`,
        count
      })),
      attendanceTrend,
      memberRankings: rankingsWithAttendance,
      meetingStats,
      // === 추가 통계 ===
      memberScoreStats,
      meetingScoreStats,
      participantTrend,
      memberAttendanceStats,
      teamStats
    };

    res.json(response);
  } catch (error) {
    console.error('통계 데이터 조회 오류:', error);
    res.status(500).json({ message: '통계 데이터를 가져오는 중 오류가 발생했습니다.' });
  }
};
