<script lang="ts">
  import { goto } from "$app/navigation";
  import { getSocket } from "$lib/socket";
  import {
    gameState,
    isTutorial,
    myPlayerId,
    playerName,
  } from "$lib/stores/game";
  import { onDestroy } from "svelte";
  import { get } from "svelte/store";

  const socket = getSocket();

  const TUTORIAL_DUMMY_ID = "tutorial_dummy";

  // ── Objective definitions ─────────────────────────────────────────────────
  interface Objective {
    id: string;
    label: string;
    hint: string;
    done: boolean;
  }

  const HINT_DELAY_MS = 25_000; // show hint after 25s of no progress

  let objectives: Objective[] = [
    {
      id: "gather",
      label: "Start gathering resources",
      hint: 'Type "gather minerals" or "gather" to send your SCVs to mine the nearest mineral patch.',
      done: false,
    },
    {
      id: "scvs",
      label: "Train 3 SCVs",
      hint: 'You start with 5 SCVs. Type "train 3 scv" in the command box below to train more from your Command Center.',
      done: false,
    },
    {
      id: "supply_depot",
      label: "Build a Supply Depot",
      hint: 'Type "build supply depot" — an SCV will construct it near your base. You need it before training Marines!',
      done: false,
    },
    {
      id: "barracks",
      label: "Build a Barracks",
      hint: 'Type "build barracks". Marines require a Barracks to be trained.',
      done: false,
    },
    {
      id: "marines",
      label: "Train 2 Marines",
      hint: 'Once your Barracks is ready, type "train 2 marines" to deploy your infantry.',
      done: false,
    },
    {
      id: "move",
      label: "Move units to the Ashen Crater",
      hint: 'Type "move all units to the Ashen Crater".',
      done: false,
    },
  ];

  // Tutorial always starts with 5 SCVs — objective is to train 3 more (total ≥ 8)
  const STARTING_SCV_COUNT = 5;

  // ── One derived boolean per objective (no circular dependency) ───────────
  $: _player = $myPlayerId ? ($gameState?.players[$myPlayerId] ?? null) : null;
  $: _units = _player ? Object.values(_player.units) : [];
  $: _buildings = _player ? Object.values(_player.buildings) : [];

  $: doneGather = _units.some(
    (u) =>
      u.unit_type === "scv" &&
      (u.status === "mining_minerals" || u.status === "mining_gas"),
  );
  $: doneSCVs =
    _units.filter((u) => u.unit_type === "scv").length >=
    STARTING_SCV_COUNT + 3;
  $: doneSupplyDepot = _buildings.some(
    (b) => b.building_type === "supply_depot" && b.status !== "destroyed",
  );
  $: doneBarracks = _buildings.some(
    (b) => b.building_type === "barracks" && b.status !== "destroyed",
  );
  $: doneMArines = _units.filter((u) => u.unit_type === "marine").length >= 2;
  $: doneMove = (() => {
    const tx = $gameState?.tutorial_target_x;
    const ty = $gameState?.tutorial_target_y;
    if (tx == null || ty == null) return false;
    return _units.some((u) => Math.hypot(u.x - tx, u.y - ty) < 12);
  })();

  // Once an objective is done it stays done — locked permanently
  const OBJECTIVE_IDS = [
    "gather",
    "scvs",
    "supply_depot",
    "barracks",
    "marines",
    "move",
  ] as const;
  // lockedCount is a plain reactive number so $: allDone re-evaluates reliably
  let lockedCount = 0;

  let doneMap: Record<string, boolean> = {};
  $: {
    const fresh: Record<string, boolean> = {
      gather: doneGather,
      scvs: doneSCVs,
      supply_depot: doneSupplyDepot,
      barracks: doneBarracks,
      marines: doneMArines,
      move: doneMove,
    };
    let changed = false;
    for (const id of OBJECTIVE_IDS) {
      if (fresh[id] && !doneMap[id]) {
        doneMap[id] = true;
        changed = true;
      }
    }
    if (changed) {
      doneMap = { ...doneMap };
      lockedCount = OBJECTIVE_IDS.filter((id) => doneMap[id]).length;
    }
  }

  // Hint state
  let activeHintId: string | null = null;
  let hintTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();
  let shownHints: Set<string> = new Set();

  // Tutorial completion — driven by lockedCount so Svelte tracks it correctly
  $: allDone = lockedCount === OBJECTIVE_IDS.length;

  let completionReported = false;
  $: if (allDone && !completionReported) {
    completionReported = true;
    socket.emit("tutorial_complete", {});
    const pName = get(playerName);
    if (pName) {
      localStorage.setItem("sc_player_name", pName);
      localStorage.setItem("sc_name_locked", "true");
    }
  }

  // ── Side-effects: schedule/clear hints when done states change ───────────
  $: {
    for (const obj of objectives) {
      const nowDone = doneMap[obj.id] ?? false;
      if (nowDone) {
        clearHintTimer(obj.id);
        if (activeHintId === obj.id) activeHintId = null;
      } else {
        scheduleHintIfNeeded(obj.id);
      }
    }
  }

  function scheduleHintIfNeeded(id: string) {
    if (shownHints.has(id)) return;
    if (hintTimers.has(id)) return;
    // Only show hint if all previous objectives are completed
    const idx = (OBJECTIVE_IDS as readonly string[]).indexOf(id);
    if (idx > 0 && (OBJECTIVE_IDS as readonly string[]).slice(0, idx).some((prevId) => !doneMap[prevId])) return;
    const t = setTimeout(() => {
      hintTimers.delete(id);
      if (!doneMap[id] && !shownHints.has(id)) {
        activeHintId = id;
      }
    }, HINT_DELAY_MS);
    hintTimers.set(id, t);
  }

  function clearHintTimer(id: string) {
    const t = hintTimers.get(id);
    if (t !== undefined) {
      clearTimeout(t);
      hintTimers.delete(id);
    }
  }

  function dismissHint() {
    const dismissedId = activeHintId;
    activeHintId = null;
    if (dismissedId !== null) {
      shownHints.add(dismissedId);
    }
  }

  function backToLobby() {
    isTutorial.set(false);
    gameState.set(null);
    goto("/");
  }

  onDestroy(() => {
    hintTimers.forEach((t) => clearTimeout(t));
    hintTimers.clear();
  });

  let panelCollapsed = false;

  $: currentObjectiveIndex = objectives.findIndex((o) => !doneMap[o.id]);
  $: activeHint = activeHintId
    ? objectives.find((o) => o.id === activeHintId)
    : null;
</script>

<!-- Tutorial objectives panel -->
<div class="tutorial-panel" class:collapsed={panelCollapsed}>
  <button
    class="collapse-btn"
    on:click={() => (panelCollapsed = !panelCollapsed)}
    aria-label={panelCollapsed ? "Expand tutorial" : "Collapse tutorial"}
    title={panelCollapsed ? "Show tutorial" : "Hide tutorial"}
  >
    {panelCollapsed ? "📋" : "×"}
  </button>

  {#if !panelCollapsed}
    <div class="panel-header">
      <span class="panel-title">Tutorial</span>
      <span class="panel-progress"
        >{objectives.filter((o) => doneMap[o.id])
          .length}/{objectives.length}</span
      >
    </div>

    <ol class="objectives-list">
      {#each objectives as obj, i}
        {@const done = doneMap[obj.id] ?? false}
        <li
          class="objective"
          class:done
          class:active={i === currentObjectiveIndex && !done}
        >
          <span class="obj-check"
            >{done ? "✓" : i === currentObjectiveIndex ? "▶" : "○"}</span
          >
          <span class="obj-label">{obj.label}</span>
        </li>
      {/each}
    </ol>

    <button class="quit-btn" on:click={backToLobby}>Quit tutorial</button>
  {/if}
</div>

<!-- Hint tooltip -->
{#if activeHint && !doneMap[activeHint.id]}
  <div class="hint-bubble" role="status" aria-live="polite">
    <div class="hint-header">
      <span class="hint-icon">💡</span>
      <span class="hint-title">Hint — {activeHint.label}</span>
    </div>
    <p class="hint-text">{activeHint.hint}</p>
    <button class="hint-dismiss" on:click={dismissHint}>Got it</button>
  </div>
{/if}

<!-- Completion modal -->
{#if allDone}
  <div class="modal">
    <div class="modal-icon">🏆</div>
    <h2 class="modal-title">Tutorial Complete!</h2>
    <p class="modal-body">
      Well done, Commander! You've mastered the basics.<br />
      Ready to face a real opponent?
    </p>
    <button class="btn-primary" on:click={backToLobby}>
      Play a real match
    </button>
  </div>
{/if}

<style>
  /* ── Panel ─────────────────────────────────────────────────────────────── */
  .tutorial-panel {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 50;
    background: rgba(15, 20, 30, 0.92);
    border: 1px solid rgba(88, 166, 255, 0.35);
    border-radius: 12px;
    padding: 14px 16px 12px;
    min-width: 220px;
    max-width: 260px;
    backdrop-filter: blur(8px);
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
    transition:
      min-width 0.2s,
      padding 0.2s;
  }

  .tutorial-panel.collapsed {
    min-width: 0;
    padding: 8px;
    border-radius: 50%;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .collapse-btn {
    position: absolute;
    top: 8px;
    right: 8px;
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.5);
    font-size: 0.85rem;
    cursor: pointer;
    line-height: 1;
    padding: 2px 4px;
    border-radius: 4px;
    transition: color 0.15s;
  }

  .collapsed .collapse-btn {
    position: static;
    font-size: 1.1rem;
    color: rgba(88, 166, 255, 0.9);
  }

  .collapse-btn:hover {
    color: #fff;
  }

  .panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
    padding-right: 20px;
  }

  .panel-title {
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #58a6ff;
  }

  .panel-progress {
    font-size: 0.75rem;
    color: rgba(255, 255, 255, 0.45);
    font-weight: 600;
  }

  /* ── Objectives list ──────────────────────────────────────────────────── */
  .objectives-list {
    list-style: none;
    padding: 0;
    margin: 0 0 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }

  .objective {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.45);
    transition: color 0.2s;
  }

  .objective.active {
    color: rgba(255, 255, 255, 0.92);
  }

  .objective.done {
    color: rgba(80, 220, 130, 0.8);
    text-decoration: line-through;
    text-decoration-color: rgba(80, 220, 130, 0.4);
  }

  .obj-check {
    font-size: 0.75rem;
    width: 14px;
    text-align: center;
    flex-shrink: 0;
  }

  .objective.active .obj-check {
    color: #58a6ff;
  }
  .objective.done .obj-check {
    color: #50dc82;
  }

  .obj-label {
    line-height: 1.3;
  }

  /* ── Quit button ─────────────────────────────────────────────────────── */
  .quit-btn {
    width: 100%;
    padding: 6px;
    background: rgba(255, 80, 80, 0.12);
    border: 1px solid rgba(255, 80, 80, 0.25);
    border-radius: 7px;
    color: rgba(255, 120, 120, 0.85);
    font-size: 0.75rem;
    cursor: pointer;
    transition:
      background 0.15s,
      color 0.15s;
  }

  .quit-btn:hover {
    background: rgba(255, 80, 80, 0.22);
    color: #ff8888;
  }

  /* ── Hint bubble ─────────────────────────────────────────────────────── */
  .hint-bubble {
    position: absolute;
    bottom: 90px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 55;
    background: rgba(15, 20, 30, 0.96);
    border: 1px solid rgba(255, 200, 60, 0.5);
    border-radius: 14px;
    padding: 14px 18px;
    max-width: 340px;
    width: calc(100% - 48px);
    box-shadow:
      0 6px 32px rgba(0, 0, 0, 0.6),
      0 0 0 1px rgba(255, 200, 60, 0.1);
    animation: hint-pop 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  @keyframes hint-pop {
    from {
      transform: translateX(-50%) scale(0.88);
      opacity: 0;
    }
    to {
      transform: translateX(-50%) scale(1);
      opacity: 1;
    }
  }

  .hint-header {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 7px;
  }

  .hint-icon {
    font-size: 1rem;
  }

  .hint-title {
    font-size: 0.78rem;
    font-weight: 700;
    color: #ffc83c;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }

  .hint-text {
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.82);
    line-height: 1.5;
    margin: 0 0 12px;
  }

  .hint-dismiss {
    display: block;
    margin-left: auto;
    padding: 6px 18px;
    background: rgba(255, 200, 60, 0.15);
    border: 1px solid rgba(255, 200, 60, 0.35);
    border-radius: 8px;
    color: #ffc83c;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s;
  }

  .hint-dismiss:hover {
    background: rgba(255, 200, 60, 0.28);
  }

  /* ── Completion modal ──────────────────────────────────────────────────── */
  .modal {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 200;
    background: var(--surface, #1a2030);
    border: 1px solid var(--border, rgba(255, 255, 255, 0.1));
    border-radius: 20px;
    padding: 40px 32px;
    text-align: center;
    max-width: 340px;
    width: 90%;
    animation: pop-in 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  @keyframes pop-in {
    from {
      transform: scale(0.8);
      opacity: 0;
    }
    to {
      transform: scale(1);
      opacity: 1;
    }
  }

  .modal-icon {
    font-size: 3.2rem;
    margin-bottom: 14px;
  }

  .modal-title {
    font-size: 1.7rem;
    font-weight: 800;
    margin-bottom: 12px;
    background: linear-gradient(135deg, #ffd700, #58a6ff);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
  }

  .modal-body {
    color: rgba(255, 255, 255, 0.65);
    font-size: 0.92rem;
    line-height: 1.6;
    margin-bottom: 28px;
  }

  .btn-primary {
    background: linear-gradient(135deg, #58a6ff, #a78bfa);
    color: #fff;
    padding: 14px 30px;
    border-radius: 12px;
    font-size: 1rem;
    font-weight: 700;
    width: 100%;
    transition:
      filter 0.15s,
      transform 0.1s;
    cursor: pointer;
    border: none;
  }

  .btn-primary:hover {
    filter: brightness(1.12);
  }
  .btn-primary:active {
    transform: scale(0.97);
  }
</style>
