<template>
  <div class="score-management">
    <DataTable
      :value="groupedScores"
      :loading="loading"
      class="mt-4"
      :paginator="true"
      :rows="30"
      stripedRows
      v-model:filters="filters"
      :sortField="'participant.name'"
      :sortOrder="1"
    >
      <!-- 순위 컬럼 추가 -->
      <Column field="rank" header="순위" sortable style="width: 5rem;">
        <template #body="slotProps">
          <span :class="'rank-badge rank-' + slotProps.data.rank">
            {{ slotProps.data.rank || '-' }}
          </span>
        </template>
      </Column>
      <Column field="participant.name" header="참가자" sortable>
        <template #body="slotProps">
          {{ slotProps.data.participant?.name }}
        </template>
      </Column>
      <template v-for="i in maxGames" :key="i">
        <Column :field="'games.' + (i-1) + '.score'" :header="i + '게임'" sortable>
          <template #body="slotProps">
            <div class="flex flex-column">
              <span :class="getScoreClass(getTotalScore(slotProps.data.games[i-1]))">
                {{ getTotalScore(slotProps.data.games[i-1]) || '-' }}
              </span>
              <span class="text-xs text-gray-500" v-if="slotProps.data.games[i-1]?.score && slotProps.data.games[i-1]?.handicap !== 0">
                {{ formatScoreWithHandicap(slotProps.data.games[i-1]) }}
              </span>
            </div>
          </template>
        </Column>
      </template>
      <!-- 총점 컬럼 추가 -->
      <Column field="totalScore" header="총점" sortable>
        <template #body="slotProps">
          <div class="flex flex-column">
            <span>{{ calculateTotalScore(slotProps.data.games) }}</span>
            <span class="text-xs text-gray-500" v-if="calculateRawTotalScore(slotProps.data.games) !== '-' && calculateTotalHandicap(slotProps.data.games) > 0">
              ({{ calculateRawTotalScore(slotProps.data.games) }}+{{ calculateTotalHandicap(slotProps.data.games) }})
            </span>
          </div>
        </template>
      </Column>
      <Column field="average" header="평균" sortable>
        <template #body="slotProps">
          <div class="flex flex-column">
            <span :class="getScoreClass(calculateAverage(slotProps.data.games))">
              {{ calculateAverage(slotProps.data.games) }}
            </span>
            <span class="text-xs text-gray-500" v-if="calculateRawAverage(slotProps.data.games) !== '-' && calculateTotalHandicap(slotProps.data.games) > 0">
              ({{ calculateRawAverage(slotProps.data.games) }})
            </span>
          </div>
        </template>
      </Column>
      <Column header="작업">
        <template #body="slotProps">
          <div class="flex gap-2">
            <Button icon="pi pi-pencil" class="p-button-rounded p-button-text" @click="editScore(slotProps.data)" />
            <Button icon="pi pi-trash" class="p-button-rounded p-button-text" @click="deleteParticipantScores(slotProps.data)" />
          </div>
        </template>
      </Column>
    </DataTable>

    <!-- 점수 입력/수정 다이얼로그 -->
    <Dialog v-model:visible="scoreDialog" :header="scoreDialogTitle" modal class="p-fluid" :style="{width: '600px'}">
      <div class="field">
        <label for="participant">참가자</label>
        <Select
          id="participant"
          v-model="editingScore.participantId"
          :options="participants"
          optionLabel="name"
          optionValue="id"
          placeholder="참가자 선택"
          :class="{'p-invalid': submitted && !editingScore.participantId}"
          :disabled="editingScore.isEdit"
        />
        <small v-if="submitted && !editingScore.participantId" class="p-error">참가자를 선택해주세요.</small>
      </div>

      <div class="grid">
        <template v-for="game in editingScore.games" :key="game.gameNumber">
          <div class="col-6">
            <div class="field">
              <label :for="'game' + game.gameNumber">{{ game.gameNumber }}게임 점수</label>
              <InputNumber
                :id="'game' + game.gameNumber"
                v-model="game.score"
                :min="0"
                :max="300"
                :placeholder="game.gameNumber + '게임 점수 입력(핸디캡 제외)'"
                @update:modelValue="() => onScoreChange(game)"
                class="w-full"
              />
            </div>
          </div>
          <div class="col-6">
            <div class="field">
              <label :for="'handicap' + game.gameNumber">{{ game.gameNumber }}게임 핸디캡</label>
              <InputNumber
                :id="'handicap' + game.gameNumber"
                v-model="game.handicap"
                :min="-300"
                :max="300"
                placeholder="핸디캡 입력"
                @update:modelValue="() => onScoreChange(game)"
                class="w-full"
              />
            </div>
          </div>
        </template>
      </div>

      <template #footer>
        <Button label="취소" icon="pi pi-times" class="p-button-text" @click="hideScoreDialog" />
        <Button label="저장" icon="pi pi-check" class="p-button-text" @click="saveScore" />
      </template>
    </Dialog>

    <!-- 삭제 확인 다이얼로그 -->
    <Dialog v-model:visible="deleteScoreDialog" :style="{width: '450px'}" header="확인" :modal="true">
      <div class="confirmation-content">
        <i class="pi pi-exclamation-triangle mr-3" style="font-size: 2rem" />
        <span>이 점수를 삭제하시겠습니까?</span>
      </div>
      <template #footer>
        <Button label="아니오" icon="pi pi-times" class="p-button-text" @click="deleteScoreDialog = false" />
        <Button label="예" icon="pi pi-check" class="p-button-text" @click="deleteScore" />
      </template>
    </Dialog>

    <!-- 점수 추가 버튼 -->
    <div class="flex justify-content-end mt-4">
      <Button label="점수 추가" icon="pi pi-plus" @click="showScoreDialog" />
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue';
import { useToast } from 'primevue/usetoast';
import eventService from '@/services/eventService';
import { calculateIndividualRankings } from '@/utils/rankingUtils';

const props = defineProps({
  eventId: {
    type: [String, Number],
    required: true
  },
  maxGames: {
    type: Number,
    required: true
  }
});

const emit = defineEmits(['score-updated']);
const toast = useToast();
const scores = ref([]);
const loading = ref(false);
const filters = ref({});
const scoreDialog = ref(false);
const deleteScoreDialog = ref(false);
const submitted = ref(false);
const participants = ref([]);

const editingScore = ref({
  isEdit: false,
  participantId: null,
  teamNumber: null,
  games: []
});

// 점수 목록 조회
const fetchScores = async () => {
  loading.value = true;
  try {
    const response = await eventService.getEventScores(props.eventId);
    scores.value = response || []; 
    await fetchParticipants();
  } catch (error) {
    console.error('점수 조회 오류:', error);
    scores.value = []; 
    toast.add({
      severity: 'error',
      summary: '오류',
      detail: error.message || '점수 목록을 가져오는 중 오류가 발생했습니다.',
      life: 3000
    });
  } finally {
    loading.value = false;
  }
};

// 참가자 목록 조회
const fetchParticipants = async () => {
  try {
    const data = await eventService.getEventParticipants(props.eventId);
    if (Array.isArray(data)) {
      participants.value = data.map(p => ({
        id: p.id,
        name: p.Member.name
      }));
    } else {
      participants.value = [];
      console.error('참가자 데이터가 배열이 아닙니다:', data);
    }
  } catch (error) {
    console.error('참가자 조회 오류:', error);
    participants.value = [];
    toast.add({
      severity: 'error',
      summary: '오류',
      detail: error.message || '참가자 목록을 가져오는 중 오류가 발생했습니다.',
      life: 3000
    });
  }
};

// 점수 수정 다이얼로그 열기
const editScore = (data) => {
  // console.log('Edit score data:', data); 
  editingScore.value = {
    isEdit: true,
    participantId: data.participant.id,
    teamNumber: data.teamNumber,
    games: data.games.map((game, index) => ({
      id: game.id, 
      gameNumber: game.gameNumber ?? index + 1, 
      score: game.score ?? null,
      handicap: game.handicap ?? null,
      isModified: false
    }))
  };
  scoreDialog.value = true;
};

// 신규 점수 입력 다이얼로그 열기
const showScoreDialog = async () => {
  try {
    // 참가자 목록 갱신
    await fetchParticipants();
    
    editingScore.value = {
      isEdit: false,
      participantId: null,
      teamNumber: null,
      games: Array.from({ length: props.maxGames }, (_, i) => ({
        id: null,
        gameNumber: i + 1,
        score: null,
        handicap: null,
        isModified: false
      }))
    };
    submitted.value = false;
    scoreDialog.value = true;
  } catch (error) {
    console.error('점수 입력 다이얼로그 오류:', error);
    toast.add({
      severity: 'error',
      summary: '오류',
      detail: '참가자 목록을 가져오는 중 오류가 발생했습니다.',
      life: 3000
    });
  }
};

// 다이얼로그 닫기
const hideScoreDialog = () => {
  scoreDialog.value = false;
  submitted.value = false;
};

// 점수 저장
const saveScore = async () => {
  submitted.value = true;

  if (!editingScore.value.participantId) {
    toast.add({
      severity: 'error',
      summary: '오류',
      detail: '참가자를 선택해주세요.',
      life: 3000
    });
    return;
  }

  try {
    if (editingScore.value.isEdit) {
      // 수정 모드: 변경된 게임만 업데이트
      const updatePromises = editingScore.value.games
        .map((game) => {
          // 점수가 없으면 건너뛰기
          if (game.score === null || game.score === undefined) return null;
          
          // 기존 게임이면서 수정되지 않은 경우 건너뛰기
          if (game.id && !game.isModified) return null;

          const scoreData = {
            gameNumber: game.gameNumber,
            score: game.score,
            handicap: game.handicap || 0
          };

          // 기존 게임 수정
          if (game.id) {
            console.log('Updating existing game:', {
              eventId: props.eventId,
              scoreId: game.id,
              ...scoreData
            });
            return eventService.updateScore(
              Number(props.eventId),
              Number(game.id),
              scoreData
            );
          }
          
          // 새로운 게임 추가
          console.log('Adding new game in edit mode:', {
            eventId: props.eventId,
            participantId: editingScore.value.participantId,
            ...scoreData
          });
          return eventService.addScore(props.eventId, {
            ...scoreData,
            participantId: editingScore.value.participantId,
            teamNumber: editingScore.value.teamNumber
          });
        })
        .filter(Boolean);

      if (updatePromises.length > 0) {
        await Promise.all(updatePromises);
      }
    } else {
      // 신규 등록 모드 (변경 없음)
      const addPromises = editingScore.value.games
        .filter(game => game.score !== null && game.score !== undefined)
        .map(game => {
          const scoreData = {
            participantId: editingScore.value.participantId,
            teamNumber: editingScore.value.teamNumber,
            gameNumber: game.gameNumber,  
            score: Number(game.score), 
            handicap: Number(game.handicap || 0) 
          };

          console.log('Adding game:', scoreData);  
          return eventService.addScore(props.eventId, scoreData);
        });

      if (addPromises.length > 0) {
        await Promise.all(addPromises);
      }
    }

    toast.add({
      severity: 'success',
      summary: '성공',
      detail: '점수가 저장되었습니다.',
      life: 3000
    });

    hideScoreDialog();
    await fetchScores();
  } catch (error) {
    console.error('점수 저장 오류:', error);
    toast.add({
      severity: 'error',
      summary: '오류',
      detail: error.message || '점수 저장 중 오류가 발생했습니다.',
      life: 3000
    });
  }
};

const getScoreClass = (score) => {
  if (!score) return '';
  if (score >= 200) return 'text-red-600 font-bold';
  return '';
};

const scoreDialogTitle = computed(() => {
  return editingScore.value.isEdit ? '점수 수정' : '점수 등록';
});

const getTotalScore = (game) => {
  if (!game || !game.score || game.score === 0) return null;
  // 핸디캡 포함 점수가 300점을 넘지 않도록 제한
  return Math.min(game.score + (game.handicap || 0), 300);
};

const calculateTotalScore = (games) => {
  const validGames = games.filter(game => game && game.score && game.score > 0);
  if (!validGames.length) return '-';
  const total = validGames.reduce((sum, game) => sum + getTotalScore(game), 0);
  return total;
};

const calculateRawTotalScore = (games) => {
  const validGames = games.filter(game => game && game.score && game.score > 0);
  if (!validGames.length) return '-';
  const total = validGames.reduce((sum, game) => sum + game.score, 0);
  return total;
};

const calculateTotalHandicap = (games) => {
  const validGames = games.filter(game => game && game.score && game.score > 0);
  if (!validGames.length) return 0;
  const totalHandicap = validGames.reduce((sum, game) => sum + (game.handicap || 0), 0);
  return totalHandicap;
};

const calculateRawAverage = (games) => {
  const validGames = games.filter(game => game && game.score && game.score > 0);
  if (!validGames.length) return '-';
  const total = validGames.reduce((sum, game) => sum + game.score, 0);
  return (total / validGames.length).toFixed(1);
};

const calculateAverage = (games) => {
  const validGames = games.filter(game => game && game.score && game.score > 0);
  if (!validGames.length) return '-';
  const total = validGames.reduce((sum, game) => sum + getTotalScore(game), 0);
  return (total / validGames.length).toFixed(1);
};

const formatScoreWithHandicap = (game) => {
  if (!game || !game.score) return '';
  
  const handicap = game.handicap || 0;
  if (handicap === 0) return `(${game.score})`;
  if (handicap < 0) return `(${game.score}${handicap})`;
  return `(${game.score}+${handicap})`;
};

// 순위 계산함수
const calculateRanks = (groupedData) => {
  if (!groupedData || groupedData.length === 0) return {};
  
  // rankingUtils에서 사용하는 형태로 데이터 변환
  const participants = groupedData.map(item => ({
    participantId: item.participantId,
    name: item.participant.name,
    handicap: calculateTotalHandicap(item.games) / item.games.filter(g => g && g.score > 0).length || 0,
    birthday: item.participant.birthday || null
  }));
  
  // 점수 프록시 데이터 생성
  const scoresProxy = {};
  groupedData.forEach(item => {
    item.games.forEach((game, index) => {
      if (game && game.score) {
        scoresProxy[`${item.participantId}-${index + 1}`] = game.score;
      }
    });
  });
  
  // rankingUtils를 사용하여 순위 계산
  return calculateIndividualRankings(participants, scoresProxy, props.maxGames);
};

const groupedScores = computed(() => {
  if (!participants.value || !scores.value) {
    return [];
  }

  const grouped = {};
  const participantsWithScores = new Set();
  
  scores.value.forEach(score => {
    if (!grouped[score.participantId]) {
      const participant = participants.value.find(p => p.id === score.participantId);
      if (participant) {
        grouped[score.participantId] = {
          participant,
          participantId: participant.id,
          teamNumber: score.teamNumber,
          games: Array(props.maxGames).fill(null).map(() => ({ score: null, handicap: null, gameNumber: null }))
        };
        participantsWithScores.add(score.participantId);
      }
    }
    if (grouped[score.participantId]) {
      grouped[score.participantId].games[score.gameNumber - 1] = {
        id: score.id,
        score: score.score,
        handicap: score.handicap,
        gameNumber: score.gameNumber
      };
    }
  });

  const groupedArray = Object.values(grouped);
  
  // 순위 계산
  const ranks = calculateRanks(groupedArray);
  
  // 순위 정보 추가
  return groupedArray.map(item => ({
    ...item,
    rank: ranks[item.participantId] || '-'
  }));
});

// 점수 변경 시 호출
const onScoreChange = (game) => {
  if (game) {
    game.isModified = true;
    /*
    console.log('Score changed:', {
      gameNumber: game.gameNumber,
      score: game.score,
      handicap: game.handicap,
      isModified: game.isModified
    });
    */
  }
};

const deleteParticipantScores = async (data) => {
  try {
    await eventService.deleteParticipantScores(
      Number(props.eventId),
      Number(data.participant.id)
    );
    
    toast.add({
      severity: 'success',
      summary: '성공',
      detail: '점수가 삭제되었습니다.',
      life: 3000
    });

    await fetchScores();
  } catch (error) {
    console.error('점수 삭제 오류:', error);
    toast.add({
      severity: 'error',
      summary: '오류',
      detail: error.message || '점수 삭제 중 오류가 발생했습니다.',
      life: 3000
    });
  }
};

onMounted(() => {
  fetchScores();  // 참가자 목록은 여기서 가져오지 않음
});
</script>

<style scoped>
.score-management {
  padding: 1rem;
}
</style>
