<script lang="ts">
  import { onMount, onDestroy } from 'svelte';
  import { io, Socket } from 'socket.io-client';
  import { Laptop, Bath, Coffee, Users, AlertCircle } from 'lucide-svelte';
  import BookingModal from './BookingModal.svelte';

  export let floorId: string;
  export let spaces: any[] = [];
  export let planImageUrl: string | null = null;
  export let selectedDate: Date = new Date();

  let container: HTMLDivElement;
  let socket: Socket;
  let spaceStatus: Record<string, any> = {};
  let selectedSpace: any = null;
  let containerWidth = 800;
  let containerHeight = 600;

  // Track if we have received any real-time updates to avoid overwriting them with stale initial status
  let realtimeUpdates: Record<string, any> = {};

  $: {
    // Initialize space status from the current state (e.g. from API)
    spaces.forEach(s => {
      // Don't overwrite if we already have a real-time update for today
      if (isToday && realtimeUpdates[s.id]) {
        spaceStatus[s.id] = realtimeUpdates[s.id];
        return;
      }

      const activeReservation = s.reservations && s.reservations.length > 0 ? s.reservations[0] : null;
      spaceStatus[s.id] = {
        isOccupied: !!activeReservation,
        reservation: activeReservation
      };
    });
    spaceStatus = { ...spaceStatus };
    updateContainerSizeToFitAll();
  }

  function updateContainerSizeToFitAll() {
    if (spaces.length === 0) return;
    
    let maxR = 800;
    let maxB = 600;

    spaces.forEach(s => {
      const w = s.width || (s.type === 'DESK' ? 12 : 20);
      const h = s.height || (s.type === 'DESK' ? 8 : 15);
      
      const r = ((s.x + w) / 100) * 800; // Use 800 as base or whatever
      const b = ((s.y + h) / 100) * 600;

      if (r > maxR) maxR = r;
      if (b > maxB) maxB = b;
    });

    // To be consistent with editor, we should probably use the same base.
    // However, in the viewer, we just want to show everything.
    // If spaces were saved with percentages relative to a larger container, 
    // we need to know that container's aspect ratio.
    
    // Actually, the percentages ARE the aspect ratio. 
    // If a space is at x=110%, it means it's outside the "original" 800px.
    // So we should just find the max percentage and scale the container.
    
    let maxXP = 100;
    let maxYP = 100;
    spaces.forEach(s => {
      const w = s.width || (s.type === 'DESK' ? 12 : 20);
      const h = s.height || (s.type === 'DESK' ? 8 : 15);
      if (s.x + w > maxXP) maxXP = s.x + w;
      if (s.y + h > maxYP) maxYP = s.y + h;
    });

    containerWidth = (maxXP / 100) * 800;
    containerHeight = (maxYP / 100) * 600;
    
    // Add some padding
    containerWidth += 40;
    containerHeight += 40;
  }

  $: isToday = new Date(selectedDate.getTime()).setHours(0,0,0,0) === new Date().setHours(0,0,0,0);

  onMount(() => {
    const socketUrl = import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:3000';
    socket = io(socketUrl, {
      transports: ['websocket'], // Prefer WebSockets
    });

    socket.on('connect', () => {
      console.log('Connected to WebSocket for floor:', floorId);
      socket.emit('join_floor', floorId);
    });

    socket.on('space_status_changed', (data: { spaceId: string, isOccupied: boolean, reservation?: any }) => {
      console.log('Space status changed received:', data);
      if (!isToday) {
        console.log('Ignoring real-time update: not today', { 
          selectedDate: selectedDate.toDateString(), 
          now: new Date().toDateString() 
        });
        return;
      }
      
      const update = {
        isOccupied: data.isOccupied,
        reservation: data.reservation
      };
      
      // Save to realtimeUpdates to prevent overwriting by API re-fetches
      realtimeUpdates[data.spaceId] = update;
      spaceStatus[data.spaceId] = update;
      spaceStatus = { ...spaceStatus }; // Trigger reactivity
    });
  });

  onDestroy(() => {
    if (socket) {
      socket.emit('leave_floor', floorId);
      socket.disconnect();
    }
  });

  function getSpaceTypeIcon(type: string, name: string) {
    if (type === 'DESK') return Laptop;
    if (type === 'MEETING_ROOM') return Users;
    const lowerName = name.toLowerCase();
    if (lowerName.includes('toilet') || lowerName.includes('bath')) return Bath;
    if (lowerName.includes('coffee')) return Coffee;
    return AlertCircle;
  }

  function handleSpaceClick(space: any) {
    if (space.type === 'AMENITY') return;
    selectedSpace = space;
  }
</script>

<div 
  bind:this={container}
  class="relative bg-white shadow-xl rounded-lg overflow-hidden border mx-auto floorplan-container"
  style="width: {containerWidth}px; height: {containerHeight}px; background-image: url({planImageUrl}); background-size: cover; background-repeat: no-repeat; background-position: center;"
>
  {#each spaces as space (space.id)}
    {@const status = spaceStatus[space.id] || { isOccupied: false }}
    <button 
      on:click={() => handleSpaceClick(space)}
      class="absolute p-2 border-2 rounded-lg shadow-md transition-all {space.type !== 'AMENITY' ? 'hover:scale-105 cursor-pointer' : 'cursor-default opacity-80'} {status.isOccupied ? 'bg-yellow-50 border-yellow-500' : 'bg-green-50 border-green-500'}"
      style="left: 0; top: 0; width: {(space.width / 100) * containerWidth}px; height: {(space.height / 100) * containerHeight}px; transform: translate({(space.x / 100) * containerWidth}px, {(space.y / 100) * containerHeight}px)"
      title="{space.name} ({status.isOccupied ? 'Booked' : 'Available'})"
    >
      <div class="flex items-center gap-1">
        <div class="relative">
          <div class={status.isOccupied ? 'text-yellow-600' : 'text-green-600'}>
            <svelte:component this={getSpaceTypeIcon(space.type, space.name)} size={16} />
          </div>
          
          {#if status.isOccupied && space.type === 'DESK'}
            <div class="absolute -top-4 -left-4 w-6 h-6 rounded-full bg-white border border-yellow-500 overflow-hidden shadow-sm flex items-center justify-center">
              {#if status.reservation?.user?.profilePicture}
                <img src={status.reservation.user.profilePicture} alt={status.reservation.user.email} class="w-full h-full object-cover" />
              {:else}
                <span class="text-[8px] font-bold text-yellow-700">
                  {status.reservation?.user?.email?.charAt(0).toUpperCase()}
                </span>
              {/if}
            </div>
          {/if}
        </div>

        <div class="flex flex-col items-start leading-none">
          <span class="text-[9px] font-bold text-gray-800 whitespace-nowrap">
            {space.name}
          </span>
          {#if status.isOccupied && space.type === 'DESK'}
            <span class="text-[7px] text-gray-500 truncate max-w-[40px]">
              {status.reservation?.user?.email.split('@')[0]}
            </span>
          {/if}
        </div>
      </div>
    </button>
  {/each}
</div>

{#if selectedSpace}
  <BookingModal 
    space={selectedSpace} 
    status={spaceStatus[selectedSpace.id] || { isOccupied: false }}
    selectedDate={selectedDate}
    on:close={() => selectedSpace = null} 
  />
{/if}

<style>
  .floorplan-container {
    background-color: #f8fafc;
    background-image: 
      linear-gradient(to right, #e2e8f0 1px, transparent 1px),
      linear-gradient(to bottom, #e2e8f0 1px, transparent 1px);
    background-size: 20px 20px;
  }
</style>
