<script setup lang="ts">
import { ref, onMounted } from "vue";
import RankBadge from "./RankBadge.vue";

interface User {
  id: number;
  username: string;
  is_staff: boolean,
  first_name?: string;
  last_name?: string;
}

interface PointsFactor {
  cost: number;
  cycles: number;
  area: number;
}

interface Puzzle {
  id: number;
  title: string;
  points_factor?: PointsFactor;
}

interface PuzzleResponse {
  id: number;
  puzzle_id: number;
  submission_id: string;
  cost?: number;
  cycles?: number;
  area?: number;
  rank_points?: number;
}

interface PuzzleRanking {
  id: number;
  puzzle_id: number;
  user_id: number;
  final_cost?: number;
  final_cycles?: number;
  final_area?: number;
  points?: number;
  rank_points?: number;
}

interface ResultsData {
  users: User[];
  puzzles: Puzzle[];
  responses_by_userid: Record<number, PuzzleResponse[]>;
  ranking_by_puzzle: Record<number, PuzzleRanking[]>;
}

const isLoading = ref(true);
const resultsData = ref<ResultsData | null>(null);
const selectedTab = ref<"overall" | "byPuzzle">("overall");
const expandedPuzzleId = ref<number | null>(null);
const userInfo = ref({
  username: "Player",
  rank: null as number | null,
  totalPoints: 0,
  puzzlesSolved: 0,
  isStaff: false,
});

const fetchResults = async () => {
  isLoading.value = true;
  try {
    const response = await fetch("/api/results/results");
    if (!response.ok) throw new Error("Failed to fetch results");

    resultsData.value = await response.json();
  } catch (error) {
    console.error("Error fetching results:", error);
  } finally {
    isLoading.value = false;
  }
};

const getOverallRanking = () => {
  if (!resultsData.value) return [];

  const userScores = resultsData.value.users.map((user) => {
    const responses = resultsData.value!.responses_by_userid[user.id] || [];
    const totalPoints = responses.reduce((sum, r) => sum + (r.rank_points || 0), 0);
    const count = responses.length;

    return {
      user: user,
      totalPoints,
      puzzlesSolved: count,
    };
  });

  return userScores.sort((a, b) => b.totalPoints - a.totalPoints);
};

const getPuzzleRanking = (puzzleId: number) => {
  if (!resultsData.value) return [];

  const ranking = resultsData.value.ranking_by_puzzle[puzzleId] || [];
  return ranking.map((response) => {
    const user = resultsData.value!.users.find((u) => u.id === response.user_id) as User;
    return {
      user: user,
      cost: response.final_cost,
      cycles: response.final_cycles,
      area: response.final_area,
      points: response.points,
      rank_points: response.rank_points || 0,
    };
  }).reverse();
};

const togglePuzzleExpanded = (puzzleId: number) => {
  expandedPuzzleId.value = expandedPuzzleId.value === puzzleId ? null : puzzleId;
};

const clearCache = async () => {
  try {
    const response = await fetch("/api/cache/clear", {
      method: "POST",
    });

    if (response.ok) {
      alert("Cache cleared successfully!");
      await fetchResults();
    } else {
      const error = await response.json();
      alert(`Error clearing cache: ${error.detail || "Unknown error"}`);
    }
  } catch (error) {
    console.error("Error clearing cache:", error);
    alert("Error clearing cache. Please try again.");
  }
};

const loadUserData = async () => {
  try {
    const response = await fetch("/api/user");
    if (response.ok) {
      const user = await response.json();
      if (user.is_authenticated) {
        userInfo.value.username = user.username;
        userInfo.value.isStaff = user.is_staff || false;

        await fetchResults();

        // Calculate user's rank and stats
        const ranking = getOverallRanking();
        const userRankIndex = ranking.findIndex((u) => u.user.id === user.id);

        if (userRankIndex !== -1) {
          userInfo.value.rank = userRankIndex + 1;
          userInfo.value.totalPoints = ranking[userRankIndex].totalPoints;
          userInfo.value.puzzlesSolved = ranking[userRankIndex].puzzlesSolved;
        }
      }
    }
  } catch (error) {
    console.error("Error loading user data:", error);
    await fetchResults();
  }
};

onMounted(() => {
  loadUserData();
});
</script>

<template>
  <div class="mb-8">
    <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
      <!-- Left Column: Your Ranking -->
      <div class="lg:col-span-1">
        <div class="card bg-base-100 shadow-lg sticky top-8">
          <div class="bg-gradient-to-br from-purple-600 to-purple-400 p-6 text-white rounded-t-2xl">
            <h3 class="text-3xl font-bold">
              <i class="mdi mdi-trophy text-3xl"></i>
              Your Ranking
            </h3>
          </div>
          <div class="card-body">
            <div class="text-center mb-6">
              <p class="text-sm text-base-content/70">Player</p>
              <p class="text-3xl font-bold">{{ userInfo.username }}</p>
            </div>

            <div class="divider"></div>

            <div v-if="isLoading" class="flex justify-center py-8">
              <span class="loading loading-spinner loading-lg"></span>
            </div>

            <div v-else class="space-y-4">
              <div class="text-center">
                <p class="text-sm text-base-content/70 mb-1">Current Rank</p>
                <p v-if="userInfo.rank !== null" class="text-4xl font-bold text-primary">
                  <RankBadge :rank="userInfo.rank" />
                </p>
                <p v-else class="text-2xl text-base-content/50">No rank yet</p>
              </div>

              <div class="text-center">
                <p class="text-sm text-base-content/70 mb-1">Total Points</p>
                <p class="text-2xl font-bold">{{ userInfo.totalPoints.toLocaleString() }}</p>
              </div>

              <div class="text-center">
                <p class="text-sm text-base-content/70 mb-1">Puzzles Solved</p>
                <p class="text-2xl font-bold">{{ userInfo.puzzlesSolved }}</p>
              </div>

              <button v-if="userInfo.isStaff" @click="clearCache" class="btn btn-error btn-sm w-full mt-6">
                <i class="mdi mdi-cache-clear mr-1"></i>
                Clear Cache
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- Right Column: Results -->
      <div class="lg:col-span-2">
        <div class="card bg-base-100 shadow-lg">
          <div class="card-body">
            <h2 class="card-title text-2xl mb-6">
              <i class="mdi mdi-trophy text-yellow-500 mr-2"></i>
              General Results
            </h2>

            <div v-if="isLoading" class="flex justify-center py-8">
              <span class="loading loading-spinner loading-lg"></span>
            </div>

            <div v-else-if="!resultsData" class="text-center py-8">
              <p class="text-base-content/70">No results available yet</p>
            </div>

            <div v-else class="space-y-6">
              <!-- Tabs -->
              <div class="tabs tabs-border">
                <button @click="selectedTab = 'overall'" :class="[
                  'tab',
                  selectedTab === 'overall' ? 'tab-active' : '',
                ]">
                  <i class="mdi mdi-chart-line mr-2"></i>
                  Overall Ranking
                </button>
                <button @click="selectedTab = 'byPuzzle'" :class="[
                  'tab',
                  selectedTab === 'byPuzzle' ? 'tab-active' : '',
                ]">
                  <i class="mdi mdi-puzzle mr-2"></i>
                  By Puzzle
                </button>
              </div>

              <!-- Overall Ranking -->
              <div v-show="selectedTab === 'overall'" class="space-y-4">
                <div v-if="getOverallRanking().length === 0" class="text-center py-8">
                  <p class="text-base-content/70">No submissions yet</p>
                </div>

                <div v-else class="overflow-x-auto">
                  <table class="table table-zebra w-full">
                    <thead>
                      <tr>
                        <th>Rank</th>
                        <th>Player</th>
                        <th class="text-right">Puzzles Solved</th>
                        <th class="text-right">Total Points</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr v-for="(ranking, index) in getOverallRanking()" :key="ranking.user.username">
                        <td class="font-bold">
                          <RankBadge :rank="index + 1" />
                        </td>
                        <td class="font-medium">
                          {{ ranking.user.username }}
                          <span v-if="ranking.user.is_staff" class="badge badge-warning">
                            admin
                          </span>
                        </td>
                        <td class="text-right">{{ ranking.puzzlesSolved }}</td>
                        <td class="text-right font-bold">{{ ranking.totalPoints }}</td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              </div>

              <!-- By Puzzle Ranking -->
              <div v-show="selectedTab === 'byPuzzle'" class="space-y-6">
                <div v-for="puzzle in resultsData.puzzles" :key="puzzle.id"
                  class="card bg-base-100 border border-base-300">
                  <button @click="togglePuzzleExpanded(puzzle.id)"
                    class="btn btn-ghost btn-lg w-full justify-start text-lg font-bold hover:bg-primary/20 rounded-b-none">
                    <i
                      :class="['mdi mr-2', expandedPuzzleId === puzzle.id ? 'mdi-chevron-down' : 'mdi-chevron-right']"></i>
                    {{ puzzle.title }}
                    <span class="ml-auto badge badge-sm">
                      {{ getPuzzleRanking(puzzle.id).length }} submissions
                    </span>
                  </button>

                  <!-- Expanded Details -->
                  <div v-if="expandedPuzzleId === puzzle.id" class="card-body">
                    <div v-if="getPuzzleRanking(puzzle.id).length === 0" class="text-center py-8">
                      <p class="text-base-content/70 text-lg">No submissions yet</p>
                    </div>

                    <div v-else class="space-y-6">
                      <!-- Points Factor Info -->
                      <div v-if="puzzle.points_factor" class="bg-base-200 p-4 rounded-lg">
                        <p class="text-sm text-base-content/70 mb-3 font-semibold">Points Coefficients</p>
                        <div class="grid grid-cols-3 gap-4">
                          <div class="text-center">
                            <span class="text-2xl font-bold text-primary"><small>x</small>{{ puzzle.points_factor.cost
                            }}</span>
                            <p class="text-xs text-base-content/70">Cost</p>
                          </div>
                          <div class="text-center">
                            <span class="text-2xl font-bold text-primary"><small>x</small>{{ puzzle.points_factor.cycles
                              }}</span>
                            <p class="text-xs text-base-content/70">Cycles</p>
                          </div>
                          <div class="text-center">
                            <span class="text-2xl font-bold text-primary"><small>x</small>{{ puzzle.points_factor.area
                              }}</span>
                            <p class="text-xs text-base-content/70">Area</p>
                          </div>
                        </div>
                      </div>

                      <!-- Top 3 Podium -->
                      <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
                        <div v-for="(response, index) in getPuzzleRanking(puzzle.id).slice(0, 3)" :key="index"
                          class="card bg-base-200">
                          <div class="card-body p-4">
                            <div class="text-xs text-base-content/70 font-bold">
                              {{ index === 0 ? '🏆 1st Place' : index === 1 ? '🥈 2nd Place' : '🥉 3rd Place' }}
                            </div>
                            <h4 class="font-bold text-lg">
                              {{ response.user.username }}
                              <span v-if="response.user.is_staff" class="badge badge-warning">
                                admin
                              </span>
                            </h4>
                            <div class="divider my-2"></div>
                            <div class="space-y-2 text-sm">
                              <div class="flex justify-between">
                                <span>Cost<span v-if="puzzle.points_factor" class="text-xs text-base-content/60">
                                    (x{{ puzzle.points_factor.cost }})
                                  </span></span>
                                <span class="badge badge-sm">{{ response.cost || 'N/A' }}</span>
                              </div>
                              <div class="flex justify-between">
                                <span>Cycles<span v-if="puzzle.points_factor" class="text-xs text-base-content/60">
                                    (x{{ puzzle.points_factor.cycles }})
                                  </span></span>
                                <span class="badge badge-sm">{{ response.cycles || 'N/A' }}</span>
                              </div>
                              <div class="flex justify-between">
                                <span>Area<span v-if="puzzle.points_factor" class="text-xs text-base-content/60">
                                    (x{{ puzzle.points_factor.area }})
                                  </span></span>
                                <span class="badge badge-sm">{{ response.area || 'N/A' }}</span>
                              </div>
                              <div class="flex justify-between pt-2 border-t">
                                <span>Total (with coef.)</span>
                                <span class="badge badge-sm">{{ response.points || 'N/A' }}</span>
                              </div>
                              <div class="flex justify-between pt-2 border-t">
                                <span class="font-bold">Points</span>
                                <span class="badge badge-primary">{{ response.rank_points }} pts</span>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>

                      <!-- Full Ranking Table -->
                      <div class="overflow-x-auto">
                        <table class="table table-zebra w-full table-sm">
                          <thead>
                            <tr>
                              <th class="w-12">Rank</th>
                              <th>Player</th>
                              <th class="text-center">
                                Cost
                                <span v-if="puzzle.points_factor" class="text-xs text-base-content/60 block">(x{{
                                  puzzle.points_factor.cost }})</span>
                              </th>
                              <th class="text-center">
                                Cycles
                                <span v-if="puzzle.points_factor" class="text-xs text-base-content/60 block">(x{{
                                  puzzle.points_factor.cycles }})</span>
                              </th>
                              <th class="text-center">
                                Area
                                <span v-if="puzzle.points_factor" class="text-xs text-base-content/60 block">(x{{
                                  puzzle.points_factor.area }})</span>
                              </th>
                              <th class="text-center">Total (with coef.)</th>
                              <th class="text-right">Points</th>
                            </tr>
                          </thead>
                          <tbody>
                            <tr v-for="(response, index) in getPuzzleRanking(puzzle.id)" :key="index"
                              :class="{ 'bg-primary/10': index < 3 }">
                              <td class="font-bold">
                                <span v-if="index === 0" class="badge badge-warning">🏆</span>
                                <span v-else-if="index === 1" class="badge">🥈</span>
                                <span v-else-if="index === 2" class="badge">🥉</span>
                                <span v-else>#{{ index + 1 }}</span>
                              </td>
                              <td class="font-medium">{{ response.user.username }}</td>
                              <td class="text-center">
                                <span v-if="response.cost" class="badge badge-sm">{{ response.cost }}</span>
                                <span v-else class="text-base-content/40">—</span>
                              </td>
                              <td class="text-center">
                                <span v-if="response.cycles" class="badge badge-sm">{{ response.cycles }}</span>
                                <span v-else class="text-base-content/40">—</span>
                              </td>
                              <td class="text-center">
                                <span v-if="response.area" class="badge badge-sm">{{ response.area }}</span>
                                <span v-else class="text-base-content/40">—</span>
                              </td>
                              <td class="text-center">
                                <span v-if="response.points" class="badge badge-sm">{{ response.points }}</span>
                                <span v-else class="text-base-content/40">—</span>
                              </td>
                              <td class="text-right font-bold text-primary text-lg">{{ response.rank_points }}</td>
                            </tr>
                          </tbody>
                        </table>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
