<script lang="ts">
import { onMount } from 'svelte';
import { get } from 'svelte/store';
import Header from '../lib/components/layout/Header.svelte';
import CanvasMap from '../lib/components/canvas/CanvasMap.svelte';
import ColorPalette from '../lib/components/canvas/ColorPalette.svelte';
import { api, ApiError } from '../lib/api/client';
import { currentUser, currentCharges } from '../lib/stores/user';
import { selectedColor } from '../lib/stores/canvas';
import { online } from '../lib/stores/global';
import { calculateLevel } from '../lib/utils/level';

interface SelectedPixel {
  tileX: number;
  tileY: number;
  x: number;
  y: number;
  latlng: { lat: number; lng: number };
}

interface PixelInfo {
  paintedBy: {
    id: number;
    name: string;
    allianceId: number;
    allianceName: string;
    equippedFlag: number;
  };
  region: Record<string, unknown> | null;
}

const SEASON = 's0';

let mapRef: CanvasMap | null = null;
let selected: SelectedPixel | null = null;
let pixelInfo: PixelInfo | null = null;
let loadingPixel = false;
let painting = false;
let errorMessage = '';
let successMessage = '';

onMount(() => {
  currentUser.fetch();
});

async function handlePixel(event: CustomEvent<SelectedPixel>) {
  selected = event.detail;
  errorMessage = '';
  successMessage = '';
  pixelInfo = null;
  await loadPixelInfo(event.detail);
}

async function loadPixelInfo(selection: SelectedPixel) {
  loadingPixel = true;
  try {
    pixelInfo = await api.getPixelInfo(SEASON, selection.tileX, selection.tileY, selection.x, selection.y);
  } catch (error) {
    if (error instanceof ApiError) {
      errorMessage = error.message;
    } else {
      errorMessage = 'Failed to load pixel info.';
    }
  } finally {
    loadingPixel = false;
  }
}

function canPaint(): boolean {
  const user = get(currentUser);
  if (!user || !selected) return false;
  const color = get(selectedColor);
  if (color === 0) return false;
  const charges = get(currentCharges);
  return charges > 0;
}

async function paint() {
  if (!selected) return;
  const user = get(currentUser);
  if (!user) {
    errorMessage = 'Login required to paint.';
    return;
  }
  const color = get(selectedColor);
  if (color === 0) {
    errorMessage = 'Select a color to paint.';
    return;
  }
  const charges = get(currentCharges);
  if (charges <= 0) {
    errorMessage = 'Not enough charges.';
    return;
  }

  painting = true;
  errorMessage = '';
  successMessage = '';

  try {
    await api.paintPixels(SEASON, selected.tileX, selected.tileY, {
      colors: [color],
      coords: [selected.x, selected.y]
    });
    await currentUser.fetch();
    await loadPixelInfo(selected);
    mapRef?.refreshTiles();
    successMessage = 'Pixel painted!';
  } catch (error) {
    if (error instanceof ApiError) {
      errorMessage = error.message;
    } else {
      errorMessage = 'Failed to paint pixel.';
    }
  } finally {
    painting = false;
  }
}
</script>

<Header />

<main class="mx-auto w-full max-w-7xl px-4 py-6 gap-6 flex flex-col lg:flex-row">
  <section class="flex-1 h-[70vh] lg:h-[calc(100vh-8rem)]">
    <CanvasMap bind:this={mapRef} on:pixel={handlePixel} />
  </section>
  <aside class="w-full lg:max-w-md flex flex-col gap-6">
    <section class="rounded-box border border-base-300 bg-base-100 p-4 shadow">
      {#if $currentUser}
        <div class="flex items-start justify-between">
          <div>
            <h2 class="text-lg font-semibold">Hello, {$currentUser.name}</h2>
            <p class="text-sm text-base-content/60">Level {calculateLevel($currentUser.pixelsPainted)} · {$currentUser.pixelsPainted.toLocaleString()} pixels</p>
          </div>
        </div>
        <div class="mt-4 grid grid-cols-2 gap-3 text-sm">
          <div class="rounded-box bg-base-200 p-3">
            <p class="text-xs uppercase text-base-content/60">Charges</p>
            <p class="text-lg font-semibold">{$currentCharges}/{$currentUser.maxCharges}</p>
          </div>
          <div class="rounded-box bg-base-200 p-3">
            <p class="text-xs uppercase text-base-content/60">Droplets</p>
            <p class="text-lg font-semibold">{$currentUser.droplets.toLocaleString()}</p>
          </div>
        </div>
      {:else}
        <p class="text-sm text-base-content/70">
          Login to start painting the world.
          <a href="/join" class="btn btn-sm btn-primary mt-3">Login</a>
        </p>
      {/if}
      {#if !$online}
        <p class="mt-4 rounded-box bg-warning/20 px-3 py-2 text-sm text-warning">You are offline. Painting is disabled.</p>
      {/if}
    </section>

    <section class="rounded-box border border-base-300 bg-base-100 p-4 shadow">
      <h2 class="text-base font-semibold">Palette</h2>
      <ColorPalette />
      <button
        class="btn btn-primary btn-block mt-4"
        on:click={paint}
        disabled={!canPaint() || painting || !$online}
      >
        {#if painting}Painting...{:else}Paint Pixel{/if}
      </button>
      {#if errorMessage}
        <p class="mt-3 rounded-box bg-error/10 px-3 py-2 text-sm text-error">{errorMessage}</p>
      {/if}
      {#if successMessage}
        <p class="mt-3 rounded-box bg-success/10 px-3 py-2 text-sm text-success">{successMessage}</p>
      {/if}
    </section>

    <section class="rounded-box border border-base-300 bg-base-100 p-4 shadow">
      <h2 class="text-base font-semibold">Pixel details</h2>
      {#if !selected}
        <p class="mt-2 text-sm text-base-content/60">Click the map to inspect a pixel.</p>
      {:else if loadingPixel}
        <p class="mt-2 text-sm text-base-content/60">Loading...</p>
      {:else if pixelInfo}
        <div class="mt-3 space-y-3 text-sm">
          <div>
            <p class="text-xs uppercase text-base-content/50">Coordinates</p>
            <p>{selected.tileX}, {selected.tileY} · {selected.x}, {selected.y}</p>
          </div>
          <div>
            <p class="text-xs uppercase text-base-content/50">Painter</p>
            {#if pixelInfo.paintedBy.id !== 0}
              <p>{pixelInfo.paintedBy.name}</p>
              {#if pixelInfo.paintedBy.allianceName}
                <p class="text-base-content/60">Alliance: {pixelInfo.paintedBy.allianceName}</p>
              {/if}
            {:else}
              <p>Unpainted</p>
            {/if}
          </div>
          {#if pixelInfo.region}
            <div>
              <p class="text-xs uppercase text-base-content/50">Region</p>
              <p>{pixelInfo.region?.name ?? 'Unknown'}</p>
            </div>
          {/if}
        </div>
      {:else}
        <p class="mt-2 text-sm text-base-content/60">No data for this pixel.</p>
      {/if}
    </section>
  </aside>
</main>
