<template>
  <div class="event-public-wrapper">
    <h1 v-if="clubName" class="p-text-primary p-text-bold p-text-lg p-mb-2">{{ clubName }}</h1>
    <div class="event-public-card">
      <div v-if="loading" class="text-center">로딩 중...</div>
      <div v-else-if="error" class="text-center text-4xl">
        <i class="pi pi-exclamation-triangle text-red block text-8xl"></i>
        <span class="text-red">{{ error }}</span>
      </div>
      <div v-else-if="!isAuthenticated">
        <Card>
          <template #content>
            <div class="event-password-form flex flex-column p-ai-center mt-6 mb-6">
              <i class="pi pi-lock mb-3 event-password-lock"></i>
              <div class="p-text-center mb-3 p-text-lg event-password-desc">이 이벤트는 비밀번호가 필요합니다.<br>비밀번호를 입력해 주세요.</div>
              <InputText v-model="inputPassword" type="password" placeholder="비밀번호 입력" class="p-mb-2 event-password-input"
                @keyup.enter="verifyPassword" autofocus />
              <Button label="확인" @click="verifyPassword" class="p-mb-2 event-password-btn" :loading="loading" />
              <div v-if="passwordError" class="p-error mt-1 event-password-error">{{ passwordError }}</div>
            </div>
          </template>
        </Card>
      </div>
      <div v-else>
        <template v-if="event">
          <Divider class="mb-4" />
          <div class="event-tag mb-2">
            <Tag :value="getEventTypeLabel(event.eventType)" :severity="getEventTypeSeverity(event.eventType)" />
            <Tag :value="getEventStatusLabel(event.status)" :severity="getStatusSeverity(event.status)" class="ml-1" />
          </div>
          <div>
            <div class="flex justify-content-end gap-2">
              <Button :label="joinButtonLabel" class="p-button-lg p-button-primary" @click="showJoinDialog = true" v-if="canJoin" />
            </div>
            <div class="flex justify-content-start p-ai-center mb-4">
              <h2 class="event-title-inline p-text-lg p-text-bold">
                {{ event.title }}
              </h2>
            </div>
            <div class="p-text-secondary mb-3">
              <div class="info-row">
                <i class="pi pi-calendar mr-1" /><strong>기간:</strong>
                {{ formatDate(event.startDate) }}
                <template v-if="event.endDate">~ {{ formatDate(event.endDate) }}</template>
              </div>
              <div v-if="event.registrationDeadline" class="info-row" :class="isRegistrationClosed ? 'text-red' : ''">
                <i class="pi pi-calendar-times mr-1" /><strong>마감:</strong> {{ formatDate(event.registrationDeadline)
                }}
              </div>
              <div v-if="event.location" class="info-row">
                <i class="pi pi-map-marker mr-1" /><strong>장소:</strong> {{ event.location }}
              </div>
              <div v-if="event.participantFee > 0" class="info-row">
                <i class="pi pi-credit-card mr-1" /><strong>참가비:</strong> {{
                  Number(event.participantFee).toLocaleString('ko-KR') }}원
              </div>
              <div v-if="event.maxParticipants > 0" class="info-row">
                <i class="pi pi-user mr-1" /><strong>참여:</strong> {{ participants.length }}/{{ event.maxParticipants
                }}명
              </div>
            </div>
            <div class="p-text-secondary mb-4">{{ event.description || '' }}</div>
            <Divider />
          </div>
          <template v-if="teams.length > 0">
            <Card class="team-score-table-wrapper mb-4">
              <template #content>
                <!-- 팀별 게임별 점수/등수 표 -->
                <DataTable :value="getAllTeamsWithUnassigned()" class="team-score-table" :responsiveLayout="'scroll'">
                  <Column header="팀"> 
                    <template #body="slotProps">
                      팀 {{ slotProps.data.teamNumber }}
                      <span v-if="slotProps.data.handicap" class="team-hc-small">
                        팀 핸디캡: {{ slotProps.data.handicap ?? 0 }}
                      </span>
                    </template>
                  </Column>
                  <Column v-for="n in event.gameCount" :key="n" :header="n + 'G'">
                    <template #body="slotProps">
                      <span class="score-main">{{ getTeamTotalScore(slotProps.data, n) }}</span>
                      <span class="block rank-badge"
                        v-if="getRanksByGame(n)[(slotProps.data.id || slotProps.data.teamNumber) + ''] !== undefined"
                        :class="'rank-badge rank-' + getRanksByGame(n)[(slotProps.data.id || slotProps.data.teamNumber) + '']">
                        ({{ getRanksByGame(n)[(slotProps.data.id || slotProps.data.teamNumber) + ''] }}위)
                      </span>
                    </template>
                  </Column>
                  <Column header="총점">
                    <template #body="slotProps">
                      {{Array.from({ length: event.gameCount }, (_, i) => getTeamTotalScore(slotProps.data, i +
                        1)).reduce((a, b) => a + b, 0) }}
                      <span class="block rank-badge" :class="'rank-' + getTeamOverallRank(slotProps.data)">
                        ({{ getTeamOverallRank(slotProps.data) }}위)
                      </span>
                    </template>
                  </Column>
                </DataTable>
              </template>
            </Card>
            <template v-if="event.status != 'completed'">
              <div v-for="team in getAllTeamsWithUnassigned()" :key="team.id" class="mb-4">
                <Card>
                  <template #content>
                    <MemberListCard
                      :title="parseInt(team.teamNumber) ? '팀 ' + team.teamNumber : '미배정 인원'"
                      :members="team.members"
                      :teamHandicap="team.handicap"
                      :teamNumber="team.teamNumber"
                      :gameCount="event.gameCount"
                      :canInputScore="canInputScore"
                      :scoresProxy="scoresProxy"
                      :scoreStates="scoreStates"
                      :onScoreInput="onScoreInput"
                      :onScoreBlur="onScoreBlur"
                      :onScoreEnter="onScoreEnter"
                      :getMemberTotalScore="getMemberTotalScore"
                      :getMemberAverageScore="getMemberAverageScore"
                      :scoreColorClass="scoreColorClass"
                      :memberRanks="memberRankMap"
                    />
                    <!-- 팀 카드 요약(총점/등수/게임별 점수)은 '팀'만 노출 -->
                    <Divider />
                    <div v-if="team.teamNumber" class="team-game-scores">
                      <div class="team-total-row team-total-row-responsive team-total-row-block">
                        <div class="team-games-grid"
                          :style="{ gridTemplateColumns: `repeat(${event.gameCount > 3 ? 3 : event.gameCount}, 1fr)` }">
                          <template v-for="n in event.gameCount" :key="n">
                            <div class="team-game-cell">
                              <b>{{ n }}G:</b> {{ getTeamTotalScore(team, n) }}
                              <span v-if="getRanksByGame(n)[(team.id || team.teamNumber) + ''] !== undefined"
                                class="rank-badge"
                                :class="'rank-' + getRanksByGame(n)[(team.id || team.teamNumber) + '']">
                                ({{ getRanksByGame(n)[(team.id || team.teamNumber) + ''] }}위)
                              </span>
                            </div>
                          </template>
                        </div>
                        <div class="team-total-main">
                          <span class="team-total-label">총점</span>
                          <span class="team-total-scores">{{ Array.from({ length: event.gameCount }, (_, i) => getTeamTotalScore(team, i + 1)).reduce((a, b) => a + b, 0) }}</span>
                          <span v-if="getTeamOverallRank({ ...team, id: (team.id || team.teamNumber) + '' })"
                            class="rank-badge"
                            :class="'rank-' + getTeamOverallRank({ ...team, id: (team.id || team.teamNumber) + '' })">
                            {{ getTeamOverallRank({ ...team, id: (team.id || team.teamNumber) + '' }) }}위
                          </span>
                        </div>
                      </div>
                    </div>
                  </template>
                </Card>
              </div>
            </template>
          </template>
          <template v-else>
            <template v-if="event.status != 'completed'">  
              <Card>
                <template #content>
                  <MemberListCard
                    title="참가자"
                    :members="sortedParticipants"
                    :gameCount="event.gameCount"
                    :canInputScore="canInputScore"
                    :scoresProxy="scoresProxy"
                    :scoreStates="scoreStates"
                    :onScoreInput="onScoreInput"
                    :onScoreBlur="onScoreBlur"
                    :onScoreEnter="onScoreEnter"
                    :getMemberTotalScore="getMemberTotalScore"
                    :getMemberAverageScore="getMemberAverageScore"
                    :scoreColorClass="scoreColorClass"
                    :memberRanks="memberRankMap"
                  />
                </template>
              </Card>
            </template>
          </template>
          <template v-if="event.status == 'completed'">
            <Card>
              <template #title>
                <div class="card-title-with-button">
                  <h2>최종 순위</h2>
                </div>
              </template>
              <template #content>
                <DataTable :value="getFinalRankingData()" stripedRows :paginator="true" :rows="30" 
                  paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
                  :rowsPerPageOptions="[5,10,20,30,50]" responsiveLayout="scroll">
                  
                  <!-- 순위 열 -->
                  <Column field="rank" header="순위" :sortable="true" style="width: 3%;">
                    <template #body="slotProps">
                      <span :class="'rank-badge rank-' + slotProps.data.rank">
                        {{ slotProps.data.rank }}
                      </span>
                    </template>
                  </Column>
                  
                  <!-- 이름 열 -->
                  <Column field="name" header="이름" :sortable="true" style="min-width: 7rem;"></Column>
                  
                  <!-- 핸디캡 열 -->
                  <Column field="handicap" header="핸디캡" :sortable="true"></Column>
                  
                  <!-- 게임별 점수 열 -->
                  <template v-for="n in event.gameCount" :key="n">
                    <Column :field="'game' + n" :header="n + 'G'" :sortable="true">
                      <template #body="slotProps">
                        <span :class="{ 'score-red': slotProps.data['game' + n] >= 200 }">
                          {{ slotProps.data['game' + n] }}
                        </span>
                      </template>
                    </Column>
                  </template>
                  
                  <!-- 총점 열 -->
                  <Column field="totalScore" header="총점" :sortable="true">
                    <template #body="slotProps">
                      <b>{{ slotProps.data.totalScore }}</b>
                    </template>
                  </Column>
                  
                  <!-- 에버리지 열 -->
                  <Column field="average" header="에버리지" :sortable="true">
                    <template #body="slotProps">
                      <span :class="{ 'score-red': slotProps.data.average >= 200 }">
                        {{ slotProps.data.average }}
                      </span>
                    </template>
                  </Column>
                </DataTable>
              </template>
            </Card>
          </template>    
        </template>
      </div>
    </div>
    <JoinDialog v-if="showJoinDialog && canJoin" v-model:visible="showJoinDialog" :publicHash="publicHash"
              :participants="participants"
              :availableMembers="availableMembers" :eventStatus="event.status"
              @close="showJoinDialog = false" @updated="reload" @guest-added="handleGuestAdded" />
  </div>
</template>

<script setup>
import { getGenderLabel, getMemberTypeLabel, getStatusLabel, getPaymentStatusLabel, getEventStatusLabel, getEventTypeLabel, getStatusSeverity, getEventTypeSeverity } from '@/utils/enumMappings';
import { ref, reactive, computed, onMounted, watch } from 'vue';
import {
  calculateIndividualRankings,
  calculateGameRankings,
  calculateParticipantTotalScore,
  calculateMemberAverageScore,
  calculateTeamGameScore,
  calculateTeamTotalHandicap,
  calculateTeamOverallRankings
} from '@/utils/rankingUtils';
import { debounce } from 'lodash-es'; // lodash 설치 필요 (이미 있다면 무시)
import { useRoute } from 'vue-router';
import MemberListCard from '@/components/public/MemberListCard.vue';
import JoinDialog from '@/components/public/JoinDialog.vue';
import dayjs from 'dayjs';
import PublicEventService from '@/services/PublicEventService';
import { useHead } from '@vueuse/head';

const route = useRoute();
const publicHash = route.params.publicHash;

const loading = ref(true);
const error = ref('');
const clubName = ref('');
const event = ref({});
const teams = ref([]);
const participants = ref([]);
const isAuthenticated = ref(false);
const inputPassword = ref('');
const passwordError = ref('');
const showJoinDialog = ref(false);

const allMembers = ref([]); // 전체 클럽 멤버 목록
const availableMembers = ref([]); // 참가 신청 가능 명단
// ===== 이벤트 상태별 권한 제어 =====
const isReady = computed(() => event.value.status === 'ready');
const isActive = computed(() => event.value.status === 'active');
const isFinished = computed(() => event.value.status === 'completed');

// description만 이벤트 정보로 동적으로 설정
const eventDescriptionText = computed(() => {
  const e = event.value || {};
  let summary = '';
  if (e.startDate) {
    summary += `[기간] ${formatDate(e.startDate)}`;
    if (e.endDate) summary += ` ~ ${formatDate(e.endDate)}`;
    summary += '.\n';
  }
  if (e.description) summary += `[이벤트 내용] ${e.description}`;
  if (e.location) summary += `[장소] ${e.location}.\n`;
  if (e.registrationDeadline) summary += `[신청마감] ${formatDate(e.registrationDeadline)}.\n`;
  if (e.maxParticipants) summary += `[참가인원] ${e.maxParticipants}명\n`;
  
  return summary || '이벤트 정보가 없습니다.';
});

useHead({
  meta: [
    { title: event.value.title },
    { property: 'og:title', content: event.value.title },
    { name: 'description', content: eventDescriptionText },
    { property: 'og:description', content: eventDescriptionText }
  ]
});

// 신청 마감일시 체크
const isRegistrationClosed = computed(() => {
  if (!event.value.registrationDeadline) return false;
  const now = new Date();
  const deadline = new Date(event.value.registrationDeadline);
  return now > deadline;
});

// 신청 마감일시가 지나지 않았고, 이벤트가 준비 또는 활성 상태이며, 인증되었을 때만 참가 신청 가능
const canJoin = computed(() => (isReady.value || isActive.value) && isAuthenticated.value && !isRegistrationClosed.value);
const canEditParticipant = computed(() => (isReady.value || isActive.value) && isAuthenticated.value);
const canInputScore = computed(() => isActive.value && isAuthenticated.value);

const joinButtonLabel = computed(() => {
  if (isRegistrationClosed.value) return '신청 마감';
  if (isReady.value) return '참가 신청/수정';
  if (isActive.value) return '참가자 정보 수정';
  return '참가자 정보';
});
// ==============================


// 점수 상태 관리: idle, saving, saved, error
const scoreStates = reactive({});

// 총점 기준 순위 맵 (reactive 값)
const memberRankMap = reactive({});

// 게임별 순위 맵
const gameRanks = reactive({});

// 점수 색상 클래스 계산
// 점수 색상 클래스 계산 (핸디캡 포함)
function scoreColorClass(state, value, handicap) {
  if (state === 'saving' || state === undefined) return 'score-gray';
  const baseScore = Number(value);
  const hc = Number(handicap) || 0;
  const total = baseScore + hc;
  if (state === 'saved') {
    if (value === '' || value === null || isNaN(baseScore)) return 'score-gray';
    return total >= 200 ? 'score-red' : 'score-black';
  }
  if (state === 'idle') {
    // 값이 있으면 색상 유지, 없으면 회색
    if (value === '' || value === null || isNaN(baseScore)) return 'score-gray';
    return total >= 200 ? 'score-red' : 'score-black';
  }
  if (state === 'error') return 'score-gray';
  return 'score-gray';
}

// 점수 저장 로직 (API 연동)
const saveScore = debounce(async (member, n, oldValue, newValue, teamNumber) => {
  const key = member.participantId + '-' + n;
  if (String(oldValue) === String(newValue)) return; // 변경 없으면 저장 X
  scoreStates[key] = 'saving';
  try {
    // 실제 API 연동
    const res = await PublicEventService.updateScore(publicHash, member.participantId, n, Number(newValue), Number(member.handicap || 0), teamNumber ?? null);
    if (!res.ok) throw new Error('점수 저장 실패');
    scoreStates[key] = 'saved';
    // 프론트 점수 동기화
    if (Array.isArray(member.scores)) {
      member.scores[n-1] = Number(newValue);
    }
    setTimeout(() => { scoreStates[key] = 'idle'; }, 1200); // 일정 시간 후 아이콘 사라지게
    
    // 점수 저장 후 순위 업데이트
    updateMemberRanks();
  } catch (e) {
    scoreStates[key] = 'error';
    setTimeout(() => { scoreStates[key] = 'idle'; }, 2000);
  }
}, 200);

// 최종 순위 데이터 생성 함수
const getFinalRankingData = () => {
  if (!participants.value || participants.value.length === 0) return [];
  
  // 순위 계산
  const activeParticipants = participants.value.filter(p => p && p.status !== '취소');
  const ranks = calculateIndividualRankings(activeParticipants, scoresProxy.value, event.value.gameCount);
  
  // 순위 맵을 memberRankMap에도 적용하여 팀 카드에서도 동일한 순위 사용
  Object.keys(ranks).forEach(participantId => {
    memberRankMap[participantId] = ranks[participantId];
  });
  
  // 참가자별 데이터 생성
  const rankingData = activeParticipants.map(participant => {
    const participantId = participant.participantId;
    const handicap = Number(participant.handicap) || 0;
    
    // 게임별 점수 계산
    const gameScores = {};
    let totalScore = 0;
    let playedGames = 0;
    
    for (let i = 1; i <= event.value.gameCount; i++) {
      const scoreKey = `${participantId}-${i}`;
      const rawScore = scoresProxy.value[scoreKey];
      
      if (rawScore !== undefined && rawScore !== null && rawScore !== '') {
        const score = Number(rawScore);
        // 핸디캡 포함 점수가 300점을 넘지 않도록 제한
        const scoreWithHc = Math.min(score + handicap, 300);
        
        gameScores[`rawGame${i}`] = score;
        gameScores[`game${i}`] = scoreWithHc;
        totalScore += scoreWithHc;
        playedGames++;
      } else {
        gameScores[`rawGame${i}`] = 0;
        gameScores[`game${i}`] = 0;
      }
    }
    
    // 평균 점수 계산 (소수점 1자리까지 표시)
    const average = playedGames > 0 ? (totalScore / playedGames).toFixed(1) : 0;
    
    return {
      participantId,
      rank: ranks[participantId] || '-',
      name: participant.name || '이름없음',
      handicap,
      ...gameScores,
      totalScore,
      average
    };
  });
  
  // 순위로 정렬
  rankingData.sort((a, b) => {
    if (a.rank === '-') return 1;
    if (b.rank === '-') return -1;
    return a.rank - b.rank;
  });
  
  return rankingData;
};


function onScoreBlur(member, n, teamNumber) {
  const key = member.participantId + '-' + n;
  const val = (scoresProxy.value[key] === undefined || scoresProxy.value[key] === null) ? '' : String(scoresProxy.value[key]);
  // 화면상의 이전 값(마지막 저장된 값)을 별도로 기억해야 함
  const oldVal = (onScoreBlur.lastValues && onScoreBlur.lastValues[key] !== undefined) ? String(onScoreBlur.lastValues[key]) : '';
  if (oldVal === val) return;
  saveScore(member, n, oldVal, val, teamNumber);
  // 저장 후 이전 값 갱신
  if (!onScoreBlur.lastValues) onScoreBlur.lastValues = {};
  onScoreBlur.lastValues[key] = val;
}
// onScoreInput에서 입력값을 기록해두고, blur에서 비교
function onScoreInput(member, n, teamNumber) {
  const key = member.participantId + '-' + n;
  scoreStates[key] = 'idle'; // 입력 시작 시 상태 초기화(회색)
  const val = String(scoresProxy.value[key] ?? '');
  // 기존 저장된 값과 다를 때만 저장
  const oldVal = member.scores?.[n-1] ?? '';
  if (val.length === 3 && String(oldVal) !== val) {
    saveScore(member, n, oldVal, val, teamNumber);
  }
}
function onScoreEnter(member, n, teamNumber) {
  const key = member.participantId + '-' + n;
  const val = String(scoresProxy.value[key] ?? '');
  saveScore(member, n, member.scores?.[n-1] ?? '', val, teamNumber);
}

// 멤버별 평균 점수 계산 (입력된 점수만 평균, 소수점 1자리) - rankingUtils 사용
function getMemberAverageScore(member) {
  if (!member || !event.value.gameCount) return 0;
  return calculateMemberAverageScore(member, scoresProxy.value, event.value.gameCount);
}

// 멤버별 핸디캡 포함 총점 계산 - rankingUtils 사용
function getMemberTotalScore(member) {
  if (!member || !event.value.gameCount) return 0;
  return calculateParticipantTotalScore(member, scoresProxy.value, event.value.gameCount);
}

// 총점 기준 순위 계산 (일반 함수로 변경)
function updateMemberRanks() {
  // 순위 계산에 사용할 참가자 목록 가져오기
  const activeParticipants = [];
  
  // 참가자 배열 직접 사용
  if (participants.value && participants.value.length > 0) {
    // 취소되지 않은 참가자만 필터링
    activeParticipants.push(...participants.value.filter(p => p && p.status !== '취소'));
  } else {
    
    // 백업 방법: 팀과 미배정 멤버 사용
    if (teams.value && teams.value.length > 0) {
      teams.value.forEach(team => {
        if (team.members && team.members.length > 0) {
          activeParticipants.push(...team.members.filter(m => m && m.status !== '취소'));
        }
      });
    }
    
    if (unassignedMembers.value && unassignedMembers.value.length > 0) {
      activeParticipants.push(...unassignedMembers.value.filter(m => m && m.status !== '취소'));
    }
  }
  
  // 순위 계산 유틸리티 함수 호출
  const ranks = calculateIndividualRankings(
    activeParticipants,
    scoresProxy.value, // .value 추가
    event.value?.gameCount || 3
  );
  
  // 순위 맵 초기화
  Object.keys(memberRankMap).forEach(key => {
    delete memberRankMap[key];
  });
  
  // 순위 맵에 계산된 순위 적용
  Object.keys(ranks).forEach(participantId => {
    memberRankMap[participantId] = ranks[participantId];
    
    // 참가자 이름 찾기
    const participant = activeParticipants.find(p => p.participantId == participantId);
    const name = participant ? (participant.name || '이름없음') : '알 수 없음';
  });
  
  
  // 게임별 순위도 계산
  updateGameRankings();
}

// 게임별 순위 계산 함수
function updateGameRankings() {
  // 게임 수 가져오기
  const gameCount = event.value?.gameCount || 3;
  
  // 팀 데이터 가져오기 (미배정 포함)
  const allTeams = getAllTeamsWithUnassigned();
  
  // 각 게임별로 순위 계산
  for (let i = 1; i <= gameCount; i++) {
    // 게임별 팀 점수 계산
    const teamsWithGameScores = allTeams.map(team => {
      const gameScore = getTeamTotalScore(team, i);
      return {
        teamId: team.id || team.teamNumber,
        teamNumber: team.teamNumber,
        gameScore: gameScore,
        isUnassigned: team.isUnassigned || false
      };
    });
    
    // 게임 점수 기준 내림차순 정렬
    teamsWithGameScores.sort((a, b) => b.gameScore - a.gameScore);
    
    // 순위 맵 초기화
    gameRanks[i] = {};
    
    // 순위 부여
    let rank = 1;
    let prevScore = -1;
    let sameRankCount = 0;
    
    teamsWithGameScores.forEach((team, index) => {
      // 동점자 처리
      if (prevScore === team.gameScore) {
        sameRankCount++;
      } else {
        rank = index + 1 - sameRankCount;
        prevScore = team.gameScore;
        sameRankCount = 0;
      }
      
      // 순위 저장
      gameRanks[i][team.teamId] = rank;
    });
  }
}

// 게임별 순위 가져오기
function getRanksByGame(gameNumber) {
  if (!gameRanks[gameNumber]) {
    updateGameRankings();
  }
  return gameRanks[gameNumber] || {};
}

// 각 참가자별로 점수 배열(scores) 생성 (점수 미정시 null)
const sortedParticipants = computed(() => {
  return [...participants.value].map(p => {
    // 기존 score가 단일 값이면 배열로 변환
    let scores = [];
    if (Array.isArray(p.scores)) {
      scores = p.scores;
    } else if (typeof p.score !== 'undefined') {
      // 백엔드에서 배열이 안 내려올 경우 단일값을 1게임으로 간주
      scores = [p.score];
    } else {
      // 여러 게임 점수 미존재시 null로 채움
      scores = Array(event.value.gameCount).fill(null);
    }
    // 점수 개수 맞추기
    if (scores.length < event.value.gameCount) {
      scores = [...scores, ...Array(event.value.gameCount - scores.length).fill(null)];
    }
    return { ...p, scores };
  }).sort((a, b) => (a.name || '').localeCompare(b.name || '', 'ko'));
});

// 점수 입력용 프록시 (v-model에서 계산식 사용 회피)
const scoresProxy = ref({});

// 점수 입력 프록시를 숫자만으로 초기화
function initScoresProxy() {
  if (!participants.value || !event.value?.gameCount) return;
  participants.value.forEach(member => {
    for (let n = 1; n <= event.value.gameCount; n++) {
      const key = member.participantId + '-' + n;
      // 객체 구조면 .score, 아니면 빈칸
      let score = '';
      if (member.scores && member.scores[n-1] && typeof member.scores[n-1] === 'object' && 'score' in member.scores[n-1]) {
        score = member.scores[n-1].score ?? '';
      } else if (member.scores && typeof member.scores[n-1] === 'number') {
        score = member.scores[n-1];
      }
      scoresProxy.value[key] = score;
    }
  });
}

// fetchEventData 등 데이터 로딩 후 반드시 호출
watch([participants, () => event.value?.gameCount], () => {
  initScoresProxy();
});

// 팀 미배정 인원 (백엔드 응답을 그대로 사용)
const unassignedMembers = ref([]);

function formatDate(date) {
  if (!date) return '-';
  const d = dayjs(date);
  const ampm = d.format('A') === 'AM' ? '오전' : '오후';
  return `${d.format('YYYY-MM-DD')} ${ampm} ${d.format('hh:mm')}`;
}

async function fetchEventData(password) {
  loading.value = true;
  error.value = '';
  try {
    const { status, data } = await PublicEventService.fetchEvent(publicHash, password);
    if (status === 403) {
      error.value = '이벤트에 접근할 수 없습니다.';
      PublicEventService.removeToken(publicHash);
      event.value = null;
      return;
    }
    if (status === 401) {
      isAuthenticated.value = false;
      PublicEventService.removeToken(publicHash);
      event.value = null;
      return;
    }
    if (status === 404 || (data && data.message === '이벤트를 찾을 수 없습니다.')) {
      error.value = data && data.message ? data.message : '존재하지 않는 이벤트입니다.';
      event.value = null;
      return;
    }
    clubName.value = data.clubName || '';
    event.value = data.event;
    teams.value = data.teams || [];
    participants.value = data.participants || [];
    unassignedMembers.value = data.unassignedMembers || [];
    availableMembers.value = data.availableMembers || [];
    isAuthenticated.value = true;
    // [추가] 기존 점수를 scoresProxy에 반영
    const proxy = {};
    [...(data.teams || [])].forEach(team => {
      (team.members || []).forEach(member => {
        if (Array.isArray(member.scores)) {
          member.scores.forEach((score, idx) => {
            const key = member.participantId + '-' + (idx + 1);
            proxy[key] = score !== null && score !== undefined ? String(score) : '';
          });
        }
      });
    });
    (data.unassignedMembers || []).forEach(member => {
      if (Array.isArray(member.scores)) {
        member.scores.forEach((score, idx) => {
          const key = member.participantId + '-' + (idx + 1);
          proxy[key] = score !== null && score !== undefined ? String(score) : '';
        });
      }
    });
    scoresProxy.value = proxy;
    // [추가] 점수 상태도 초기화 (핸디캡 포함 점수 기준 색상 적용)
    Object.keys(proxy).forEach(key => {
      // 점수 상태는 항상 'idle'로 초기화 (저장됨 아이콘이 안나오게)
      scoreStates[key] = 'idle';
    });
    
    // 순위 업데이트
    updateMemberRanks();
    
    // 순위 맵이 비어있으면 순위 계산 유틸리티 함수 사용
    if (Object.keys(memberRankMap).length === 0) {
      // 참가자 데이터가 있는 경우
      if (participants.value && participants.value.length > 0) {
        // 취소되지 않은 참가자만 필터링
        const activeParticipants = participants.value.filter(p => p && p.status !== '취소');
        
        // 순위 계산 유틸리티 함수 호출
        const initialRanks = calculateIndividualRankings(
          activeParticipants,
          scoresProxy.value, // .value 추가
          event.value?.gameCount || 3
        );
        
        // 계산된 순위 적용
        Object.keys(initialRanks).forEach(participantId => {
          memberRankMap[participantId] = initialRanks[participantId];
        });
      }
    }
  } catch (e) {
    error.value = e.message;
    event.value = null;
  } finally {
    loading.value = false;
  }
}

function verifyPassword() {
  passwordError.value = '';
  PublicEventService.removeToken(publicHash); // 항상 먼저 토큰 제거
  fetchEventData(inputPassword.value).then(() => {
    if (isAuthenticated.value) {
      inputPassword.value = '';
    } else {
      passwordError.value = '비밀번호가 올바르지 않습니다.';
      PublicEventService.removeToken(publicHash);
    }
  });
}

function reload() {
  fetchEventData();
}

// 게스트 추가 시 처리 함수
function handleGuestAdded(guest) {
  // 게스트 추가 후 전체 데이터 다시 불러오기
  reload();
}

// 페이지 진입 시 Google Analytics 페이지뷰 추적
onMounted(() => {
  const gtag = useGtag();
  gtag.pageview({
    page_title: '이벤트공개페이지',
    page_path: window.location.pathname,
    page_location: window.location.href
  });
  const token = sessionStorage.getItem('event_token_' + publicHash);
  if (token) {
    fetchEventData();
  } else {
    fetchEventData();
  }
});

// 팀별 게임별 합산 점수 계산 (computed)
// 팀별 게임별 합산 점수 계산 함수 (단순 값 반환)
function getAllTeamsWithUnassigned() {
  // 멤버 1명 이상인 팀만 등수 산정에 포함
  const teamList = (teams.value || [])
    .filter(team => team.members && team.members.length > 0)
    .map(team => ({
      ...team,
      id: team.id || team.teamNumber, // id 없으면 teamNumber 사용
      isUnassigned: false
    }));
  if (unassignedMembers.value && unassignedMembers.value.length > 0) {
    teamList.push({
      id: 'unassigned',
      teamNumber: '미배정',
      members: unassignedMembers.value,
      handicap: 0,
      isUnassigned: true
    });
  }
  return teamList;
}

// 팀별 게임 총점 계산 함수 - rankingUtils 사용
function getTeamTotalScore(team, gameIdx) {
  if (!team || !team.members) return 0;
  return calculateTeamGameScore(team, scoresProxy.value, gameIdx);
}

// 팀별 핸디캡 합산 계산 함수 - rankingUtils 사용
function getTeamTotalHandicap(team) {
  if (!team || !team.members) return 0;
  return calculateTeamTotalHandicap(team);
}

// 전체 게임 합계 기준 팀별 등수 계산 함수 - rankingUtils 사용
function getTeamOverallRank(team) {
  if (!team || !team.id) return '';
  
  // 실제 팀만 포함하여 순위 계산
  const allTeams = getAllTeamsWithUnassigned();
  const rankMap = calculateTeamOverallRankings(allTeams, scoresProxy.value, event.value.gameCount);
  
  // 해당 팀의 순위 반환
  const teamId = team.id || team.teamNumber;
  return rankMap[teamId] || '';
}

// 게임별 팀 등수 계산 함수 (rankingUtils로 대체됨)
// 이 함수는 삭제되었으며 새로운 getRanksByGame 함수를 사용합니다.


</script>
<style src="./EventPublicPage.css"></style>