<template>
  <div class="game">
    <!-- End of game modal overlay -->
    <div v-if="endModal.visible" class="end-modal-overlay" @click.self="dismissEndModal">
      <div class="end-modal">
        <button class="close-btn" @click="dismissEndModal" aria-label="Cerrar">×</button>
        <div class="title">🏁 Juego finalizado</div>
        <div class="scores">
          <div v-for="s in finalScores" :key="s.sessionId" class="score-row">
            <span class="name">{{ s.name }}</span>
            <span class="tokens">🦃 {{ s.pavo }} · 🌽 {{ s.elote }}</span>
            <span class="points">Puntos: {{ s.points }}</span>
          </div>
        </div>
        <div class="modal-actions">
          <button @click="changeToPreviousVariant" class="btn btn-prev-variant">
            ⏪ {{ getPreviousVariant() }}
          </button>
          <button @click="restartCurrentVariant" class="btn btn-restart-variant">
            🔄 {{ currentVariant }}
          </button>
          <button @click="changeToNextVariant" class="btn btn-next-variant">
            {{ getNextVariant() }} ⏩
          </button>
        </div>
        <div class="hint">Se cerrará en {{ remainingSeconds }}s</div>
      </div>
    </div>
    <div class="game-container">
      <div class="game-header">
        <h1>🧪 Demo Room</h1>
        <div class="meta">
          <div>Room: <code>{{ roomId }}</code></div>
          <div>Round: {{ currentRound }}/3</div>
          <div>Status: <span class="badge">{{ gameStatus }}</span></div>
        </div>
        <div class="variant-selector">
          <button v-for="g in variants" :key="g" @click="setVariant(g)" :class="['btn', 'btn-variant', { active: currentVariant === g }]">
            {{ g }}
          </button>
        </div>
      </div>

      <div class="players-section">
        <PlayerStats v-for="p in players" :key="p.sessionId" :player="p" :highlight="p.sessionId === sessionId" />
      </div>

      <div v-if="gameStatus === 'waiting'" class="waiting-area">
        <div class="waiting-message">
          <div class="spinner"></div>
          <h2>Waiting for opponent...</h2>
          <p>Players in room: {{ players.length }}/2</p>
        </div>
      </div>

      <div v-else class="gameplay">
        <component :is="currentComponent"
                   :state="roundState"
                   :my-role="myRole"
                   :players="players"
                   @p2Force="onP2Force"
                   @p1Action="onP1Action"
                   @p2Action="onP2Action"
                   @report="onReport"
                   @assignShame="onAssignShame"
                   @proposeOffer="onProposeOffer"
        />

        <div class="outcome" v-if="outcomeP1 || outcomeP2">
          <div class="outcome-box">
            <div>Outcome P1: <strong>{{ outcomeP1 }}</strong></div>
            <div>Outcome P2: <strong>{{ outcomeP2 }}</strong></div>
          </div>
        </div>
      </div>

      <ChatWidget />

      <div class="game-footer">
        <button @click="leaveGame" class="btn btn-leave">Leave Game</button>
      </div>
    </div>

    <!-- Pause overlay to block all interactions -->
    <div v-if="gameStatus === 'paused'" class="pause-overlay">
      <div class="pause-box">
        <div class="icon">⏸️</div>
        <div class="title">Juego en pausa</div>
        <div class="hint">Esperando a que ambos jugadores estén conectados…</div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { colyseusService } from '../services/colyseus';
import { getStateCallbacks } from 'colyseus.js';

import G1 from './games/G1.vue';
import G2 from './games/G2.vue';
import G3 from './games/G3.vue';
import G4 from './games/G4.vue';
import G5 from './games/G5.vue';
import PlayerStats from './games/PlayerStats.vue';
import ChatWidget from './games/ChatWidget.vue';

const router = useRouter();
const route = useRoute();
const routeUuid = computed(() => (route.params as any)?.uuid as string || '');

const players = ref<any[]>([]);
const gameStatus = ref('waiting');
const roomId = ref('');
const currentVariant = ref<'G1'|'G2'|'G3'|'G4'|'G5'>('G1');
const currentRound = ref(1);
const p1Action = ref('');
const p2Action = ref('');
const forcedByP2 = ref(false);
const reported = ref(false);
const shameAssigned = ref(false);
const outcomeP1 = ref(0);
const outcomeP2 = ref(0);

const variants = ['G1','G2','G3','G4','G5'];

// End-of-game modal state and helpers
const endModal = ref<{ visible: boolean }>({ visible: false });
const remainingSeconds = ref(20);
let endTimerTimeout: any = null;
let endTimerInterval: any = null;

function showEndModal() {
  // Prevent multiple timers
  if (endModal.value.visible) return;
  endModal.value.visible = true;
  remainingSeconds.value = 20;
  if (endTimerInterval) clearInterval(endTimerInterval);
  if (endTimerTimeout) clearTimeout(endTimerTimeout);
  endTimerInterval = setInterval(() => {
    remainingSeconds.value = Math.max(0, remainingSeconds.value - 1);
  }, 1000);
  endTimerTimeout = setTimeout(() => {
    dismissEndModal();
  }, 20000);
}

function dismissEndModal() {
  endModal.value.visible = false;
  if (endTimerInterval) { clearInterval(endTimerInterval); endTimerInterval = null; }
  if (endTimerTimeout) { clearTimeout(endTimerTimeout); endTimerTimeout = null; }
}

// Function to get next variant in sequence
function getNextVariant(): string {
  const currentIndex = variants.indexOf(currentVariant.value);
  const nextIndex = (currentIndex + 1) % variants.length;
  return variants[nextIndex];
}

// Function to get previous variant in sequence
function getPreviousVariant(): string {
  const currentIndex = variants.indexOf(currentVariant.value);
  const previousIndex = (currentIndex - 1 + variants.length) % variants.length;
  return variants[previousIndex];
}

// Function to change to next variant and dismiss modal
function changeToNextVariant() {
  const nextVariant = getNextVariant();
  setVariant(nextVariant);
  dismissEndModal();
}

// Function to change to previous variant and dismiss modal
function changeToPreviousVariant() {
  const previousVariant = getPreviousVariant();
  setVariant(previousVariant);
  dismissEndModal();
}

// Function to restart the same variant and dismiss modal
function restartCurrentVariant() {
  setVariant(currentVariant.value);
  dismissEndModal();
}

const finalScores = computed(() => {
  return players.value.map(p => {
    const points = (p.role === 'P2')
      ? (p.eloteTokens || 0) * 1 + (p.pavoTokens || 0) * 2
      : (p.pavoTokens || 0) * 1 + (p.eloteTokens || 0) * 2;
    return {
      sessionId: p.sessionId,
      name: p.name,
      pavo: p.pavoTokens || 0,
      elote: p.eloteTokens || 0,
      points
    };
  }).sort((a, b) => b.points - a.points);
});

// Round transition banner state and helper
const roundBanner = ref<{ visible: boolean; text: string; kind: 'start'|'end' }>({ visible: false, text: '', kind: 'start' });
let roundBannerTimeout: any = null;

function showRoundBanner(text: string, kind: 'start'|'end', ms = 1400) {
  if (roundBannerTimeout) { clearTimeout(roundBannerTimeout); roundBannerTimeout = null; }
  roundBanner.value = { visible: true, text, kind };
  roundBannerTimeout = setTimeout(() => { roundBanner.value.visible = false; }, ms);
}

const sessionId = computed(() => colyseusService.sessionId.value);
const myRole = computed(() => {
  const me = players.value.find(p => p.sessionId === sessionId.value);
  return me?.role || '';
});

  const roundState = computed(() => ({
    currentVariant: currentVariant.value,
    currentRound: currentRound.value,
    p1Action: p1Action.value,
    p2Action: p2Action.value,
    forcedByP2: forcedByP2.value,
    reported: reported.value,
    shameAssigned: shameAssigned.value,
    offer: {
      offerPavo: roomOffer('offerPavo'),
      offerElote: roomOffer('offerElote'),
      requestPavo: roomOffer('requestPavo'),
      requestElote: roomOffer('requestElote'),
      active: roomOffer('offerActive')
    }
  }));

const componentMap: Record<string, any> = { G1, G2, G3, G4, G5 };
const currentComponent = computed(() => componentMap[currentVariant.value]);

onMounted(() => {
  let room = colyseusService.gameRoom.value;
  if (!room) {
    router.push(`/${routeUuid.value}`);
    return;
  }

  setupRoom(room);

  function setupRoom(room: any) {
  const $ = getStateCallbacks(room);

  room.onStateChange.once((state: any) => {
    gameStatus.value = state.gameStatus || 'waiting';
  });

  $(room.state).listen("gameStatus", (value: string) => { 
    gameStatus.value = value; 
    if ((value || '').toLowerCase() === 'finished') {
      showEndModal();
    }
  });
  $(room.state).listen("roomId", (value: string) => { roomId.value = value; });
  $(room.state).listen("currentVariant", (value: string) => { currentVariant.value = value as any; });
  $(room.state).listen("currentRound", (value: number) => { currentRound.value = value; });
  $(room.state).listen("p1Action", (value: string) => { p1Action.value = value; });
  $(room.state).listen("p2Action", (value: string) => { p2Action.value = value; });
  $(room.state).listen("forcedByP2", (value: boolean) => { forcedByP2.value = value; });
  $(room.state).listen("reported", (value: boolean) => { reported.value = value; });
  $(room.state).listen("shameAssigned", (value: boolean) => { shameAssigned.value = value; });
  // Offer fields
  $(room.state).listen("offerPavo", () => forceUpdate());
  $(room.state).listen("offerElote", () => forceUpdate());
  $(room.state).listen("requestPavo", () => forceUpdate());
  $(room.state).listen("requestElote", () => forceUpdate());
  $(room.state).listen("offerActive", () => forceUpdate());

  $(room.state).players.onAdd((player: any, key: string) => {
    const idx = players.value.findIndex(p => p.sessionId === key);
    if (idx === -1) {
      players.value.push({
        sessionId: key,
        name: player.name,
        role: player.role,
        pavoTokens: player.pavoTokens,
        eloteTokens: player.eloteTokens,
        shameTokens: player.shameTokens,
        color: player.color,
      });
    }
    $(player).listen("role", (v: string) => { const p = players.value.find(x => x.sessionId === key); if (p) p.role = v; });
    $(player).listen("pavoTokens", (v: number) => { const p = players.value.find(x => x.sessionId === key); if (p) p.pavoTokens = v; });
    $(player).listen("eloteTokens", (v: number) => { const p = players.value.find(x => x.sessionId === key); if (p) p.eloteTokens = v; });
    $(player).listen("shameTokens", (v: number) => { const p = players.value.find(x => x.sessionId === key); if (p) p.shameTokens = v; });
    $(player).listen("color", (v: string) => { const p = players.value.find(x => x.sessionId === key); if (p) p.color = v; });
  });
  $(room.state).players.onRemove((_: any, key: string) => {
    const i = players.value.findIndex(p => p.sessionId === key);
    if (i !== -1) players.value.splice(i, 1);
  });

  room.onMessage("playerInfo", (info: any) => {
    colyseusService.sessionId.value = info.sessionId;
    colyseusService.playerName.value = info.name;
  });

  room.onMessage("gameEnd", () => { showEndModal(); });

  // Register additional message handlers to avoid warnings
  room.onMessage("gamePaused", () => {
    // Game paused, could update UI state if needed
  });

  room.onMessage("gameRestart", () => {
    // Game restarted, could update UI state if needed
  });

  room.onMessage("variantChanged", (data: { variant: string }) => {
    currentVariant.value = data.variant as any;
    // Close end modal if it's open when variant changes
    if (endModal.value.visible) {
      dismissEndModal();
    }
  });

  // No round transition banners

  // Handle room closure/disconnection
  room.onLeave((code: number) => {
    console.log('[DemoGame] Room disconnected with code:', code);
    
    // Handle shuffle disconnection specially
    if (code === 1002) {
      console.log('[DemoGame] Disconnected for player shuffle - will redirect to lobby');
      try { 
        if (typeof window !== 'undefined') { 
          window.localStorage.removeItem('snatch.game.roomId'); 
          window.localStorage.removeItem('snatch.game.sessionId'); 
        } 
      } catch {}
      
      // Redirect to lobby and let it handle the shuffle redirect
      router.push(`/${routeUuid.value}`);
      return;
    }
    
    // Normal disconnection handling
    // Always clean up local storage when room closes
    // no-op for local storage cleanup
    
    // If not on lobby page, redirect there
    if (router.currentRoute.value.path !== `/${routeUuid.value}`) {
      console.log('[DemoGame] Room closed, redirecting to lobby');
      router.push(`/${routeUuid.value}`);
    }
  });

  room.onError((code: number, message: any) => {
    console.error('[DemoGame] Room error:', code, message);
    // On error, redirect to lobby
    router.push(`/${routeUuid.value}`);
  });
  }
});

function roomOffer<K extends string>(key: K): any {
  const room = colyseusService.gameRoom.value as any;
  return room?.state?.[key as any];
}

const refreshTick = ref(0);
function forceUpdate() { refreshTick.value++; }

function setVariant(g: string) { colyseusService.setVariant(g); }
function onP2Force(force: boolean) { colyseusService.p2Force(force); }
function onP1Action(action: 'no_offer') { colyseusService.noOffer(); }
function onProposeOffer(payload: { offerPavo:number; offerElote:number; requestPavo:number; requestElote:number; }) { colyseusService.proposeOffer(payload.offerPavo, payload.offerElote, payload.requestPavo, payload.requestElote); }
function onP2Action(action: 'accept'|'reject'|'snatch') { colyseusService.p2Action(action); }
function onReport(val: boolean) { colyseusService.report(val); }
function onAssignShame(val: boolean) { colyseusService.assignShame(val); }

async function leaveGame() { 
  // Ask for confirmation before closing the room for both players
  if (!confirm('¿Cerrar la sala para ambos jugadores? Esto terminará el juego inmediatamente.')) {
    return;
  }
  
  console.log('[DemoGame] User closing room for both players');
  
  try {
    // Close the room for both players using the admin API
    const response = await fetch(`${import.meta.env.VITE_API_URL || 'http://localhost:3000/api'}/rooms/${roomId.value}/close`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' }
    });
    
    if (!response.ok) {
      console.error('Failed to close room via API');
      // Fallback to normal leave if API fails
      colyseusService.leaveGame();
    } else {
      console.log(`Room ${roomId.value} closed successfully for both players`);
      // Just leave locally, the server will handle disconnecting both players
      if (colyseusService.gameRoom.value) {
        colyseusService.gameRoom.value.leave();
      }
    }
  } catch (error) {
    console.error('Error closing room:', error);
    // Fallback to normal leave if error occurs
    colyseusService.leaveGame();
  }
  
  // Navigate back to lobby
  router.push(`/${routeUuid.value}`);
}
</script>

<style scoped>
.game { min-height: 100vh; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); display:flex; align-items:center; justify-content:center; padding:20px; }
.end-modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.55); display:flex; align-items:center; justify-content:center; z-index: 1200; }
.end-modal { position: relative; background: white; color:#111; border-radius: 16px; padding: 24px 24px 18px; width: min(520px, 92vw); box-shadow: 0 30px 80px rgba(0,0,0,0.5); border:1px solid #e5e7eb; }
.end-modal .close-btn { position:absolute; top:8px; right:8px; width:32px; height:32px; border-radius: 8px; border:1px solid #e5e7eb; background:#f8fafc; color:#111; font-weight:800; cursor:pointer; }
.end-modal .close-btn:hover { background:#eef2ff; }
.end-modal .title { font-size: 20px; font-weight: 900; margin-bottom: 8px; }
.end-modal .scores { display:flex; flex-direction:column; gap:8px; margin: 8px 0 12px; }
.end-modal .score-row { display:flex; align-items:center; justify-content:space-between; gap:8px; background:#f8fafc; border:1px solid #e5e7eb; border-radius: 10px; padding:8px 10px; }
.end-modal .score-row .name { font-weight:800; color:#1f2937; }
.end-modal .score-row .tokens { font-weight:700; color:#374151; }
.end-modal .score-row .points { font-weight:900; color:#111827; }
.end-modal .modal-actions { 
  margin: 16px 0; 
  display: flex; 
  gap: 12px; 
  justify-content: center; 
  align-items: center;
}
.end-modal .btn-next-variant, .end-modal .btn-prev-variant, .end-modal .btn-restart-variant { 
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 
  color: white; 
  border: none; 
  padding: 12px 16px; 
  border-radius: 8px; 
  font-size: 14px; 
  font-weight: 600; 
  cursor: pointer; 
  transition: all 0.3s ease;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
  min-width: 85px;
}
.end-modal .btn-prev-variant {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  box-shadow: 0 4px 12px rgba(240, 147, 251, 0.3);
}
.end-modal .btn-restart-variant {
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  box-shadow: 0 4px 12px rgba(79, 172, 254, 0.3);
}
.end-modal .btn-next-variant:hover { 
  transform: translateY(-2px); 
  box-shadow: 0 6px 16px rgba(102, 126, 234, 0.4);
}
.end-modal .btn-prev-variant:hover { 
  transform: translateY(-2px); 
  box-shadow: 0 6px 16px rgba(240, 147, 251, 0.4);
}
.end-modal .btn-restart-variant:hover { 
  transform: translateY(-2px); 
  box-shadow: 0 6px 16px rgba(79, 172, 254, 0.4);
}
.end-modal .hint { font-size: 12px; color:#6b7280; text-align:right; }
.game-container { background: white; border-radius: 20px; padding: 24px; max-width: 1000px; width: 100%; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }
.game-header { display:flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.game-header h1 { margin: 0; font-size: 20px; }
.meta { display:flex; gap: 16px; font-size: 14px; }
.badge { background:#e3f2fd; color:#2196f3; padding: 2px 8px; border-radius: 12px; font-size: 12px; }
.variant-selector { display:flex; gap: 8px; flex-wrap: wrap; }
.btn { padding: 8px 12px; border-radius: 8px; border: none; cursor: pointer; }
.btn-variant { background: #f2f2f2; }
.btn-variant.active { background: #667eea; color: white; }
.btn-next { background:#2196f3; color:white; margin-top: 12px; }
.btn-leave { background:#f44336; color:white; }
.players-section { display:grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; margin: 12px 0; }
.player-card { padding: 12px; background:#f8f9fa; border-radius: 10px; }
.player-role { color:#666; margin-top: 4px; }
.player-tokens { display:flex; gap: 12px; margin-top: 8px; }
.waiting-area { text-align:center; padding: 24px 0; }
.spinner { width:40px; height:40px; border: 4px solid #eee; border-top:4px solid #667eea; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto 8px; }
@keyframes spin { 0%{transform:rotate(0)} 100%{transform:rotate(360deg)} }
.outcome-box { display:flex; gap: 24px; background:#f5f5f5; padding: 12px; border-radius: 8px; }

/* Full-screen overlay while paused */
.pause-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.55); display:flex; align-items:center; justify-content:center; z-index: 1000; }
.pause-box { background: white; color:#333; border-radius: 16px; padding: 24px 32px; text-align: center; box-shadow: 0 20px 60px rgba(0,0,0,0.4); }
.pause-box .icon { font-size: 48px; margin-bottom: 8px; }
.pause-box .title { font-weight: 800; font-size: 20px; }
.pause-box .hint { margin-top: 6px; color:#666; font-size: 14px; }
</style>
