import React, { useEffect, useRef, useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import { fetchIslands, fetchIslandPosts, fetchPosts } from '../../api/client';
import { useAuth } from '../../auth/AuthContext';
import './IslandsWorld.css';

/**
 * IslandsWorld: Full-screen metaverse for personal islands
 * Each user has their own floating island in this virtual ocean
 */
export default function IslandsWorld({ theme, onIslandClick, onOpenMap, onOpenPlanets }) {
  const { t } = useTranslation();
  const { authenticated, username } = useAuth();
  const containerRef = useRef(null);
  const mapRef = useRef(null);
  const markersRef = useRef([]);
  const animationRef = useRef(null);
  const islandPositionsRef = useRef(new Map()); // Store island positions

  const [islands, setIslands] = useState([]);
  const [loading, setLoading] = useState(true);
  const [searchQuery, setSearchQuery] = useState('');
  const [hoveredIsland, setHoveredIsland] = useState(null);

  // Zoomed island state
  const [zoomedIsland, setZoomedIsland] = useState(null);
  const [isZooming, setIsZooming] = useState(false);
  const [islandPosts, setIslandPosts] = useState([]);
  const [loadingPosts, setLoadingPosts] = useState(false);

  // Click-to-place post state
  const [pendingPostPosition, setPendingPostPosition] = useState(null);
  const terrainRef = useRef(null);

  // Set global island context when zoomed (for FAB to use)
  useEffect(() => {
    if (zoomedIsland) {
      window.__activeIslandContext = {
        username: zoomedIsland.username,
        isOwner: username && username.toLowerCase() === (zoomedIsland.username || '').toLowerCase(),
        pendingPosition: pendingPostPosition
      };
    } else {
      window.__activeIslandContext = null;
    }
    return () => {
      window.__activeIslandContext = null;
    };
  }, [zoomedIsland, username, pendingPostPosition]);

  // Fetch islands
  useEffect(() => {
    let mounted = true;
    setLoading(true);

    fetchIslands({ limit: 200 })
      .then(data => {
        if (mounted) {
          setIslands(data || []);
          setLoading(false);
        }
      })
      .catch(err => {
        console.warn('[IslandsWorld] Failed to fetch islands:', err);
        if (mounted) setLoading(false);
      });

    return () => { mounted = false; };
  }, []);

  // Filter islands by search
  const filteredIslands = searchQuery
    ? islands.filter(i =>
        (i.username || '').toLowerCase().includes(searchQuery.toLowerCase()) ||
        (i.display_name || '').toLowerCase().includes(searchQuery.toLowerCase())
      )
    : islands;

  // Handle zoom to island - shows full-screen island terrain overlay
  const handleZoomToIsland = useCallback(async (island) => {
    if (isZooming) return;

    setIsZooming(true);
    setZoomedIsland(island);
    setLoadingPosts(true);

    // Fetch posts for this island
    try {
      const posts = await fetchPosts({ username: island.username, limit: 50 });
      setIslandPosts(posts || []);
    } catch (err) {
      console.warn('[IslandsWorld] Failed to fetch island posts:', err);
      setIslandPosts([]);
    }
    setLoadingPosts(false);
    setIsZooming(false);
  }, [isZooming]);

  // Handle zoom out (back to world view)
  const handleZoomOut = useCallback(() => {
    if (isZooming) return;

    setZoomedIsland(null);
    setIslandPosts([]);
    setIsZooming(false);
  }, [isZooming]);

  // Initialize MapLibre
  useEffect(() => {
    if (!containerRef.current || loading) return;

    const centerLng = 0;
    const centerLat = 0;

    const map = new maplibregl.Map({
      container: containerRef.current,
      style: {
        version: 8,
        sources: {},
        layers: [
          {
            id: 'background',
            type: 'background',
            paint: {
              'background-color': '#0a1628'
            }
          }
        ]
      },
      center: [centerLng, centerLat],
      zoom: 2,
      minZoom: 1,
      maxZoom: 18,
      pitch: 0,
      bearing: 0,
      antialias: true,
      attributionControl: false,
      dragRotate: false // Disable rotation, keep simple 2D navigation
    });

    mapRef.current = map;

    // Add navigation controls
    map.addControl(new maplibregl.NavigationControl({ showCompass: false }), 'bottom-right');

    map.on('load', () => {
      // Add ocean gradient layer
      const oceanGradientData = createOceanGradient(centerLng, centerLat);
      map.addSource('ocean-gradient', { type: 'geojson', data: oceanGradientData });
      map.addLayer({
        id: 'ocean-glow',
        type: 'fill',
        source: 'ocean-gradient',
        paint: {
          'fill-color': ['interpolate', ['linear'], ['get', 'intensity'],
            0, '#0a1628', 0.5, '#0d2847', 1, '#1e3a5f'
          ],
          'fill-opacity': 0.8
        }
      });

      // Add starfield
      const starsData = createStarfield(500);
      map.addSource('stars', { type: 'geojson', data: starsData });
      map.addLayer({
        id: 'stars',
        type: 'circle',
        source: 'stars',
        paint: {
          'circle-radius': ['interpolate', ['linear'], ['zoom'], 0, 1, 5, 3],
          'circle-color': ['get', 'color'],
          'circle-opacity': ['get', 'opacity'],
          'circle-blur': 0.3
        }
      });

      // Create island markers - spread in a grid with some randomization
      const markers = [];
      const numIslands = filteredIslands.length;
      const gridSize = Math.ceil(Math.sqrt(numIslands));
      const spacing = 25; // Degrees between islands

      filteredIslands.forEach((island, idx) => {
        // Grid position with jitter
        const gridX = idx % gridSize;
        const gridY = Math.floor(idx / gridSize);
        const rng = seededRandom((island.username || '').charCodeAt(0) || idx);
        const jitterX = (rng() - 0.5) * spacing * 0.6;
        const jitterY = (rng() - 0.5) * spacing * 0.6;

        const lng = (gridX - gridSize / 2) * spacing + jitterX;
        const lat = (gridY - gridSize / 2) * spacing + jitterY;

        // Store position for zoom
        islandPositionsRef.current.set(island.username || island.id, { lng, lat });

        const el = createIslandMarker(island, idx, t, username);

        el.addEventListener('mouseenter', () => setHoveredIsland(island));
        el.addEventListener('mouseleave', () => setHoveredIsland(null));
        el.addEventListener('click', (e) => {
          e.stopPropagation();
          const action = e.target.closest('[data-action]')?.dataset?.action;
          if (action === 'profile') {
            window.location.href = `/profile/${island.username}`;
            return;
          }
          if (action === 'edit') {
            window.location.href = `/island/${island.username}/edit`;
            return;
          }
          // Zoom to island
          handleZoomToIsland(island);
        });

        const marker = new maplibregl.Marker({
          element: el,
          anchor: 'center'
        })
          .setLngLat([lng, lat])
          .addTo(map);

        markers.push({ marker, island, el });
      });

      markersRef.current = markers;
    });

    return () => {
      if (animationRef.current) cancelAnimationFrame(animationRef.current);
      markersRef.current.forEach(({ marker }) => marker.remove());
      markersRef.current = [];
      islandPositionsRef.current.clear();
      map.remove();
    };
  }, [filteredIslands, loading, t, username, handleZoomToIsland]);

  return (
    <div className="islands-world">
      {/* Search bar with icon and world nav */}
      <div className="islands-world-search">
        <i className="fa-solid fa-umbrella-beach search-icon" />
        <i className="fa-solid fa-search" />
        <input
          type="text"
          placeholder={t('worlds.searchIslands')}
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
        />
        {searchQuery && (
          <button onClick={() => setSearchQuery('')} className="search-clear">
            <i className="fa-solid fa-xmark" />
          </button>
        )}
        <span className="search-count">{islands.length}</span>
        <div className="world-nav-inline">
          <button className="world-nav-btn-sm" onClick={onOpenMap} title={t('worlds.map')}>
            <i className="fa-solid fa-earth-americas" />
          </button>
          <button className="world-nav-btn-sm" onClick={onOpenPlanets} title={t('worlds.planets')}>
            <i className="fa-solid fa-globe" />
          </button>
        </div>
      </div>

      {/* Main canvas */}
      <div ref={containerRef} className="islands-world-canvas" />

      {/* Hovered island tooltip (only when not zoomed) */}
      {hoveredIsland && !zoomedIsland && (
        <div className="islands-world-tooltip">
          <div className="tooltip-avatar">
            {hoveredIsland.avatar_url ? (
              <img src={hoveredIsland.avatar_url} alt={hoveredIsland.username} />
            ) : (
              <span>{(hoveredIsland.username || 'U')[0].toUpperCase()}</span>
            )}
          </div>
          <div className="tooltip-info">
            <div className="tooltip-username">@{hoveredIsland.username}</div>
            <div className="tooltip-bio">{hoveredIsland.display_name || hoveredIsland.bio || t('worlds.clickToVisit')}</div>
            <div className="tooltip-stats">
              {hoveredIsland.content_count || 0} {t('worlds.posts')} • {hoveredIsland.terrain_type || 'tropical'}
            </div>
          </div>
        </div>
      )}

      {/* Zoomed island - full screen terrain view (like a map) */}
      {zoomedIsland && (
        <div className="island-fullscreen-overlay">
          {/* Header bar */}
          <div className="island-terrain-header">
            <button className="island-terrain-back" onClick={() => {
              handleZoomOut();
              setPendingPostPosition(null);
            }}>
              <i className="fa-solid fa-arrow-left" />
              <span>{t('worlds.backToIslands')}</span>
            </button>
            <div className="island-terrain-title">
              <h2>@{zoomedIsland.username}</h2>
              <span>{zoomedIsland.display_name || zoomedIsland.terrain_type || 'Island'}</span>
            </div>
            <div className="island-terrain-actions">
              <button className="island-terrain-btn" onClick={() => window.location.href = `/profile/${zoomedIsland.username}`}>
                <i className="fa-solid fa-user" />
              </button>
              {username && username.toLowerCase() === (zoomedIsland.username || '').toLowerCase() && (
                <button className="island-terrain-btn" onClick={() => window.location.href = `/island/${zoomedIsland.username}/edit`}>
                  <i className="fa-solid fa-cog" />
                </button>
              )}
            </div>
          </div>

          {/* Interactive terrain area */}
          <div
            ref={terrainRef}
            className="island-terrain-interactive"
            onClick={(e) => {
              // Only owner can place posts
              if (!username || username.toLowerCase() !== (zoomedIsland.username || '').toLowerCase()) return;

              const rect = terrainRef.current?.getBoundingClientRect();
              if (!rect) return;

              // Calculate position as percentage (0-100)
              const x = ((e.clientX - rect.left) / rect.width) * 100;
              const y = ((e.clientY - rect.top) / rect.height) * 100;

              setPendingPostPosition({ x, y });
            }}
          >
            {/* Full-screen island terrain background */}
            <IslandTerrainBackground island={zoomedIsland} />

            {/* Loading */}
            {loadingPosts && (
              <div className="island-terrain-loading">
                <div className="loading-spinner" />
              </div>
            )}

            {/* Empty state hint */}
            {!loadingPosts && islandPosts.length === 0 && !pendingPostPosition && (
              <div className="island-terrain-empty">
                <i className="fa-solid fa-umbrella-beach" />
                <p>{t('worlds.emptyIsland')}</p>
                {username && username.toLowerCase() === (zoomedIsland.username || '').toLowerCase() && (
                  <p className="island-terrain-hint">{t('worlds.clickToPlacePost')}</p>
                )}
              </div>
            )}

            {/* Posts displayed at their coordinates */}
            {!loadingPosts && islandPosts.map((post, idx) => (
              <IslandPost
                key={post.id || idx}
                post={post}
                index={idx}
                islandSeed={zoomedIsland.seed || 0}
              />
            ))}

            {/* Pending post marker (where user clicked) */}
            {pendingPostPosition && (
              <div
                className="island-pending-post-marker"
                style={{
                  left: `${pendingPostPosition.x}%`,
                  top: `${pendingPostPosition.y}%`
                }}
              >
                <div className="pending-marker-icon">
                  <i className="fa-solid fa-plus" />
                </div>
                <div className="pending-marker-actions">
                  <button
                    className="pending-marker-btn pending-marker-confirm"
                    onClick={(e) => {
                      e.stopPropagation();
                      // Open post composer with position
                      window.dispatchEvent(new CustomEvent('sw:openPostCreator', {
                        detail: {
                          island_username: zoomedIsland.username,
                          island_x: pendingPostPosition.x,
                          island_y: pendingPostPosition.y
                        }
                      }));
                      setPendingPostPosition(null);
                    }}
                  >
                    <i className="fa-solid fa-check" />
                    <span>{t('worlds.postHere')}</span>
                  </button>
                  <button
                    className="pending-marker-btn pending-marker-cancel"
                    onClick={(e) => {
                      e.stopPropagation();
                      setPendingPostPosition(null);
                    }}
                  >
                    <i className="fa-solid fa-times" />
                  </button>
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* Loading overlay */}
      {loading && (
        <div className="islands-world-loading">
          <div className="loading-spinner" />
          <p>{t('worlds.loadingIslands')}</p>
        </div>
      )}
    </div>
  );
}

/**
 * Create a stylized island marker element
 */
function createIslandMarker(island, idx, t, currentUsername) {
  const el = document.createElement('div');
  el.className = 'island-marker';

  const terrainColors = {
    'tropical': '#2ecc71',
    'desert': '#f39c12',
    'arctic': '#3498db',
    'volcanic': '#e74c3c',
    'meadow': '#27ae60',
  };
  const color = terrainColors[island.terrain_type] || terrainColors['tropical'];
  const seed = island.seed || idx;
  const islandSVG = generateIslandSVG(seed, color);
  const postCount = island.content_count || 0;
  const isOwner = currentUsername && island.username &&
    currentUsername.toLowerCase() === island.username.toLowerCase();

  el.innerHTML = `
    <div class="island-marker-inner" style="animation-delay: ${(idx % 12) * 0.25}s;">
      ${isOwner ? `
        <div class="island-owner-badge">
          <i class="fa-solid fa-home"></i>
          <span>Mon île</span>
        </div>
      ` : ''}
      ${islandSVG}
      <div class="island-marker-label">
        <span class="island-marker-name" style="color: ${color}">@${island.username}</span>
        <span class="island-marker-meta">${postCount} posts</span>
      </div>
      <div class="island-marker-actions">
        <button class="island-action-btn island-profile-btn" data-action="profile" title="View Profile">
          <i class="fa-solid fa-user"></i>
        </button>
        ${isOwner ? `
        <button class="island-action-btn island-edit-btn" data-action="edit" title="Edit Island">
          <i class="fa-solid fa-pen"></i>
        </button>
        ` : ''}
      </div>
    </div>
  `;

  return el;
}

/**
 * Generate island SVG with organic shape
 */
function generateIslandSVG(seed, color) {
  const rng = seededRandom(seed);
  const size = 140;
  const cx = size / 2;
  const cy = size / 2;
  const numPoints = 10;

  const points = [];
  for (let i = 0; i < numPoints; i++) {
    const angle = (i / numPoints) * Math.PI * 2;
    const radiusVar = 0.55 + rng() * 0.45;
    const r = (size / 2.5) * radiusVar;
    points.push({ x: cx + Math.cos(angle) * r, y: cy + Math.sin(angle) * r });
  }

  let path = `M ${points[0].x} ${points[0].y}`;
  for (let i = 0; i < numPoints; i++) {
    const curr = points[i];
    const next = points[(i + 1) % numPoints];
    const cpx = (curr.x + next.x) / 2 + (rng() - 0.5) * 10;
    const cpy = (curr.y + next.y) / 2 + (rng() - 0.5) * 10;
    path += ` Q ${cpx} ${cpy} ${next.x} ${next.y}`;
  }
  path += ' Z';

  const numTrees = 3 + Math.floor(rng() * 4);
  let trees = '';
  for (let i = 0; i < numTrees; i++) {
    const angle = rng() * Math.PI * 2;
    const dist = 10 + rng() * 20;
    const tx = cx + Math.cos(angle) * dist;
    const ty = cy + Math.sin(angle) * dist;
    const treeSize = 6 + rng() * 6;
    trees += `
      <g transform="translate(${tx}, ${ty})">
        <rect x="-1" y="${-treeSize}" width="2" height="${treeSize}" fill="#5D4037" rx="0.5"/>
        <ellipse cx="0" cy="${-treeSize}" rx="${treeSize * 0.8}" ry="${treeSize * 0.5}" fill="#228B22" opacity="0.9"/>
      </g>
    `;
  }

  return `
    <svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" class="island-svg">
      <defs>
        <radialGradient id="ig-${seed}" cx="30%" cy="30%">
          <stop offset="0%" stop-color="${color}" stop-opacity="1" />
          <stop offset="70%" stop-color="${color}" stop-opacity="0.85" />
          <stop offset="100%" stop-color="${color}" stop-opacity="0.6" />
        </radialGradient>
        <filter id="glow-${seed}">
          <feGaussianBlur stdDeviation="4" result="blur"/>
          <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
      </defs>
      <path d="${path}" fill="#F5DEB3" transform="scale(1.08) translate(-5.6, -5.6)" opacity="0.6"/>
      <path d="${path}" fill="url(#ig-${seed})" filter="url(#glow-${seed})"/>
      ${trees}
    </svg>
  `;
}

function createStarfield(count) {
  const features = [];
  for (let i = 0; i < count; i++) {
    const lng = (Math.random() - 0.5) * 400;
    const lat = (Math.random() - 0.5) * 400;
    const brightness = Math.random();
    features.push({
      type: 'Feature',
      geometry: { type: 'Point', coordinates: [lng, lat] },
      properties: {
        color: brightness > 0.8 ? '#ffeedd' : brightness > 0.5 ? '#aaccff' : '#ffffff',
        opacity: 0.3 + brightness * 0.5
      }
    });
  }
  return { type: 'FeatureCollection', features };
}

function createOceanGradient(centerLng, centerLat) {
  const features = [];
  const rings = 10;
  for (let i = 0; i < rings; i++) {
    const radius = (i + 1) * 30;
    const coords = [];
    for (let j = 0; j <= 64; j++) {
      const angle = (j / 64) * Math.PI * 2;
      coords.push([centerLng + Math.cos(angle) * radius, centerLat + Math.sin(angle) * radius]);
    }
    features.push({
      type: 'Feature',
      geometry: { type: 'Polygon', coordinates: [coords] },
      properties: { intensity: 1 - (i / rings) }
    });
  }
  return { type: 'FeatureCollection', features };
}

function seededRandom(seed) {
  let s = seed;
  return function() {
    s = (s * 9301 + 49297) % 233280;
    return s / 233280;
  };
}

/**
 * IslandTerrainBackground - Full-screen island shape background
 */
function IslandTerrainBackground({ island }) {
  const terrainColors = {
    'tropical': { main: '#2ecc71', sand: '#F5DEB3', water: '#1e3a5f' },
    'desert': { main: '#f39c12', sand: '#DEB887', water: '#1e3a5f' },
    'arctic': { main: '#3498db', sand: '#E0FFFF', water: '#0d2847' },
    'volcanic': { main: '#e74c3c', sand: '#2C2C2C', water: '#1a1a2e' },
    'meadow': { main: '#27ae60', sand: '#90EE90', water: '#0d2847' },
  };
  const colors = terrainColors[island.terrain_type] || terrainColors['tropical'];
  const seed = island.seed || (island.username || '').charCodeAt(0) || 0;

  return (
    <svg className="island-terrain-bg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice">
      <defs>
        <radialGradient id="ocean-grad" cx="50%" cy="50%" r="70%">
          <stop offset="0%" stopColor={colors.water} />
          <stop offset="100%" stopColor="#0a1628" />
        </radialGradient>
        <radialGradient id="island-grad" cx="30%" cy="30%">
          <stop offset="0%" stopColor={colors.main} stopOpacity="1" />
          <stop offset="60%" stopColor={colors.main} stopOpacity="0.9" />
          <stop offset="100%" stopColor={colors.main} stopOpacity="0.7" />
        </radialGradient>
        <filter id="island-shadow">
          <feDropShadow dx="0" dy="2" stdDeviation="3" floodColor="rgba(0,0,0,0.5)" />
        </filter>
      </defs>

      {/* Ocean background */}
      <rect width="100" height="100" fill="url(#ocean-grad)" />

      {/* Beach/sand ring */}
      <IslandShape seed={seed} cx={50} cy={50} scale={1.15} fill={colors.sand} opacity={0.6} />

      {/* Main island */}
      <IslandShape seed={seed} cx={50} cy={50} scale={1} fill="url(#island-grad)" filter="url(#island-shadow)" />

      {/* Trees and details */}
      <IslandDetails seed={seed} cx={50} cy={50} />
    </svg>
  );
}

/**
 * Generate organic island shape path
 */
function IslandShape({ seed, cx, cy, scale, fill, opacity = 1, filter }) {
  const rng = seededRandom(seed);
  const baseRadius = 30;
  const numPoints = 12;

  const points = [];
  for (let i = 0; i < numPoints; i++) {
    const angle = (i / numPoints) * Math.PI * 2;
    const radiusVar = 0.7 + rng() * 0.3;
    const r = baseRadius * radiusVar * scale;
    points.push({
      x: cx + Math.cos(angle) * r,
      y: cy + Math.sin(angle) * r
    });
  }

  let path = `M ${points[0].x} ${points[0].y}`;
  for (let i = 0; i < numPoints; i++) {
    const curr = points[i];
    const next = points[(i + 1) % numPoints];
    const cpx = (curr.x + next.x) / 2 + (rng() - 0.5) * 6;
    const cpy = (curr.y + next.y) / 2 + (rng() - 0.5) * 6;
    path += ` Q ${cpx} ${cpy} ${next.x} ${next.y}`;
  }
  path += ' Z';

  return <path d={path} fill={fill} opacity={opacity} filter={filter} />;
}

/**
 * Island trees and details
 */
function IslandDetails({ seed, cx, cy }) {
  const rng = seededRandom(seed + 100);
  const numTrees = 8 + Math.floor(rng() * 6);
  const trees = [];

  for (let i = 0; i < numTrees; i++) {
    const angle = rng() * Math.PI * 2;
    const dist = 5 + rng() * 18;
    const tx = cx + Math.cos(angle) * dist;
    const ty = cy + Math.sin(angle) * dist;
    const treeSize = 2 + rng() * 3;

    trees.push(
      <g key={i} transform={`translate(${tx}, ${ty})`}>
        <rect x="-0.3" y={-treeSize} width="0.6" height={treeSize} fill="#5D4037" rx="0.2" />
        <ellipse cx="0" cy={-treeSize} rx={treeSize * 0.7} ry={treeSize * 0.5} fill="#228B22" opacity="0.85" />
      </g>
    );
  }

  return <g>{trees}</g>;
}

/**
 * IslandPost - A post displayed on the island terrain at its coordinates
 */
function IslandPost({ post, index, islandSeed }) {
  // Use island coordinates if available, otherwise fall back to random placement
  let left, top;
  if (post.island_x !== undefined && post.island_y !== undefined) {
    left = post.island_x;
    top = post.island_y;
  } else {
    // Fallback: random position based on seed
    const rng = seededRandom(islandSeed * 100 + index + (post.id || 0));
    left = 15 + rng() * 70; // 15-85% from left
    top = 20 + rng() * 60; // 20-80% from top
  }

  const hasImage = post.media_urls?.length > 0 || post.image_url;
  const imageUrl = post.media_urls?.[0] || post.image_url;

  return (
    <div
      className="island-post-marker"
      style={{
        left: `${left}%`,
        top: `${top}%`
      }}
      onClick={(e) => {
        e.stopPropagation();
        window.location.href = `/post/${post.id}`;
      }}
    >
      {hasImage ? (
        <div className="island-post-image">
          <img src={imageUrl} alt="" />
        </div>
      ) : (
        <div className="island-post-text">
          <p>{(post.content || post.text || '').slice(0, 80)}</p>
        </div>
      )}
      <div className="island-post-meta">
        <span className="island-post-likes">
          <i className="fa-solid fa-heart" /> {post.like_count || 0}
        </span>
      </div>
    </div>
  );
}
