'use strict';

(() => {
  const TILE_W = 78;
  const TILE_H = 40;
  const WORLD_WIDTH = 6000;
  const WORLD_HEIGHT = 3300;
  const ORIGIN_X = 3000;
  const ORIGIN_Y = 170;

  const COLORS = {
    roof: ['#8d3828', '#a3432c', '#195f67', '#274d6c', '#8b5a13'],
    wall: ['#b99867', '#cbb17f', '#a7a394', '#8e9a9d', '#d0bd87'],
    dark: '#3b2b20',
    stone: '#77786f',
    stoneDark: '#4d504b',
    wood: '#6b4326',
    woodDark: '#3e2819',
    gold: '#d7aa3d'
  };

  function esc(value) {
    return String(value ?? '').replace(/[&<>'"]/g, char => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', "'": '&#39;', '"': '&quot;' }[char]));
  }

  function project(x, y) {
    return {
      x: ORIGIN_X + (x - y) * TILE_W / 2,
      y: ORIGIN_Y + (x + y) * TILE_H / 2
    };
  }

  function tierFor(level) {
    const value = Math.max(1, Number(level) || 1);
    if (value >= 10) return 5;
    if (value >= 7) return 4;
    if (value >= 5) return 3;
    if (value >= 3) return 2;
    return 1;
  }

  function stageFor(profile) {
    const expansion = Number(profile?.castleState?.expansionLevel) || 0;
    const keepLevel = Number(profile?.buildings?.find(item => item.type === 'keep')?.level) || 1;
    if (expansion >= 16 && keepLevel >= 8) return { id: 5, name: 'Cidadela máxima', text: '60 × 60 quadrados, muralhas completas e edifícios de elite' };
    if (expansion >= 12 || keepLevel >= 7) return { id: 4, name: 'Grande cidadela', text: 'Uma cidade fortificada com numerosas torres' };
    if (expansion >= 8 || keepLevel >= 5) return { id: 3, name: 'Cidade murada', text: 'Mais terreno, torres e edifícios avançados' };
    if (expansion >= 4 || keepLevel >= 3) return { id: 2, name: 'Fortaleza em crescimento', text: 'O povoado começa a transformar-se numa fortaleza' };
    return { id: 1, name: 'Povoado inicial', text: 'Poucos edifícios dentro de uma muralha pequena' };
  }

  function prism(x, y, w, h, depth, top, left, right) {
    return `<polygon points="${x},${y} ${x + w / 2},${y + h / 2} ${x},${y + h} ${x - w / 2},${y + h / 2}" fill="${top}"/>
      <polygon points="${x - w / 2},${y + h / 2} ${x},${y + h} ${x},${y + h + depth} ${x - w / 2},${y + h / 2 + depth}" fill="${left}"/>
      <polygon points="${x + w / 2},${y + h / 2} ${x},${y + h} ${x},${y + h + depth} ${x + w / 2},${y + h / 2 + depth}" fill="${right}"/>`;
  }

  function roof(x, y, w, h, rise, color, dark) {
    return `<polygon points="${x - w / 2},${y + h / 2} ${x},${y - rise} ${x},${y + h} ${x - w / 2},${y + h / 2}" fill="${dark}"/>
      <polygon points="${x + w / 2},${y + h / 2} ${x},${y - rise} ${x},${y + h} ${x + w / 2},${y + h / 2}" fill="${color}"/>
      <path d="M ${x} ${y - rise} L ${x} ${y + h}" stroke="#f4cc66" stroke-width="2" opacity=".65"/>`;
  }

  function windows(x, y, count = 3, spacing = 22, color = '#9fe8ff') {
    let html = '';
    for (let i = 0; i < count; i++) {
      const px = x + (i - (count - 1) / 2) * spacing;
      html += `<rect x="${px - 5}" y="${y}" width="10" height="15" rx="2" fill="${color}" stroke="#26343b" stroke-width="2"/>`;
    }
    return html;
  }

  function commonHouse(type, tier, symbol, options = {}) {
    const roofColor = options.roof || COLORS.roof[Math.min(COLORS.roof.length - 1, tier - 1)];
    const wallColor = options.wall || COLORS.wall[Math.min(COLORS.wall.length - 1, tier - 1)];
    const width = 112 + tier * 6;
    const height = 44 + tier * 3;
    const baseY = 78;
    const tower = tier >= 4 ? `<g>${prism(159, 58, 38, 20, 55, '#8f948c', '#62665f', '#777c74')}${roof(159, 48, 46, 22, 30, roofColor, '#6f2b26')}${windows(159, 95, 1)}</g>` : '';
    const chimney = tier >= 2 ? `<g><polygon points="70,43 79,48 79,82 70,77" fill="#4c4c47"/><polygon points="79,48 87,44 87,78 79,82" fill="#686861"/><ellipse cx="83" cy="38" rx="9" ry="5" fill="#d8d4c8" opacity=".35"/></g>` : '';
    return `<svg viewBox="0 0 220 190" aria-hidden="true">
      <ellipse cx="110" cy="165" rx="88" ry="18" fill="#172019" opacity=".35"/>
      ${prism(110, baseY, width, height, 52 + tier * 3, wallColor, '#826543', '#a98355')}
      ${roof(110, baseY - 2, width + 20, height + 8, 42 + tier * 3, roofColor, '#6d2a24')}
      ${chimney}${tower}
      <rect x="101" y="124" width="20" height="38" rx="2" fill="#4a2d1a" stroke="#2c1c12" stroke-width="3"/>
      ${windows(110, 111, tier >= 4 ? 4 : tier >= 2 ? 3 : 2, 27)}
      <circle cx="111" cy="142" r="2" fill="#d9bd5c"/>
      <g transform="translate(110 101)"><circle r="17" fill="#efe0ad" stroke="#594529" stroke-width="3"/><text text-anchor="middle" dominant-baseline="central" font-size="19">${symbol}</text></g>
      ${tier >= 3 ? '<path d="M45 137 Q70 124 92 141" stroke="#d7aa3d" stroke-width="4" fill="none"/><path d="M175 137 Q150 124 128 141" stroke="#d7aa3d" stroke-width="4" fill="none"/>' : ''}
    </svg>`;
  }

  function keepSvg(tier) {
    const roofColor = COLORS.roof[Math.min(COLORS.roof.length - 1, tier - 1)];
    const stone = COLORS.wall[Math.min(COLORS.wall.length - 1, Math.max(2, tier - 1))];
    const wing = (x, mirror = false) => `<g transform="translate(${x} 0) scale(${mirror ? -1 : 1} 1)">
      ${prism(0, 90, 58, 28, 58, stone, '#696b66', '#858781')}
      ${roof(0, 79, 68, 30, 40, roofColor, '#692824')}
      ${windows(0, 121, 2, 20)}
    </g>`;
    return `<svg viewBox="0 0 260 230" aria-hidden="true">
      <ellipse cx="130" cy="207" rx="112" ry="21" fill="#152019" opacity=".4"/>
      ${tier >= 2 ? wing(62, true) + wing(198, false) : ''}
      ${prism(130, 78, 105, 45, 90 + tier * 5, stone, '#666962', '#858a82')}
      ${roof(130, 68, 119, 47, 50 + tier * 4, roofColor, '#662823')}
      <rect x="116" y="142" width="29" height="57" rx="4" fill="#3e2a1b" stroke="#1f1711" stroke-width="4"/>
      ${windows(130, 126, tier >= 4 ? 5 : 3, 26)}
      <g transform="translate(130 92)"><circle r="22" fill="#f0dfac" stroke="#5d4727" stroke-width="4"/><text text-anchor="middle" dominant-baseline="central" font-size="24">♜</text></g>
      <line x1="130" y1="15" x2="130" y2="63" stroke="#322419" stroke-width="4"/>
      <path d="M132 18 L177 30 L143 53 L132 48 Z" fill="#b41e2c" stroke="#6f1019" stroke-width="2"/>
      ${tier >= 3 ? '<path d="M80 154 L180 154" stroke="#d6a734" stroke-width="5"/><circle cx="80" cy="154" r="5" fill="#d6a734"/><circle cx="180" cy="154" r="5" fill="#d6a734"/>' : ''}
      ${tier >= 5 ? '<path d="M42 116 L20 79 L59 95 Z" fill="#b41e2c"/><path d="M218 116 L240 79 L201 95 Z" fill="#b41e2c"/>' : ''}
    </svg>`;
  }

  function farmSvg(tier) {
    const crops = Array.from({ length: 6 }, (_, i) => `<path d="M${32 + i * 20} 153 l12 -8 l12 8 l-12 8z" fill="${i % 2 ? '#d7b641' : '#edcd55'}" opacity=".95"/>`).join('');
    return `<svg viewBox="0 0 220 190" aria-hidden="true"><ellipse cx="110" cy="166" rx="92" ry="18" fill="#172019" opacity=".32"/>${crops}
      ${prism(110, 76, 112, 44, 55, '#b98551', '#7b583a', '#a16d43')}${roof(110, 74, 126, 47, 45, '#a8442c', '#6c2a24')}
      <rect x="97" y="119" width="27" height="42" fill="#4c2e1c" stroke="#291b12" stroke-width="3"/>
      <path d="M105 119 L105 161 M116 119 L116 161" stroke="#8a5c38" stroke-width="3"/>
      <g transform="translate(110 99)"><circle r="17" fill="#f1dfa7" stroke="#5a4328" stroke-width="3"/><g fill="none" stroke="#8a6819" stroke-width="1.8" stroke-linecap="round"><path d="M0 11V-11"/><path d="M0-7C-5-9-7-7-8-4  -4-4-2-3 0 0"/><path d="M0-3C5-5 7-3 8 0 4 0 2 1 0 4"/><path d="M0 2C-5 0-7 2-8 5-4 5-2 6 0 9"/></g></g>
      ${tier >= 3 ? '<circle cx="58" cy="126" r="17" fill="#c8a353"/><circle cx="162" cy="126" r="17" fill="#c8a353"/>' : ''}
    </svg>`;
  }

  function quarrySvg(tier) {
    const rocks = '<g fill="#81827c" stroke="#535650" stroke-width="2"><polygon points="25,150 45,124 65,151"/><polygon points="47,160 72,132 95,161"/><polygon points="150,158 172,127 198,158"/><polygon points="137,165 155,141 178,165"/></g>';
    return `<svg viewBox="0 0 220 190" aria-hidden="true"><ellipse cx="110" cy="166" rx="91" ry="18" fill="#172019" opacity=".32"/>${rocks}
      ${prism(110, 84, 102, 40, 47, '#9c8a6b', '#6e604b', '#837159')}${roof(110, 81, 116, 42, 35, '#57493d', '#3e342e')}
      <rect x="100" y="121" width="22" height="39" fill="#463124"/>
      <path d="M152 57 L187 36 L187 132 M153 58 L187 58 M166 58 L166 111" stroke="#5b3c22" stroke-width="6" fill="none"/>
      <path d="M166 111 l-10 15 h20z" fill="#8f8f88"/>
      <g transform="translate(110 103)"><circle r="17" fill="#e9d7a3" stroke="#59462c" stroke-width="3"/><path d="M-8 10 8-7" stroke="#5a3820" stroke-width="3" stroke-linecap="round"/><path d="M1-9C6-12 11-9 12-4M1-9C-3-8-7-5-9-1" fill="none" stroke="#747a7d" stroke-width="3" stroke-linecap="round"/></g>
      ${tier >= 4 ? '<path d="M31 139 L63 98 L91 139" fill="#6f716d" stroke="#474946" stroke-width="3"/>' : ''}
    </svg>`;
  }

  function woodcutterSvg(tier) {
    return `<svg viewBox="0 0 220 190" aria-hidden="true"><ellipse cx="110" cy="165" rx="94" ry="18" fill="#172019" opacity=".32"/>
      <g stroke="#3a2518" stroke-width="3"><rect x="25" y="139" width="58" height="12" rx="6" fill="#8a552e"/><rect x="36" y="151" width="58" height="12" rx="6" fill="#9b6236"/><circle cx="28" cy="145" r="6" fill="#d5a66b"/><circle cx="39" cy="157" r="6" fill="#d5a66b"/></g>
      ${prism(121, 78, 108, 44, 54, '#c18c55', '#805833', '#a36d3f')}${roof(121, 76, 124, 46, 42, '#9e3d2a', '#662820')}
      <rect x="109" y="119" width="25" height="42" fill="#4b2c18"/>
      <circle cx="174" cy="135" r="28" fill="#70664e" stroke="#34291d" stroke-width="4"/><circle cx="174" cy="135" r="8" fill="#b9915a"/>
      <g transform="translate(121 101)"><circle r="17" fill="#eedda8" stroke="#5b4328" stroke-width="3"/><path d="M-10 7 7-7" stroke="#7b8589" stroke-width="4" stroke-linecap="round"/><path d="M-7 7l2 3 2-4 2 3 2-4 2 3 2-4" fill="none" stroke="#52585b" stroke-width="1.5" stroke-linejoin="round"/><path d="M7-7l4-4" stroke="#704221" stroke-width="4" stroke-linecap="round"/></g>
      ${tier >= 3 ? '<path d="M174 107 L192 72" stroke="#55412b" stroke-width="6"/><path d="M191 72 L201 87" stroke="#55412b" stroke-width="6"/>' : ''}
    </svg>`;
  }

  function decorationSvg(tier) {
    if (tier >= 4) return `<svg viewBox="0 0 170 170"><ellipse cx="85" cy="144" rx="60" ry="16" fill="#172019" opacity=".3"/><ellipse cx="85" cy="124" rx="51" ry="22" fill="#67b7d1" stroke="#d6c887" stroke-width="7"/><rect x="76" y="57" width="18" height="67" fill="#9a9b91"/><circle cx="85" cy="44" r="24" fill="#d1ad42" stroke="#6e5523" stroke-width="4"/><path d="M61 91 Q85 64 109 91" stroke="#8de4f3" stroke-width="5" fill="none"/></svg>`;
    return `<svg viewBox="0 0 170 170"><ellipse cx="85" cy="146" rx="58" ry="15" fill="#172019" opacity=".3"/><rect x="76" y="89" width="18" height="47" fill="#7f6d55"/><circle cx="85" cy="70" r="39" fill="#4f8a3b" stroke="#2f632c" stroke-width="5"/><circle cx="58" cy="82" r="27" fill="#63a249"/><circle cx="111" cy="84" r="28" fill="#5b9844"/><circle cx="85" cy="42" r="25" fill="#6aaa4d"/></svg>`;
  }

  function buildingSvg(type, level) {
    const tier = tierFor(level);
    if (type === 'keep') return keepSvg(tier);
    if (type === 'woodcutter') return woodcutterSvg(tier);
    if (type === 'quarry') return quarrySvg(tier);
    if (type === 'farm') return farmSvg(tier);
    if (type === 'decoration') return decorationSvg(tier);
    const symbols = {
      house: '⌂', barracks: '⚔', warehouse: '▣', marketplace: '⚖', workshop: '⚒', stables: '♞', hospital: '✚', tavern: '🍺', watchtower: '◉'
    };
    const options = {
      barracks: { roof: '#872b2d', wall: '#aaa28e' }, warehouse: { roof: '#6c4b2b', wall: '#bd9b67' }, marketplace: { roof: '#267f84', wall: '#ceb780' },
      workshop: { roof: '#3d4848', wall: '#8e8271' }, stables: { roof: '#754429', wall: '#b68b58' }, hospital: { roof: '#e4e0cd', wall: '#aaa9a0' },
      tavern: { roof: '#7d3340', wall: '#c19866' }, watchtower: { roof: '#3d5569', wall: '#898c87' }
    };
    return commonHouse(type, tier, symbols[type] || '⌂', options[type] || {});
  }

  function renderTile(x, y, occupied, gridSize) {
    const point = project(x, y);
    const slot = y * gridSize + x;
    return `<button class="castle-ground-tile castle-iso-tile unlocked ${occupied ? 'occupied-start' : ''}" data-action="build-slot" data-slot="${slot}" data-grid-x="${x}" data-grid-y="${y}" style="left:${point.x - TILE_W / 2}px;top:${point.y - TILE_H / 2}px;--tile-z:${100 + x + y}" aria-label="Parcela X ${x} Y ${y}"><span>＋</span></button>`;
  }

  function renderTerrain(profile, bounds, gridSize = 60) {
    const occupied = new Set((profile.buildings || []).map(item => item.slot));
    const cells = globalThis.ReinosCastleExpansions?.cells?.(profile) || [];
    return cells.map(({ x, y }) => renderTile(x, y, occupied.has(y * gridSize + x), gridSize)).join('');
  }

  function renderBuilding(building, ctx, helpers) {
    const meta = ctx.getBuildingsMeta()[building.type] || { name: building.type };
    const position = helpers.slotToPosition(building.slot);
    const size = helpers.sizeFor(building.type);
    const centerX = position.x + (size.w - 1) / 2;
    const centerY = position.y + (size.h - 1) / 2;
    const point = project(centerX, centerY);
    const tier = tierFor(building.level);
    const supportsIllustrated = ['keep','woodcutter','quarry','farm','house','barracks','warehouse','marketplace','workshop','stables','hospital','tavern','watchtower','decoration'].includes(building.type);
    const illustratedMetrics = globalThis.ReinosIllustratedBuildings?.metrics?.(building.type, building.level || 1)
      || (supportsIllustrated ? (building.type === 'keep' ? { width:292, height:232 } : building.type === 'watchtower' ? { width:235, height:225 } : building.type === 'decoration' ? { width:205, height:195 } : { width:248, height:205 }) : null);
    const detailedMetrics = globalThis.ReinosBuildingVisuals?.metrics?.(building.type, building.level || 1) || null;
    const barracksMetrics = building.type === 'barracks'
      ? globalThis.ReinosBarracksVisuals?.isometricMetrics?.(building.level || 1)
      : null;
    const width = illustratedMetrics?.width || detailedMetrics?.width || barracksMetrics?.width
      || (building.type === 'keep' ? 250 : building.type === 'decoration' ? 150 : 205 + (size.w - 2) * 24);
    const height = illustratedMetrics?.height || detailedMetrics?.height || barracksMetrics?.height
      || (building.type === 'keep' ? 220 : building.type === 'decoration' ? 155 : 185);
    const queue = ctx.getProfile().constructionQueue.find(item => item.buildingId === building.id);
    const statusClass = building.status === 'burning' ? 'is-burning' : ['constructing', 'upgrading'].includes(building.status) ? 'is-building' : '';
    const footprintWidth = (size.w + size.h) * TILE_W / 2;
    const footprintHeight = (size.w + size.h) * TILE_H / 2;
    const illustratedBuildingArt = globalThis.ReinosIllustratedBuildings?.isometricArt?.(building)
      || (supportsIllustrated
        ? `<img class="illustrated-building-image illustrated-building-image-isometric" src="${globalThis.ReinosIllustratedBuildings?.assetFor?.(building.type, building.level || 1) || ('../assets/buildings/levels/' + building.type + '/level_01.png')}" alt="${esc(meta.name)} — nível ${building.level || 1}" draggable="false" />`
        : '');
    const detailedBuildingArt = globalThis.ReinosBuildingVisuals?.isometricArt?.(building) || '';
    const isDetailedBarracks = building.type === 'barracks' && Boolean(globalThis.ReinosBarracksVisuals?.isometricArt);
    const visualArt = illustratedBuildingArt || detailedBuildingArt || (isDetailedBarracks
      ? globalThis.ReinosBarracksVisuals.isometricArt(building)
      : buildingSvg(building.type, building.level || 1));
    const detailedClass = illustratedBuildingArt ? 'has-illustrated-building-art'
      : (detailedBuildingArt ? 'has-detailed-building-art' : (isDetailedBarracks ? 'has-detailed-barracks-art' : ''));
    return `<button class="castle-building castle-iso-building castle-building-${building.type} castle-building-tier-${tier} ${detailedClass} ${statusClass}" data-action="building-open" data-id="${building.id}" style="left:${point.x - width / 2}px;top:${point.y - height + TILE_H / 2}px;width:${width}px;height:${height}px;z-index:${700 + Math.round((centerX + centerY) * 12)};--foot-w:${footprintWidth}px;--foot-h:${footprintHeight}px" title="${esc(meta.name)} — Nível ${building.level || 1}">
      <span class="castle-building-click-zone" data-action="building-open" data-id="${building.id}" title="${esc(meta.name)} — Nível ${building.level || 1}" aria-label="${esc(meta.name)} — Nível ${building.level || 1}"></span>
      <span class="castle-iso-building-shadow"></span>
      <span class="castle-iso-building-art">${visualArt}</span>
      <span class="castle-building-level-badge">${building.level || 1}</span>
      <span class="castle-building-label"><strong>${esc(meta.name)}</strong><em>Nv. ${building.level || 1}</em></span>
      ${queue ? `<span class="castle-building-timer" data-countdown="${queue.endAt}">${ctx.formatTime(queue.endAt - ctx.now())}</span>` : ''}
    </button>`;
  }

  function wallSegment(x, y, orientation, profile, gate = false) {
    const point = project(x, y);
    const level = Math.max(1, Number(gate ? profile.castleState?.gateLevel : profile.castleState?.wallLevel) || 1);
    const tier = Math.min(5, level);
    const visuals = globalThis.ReinosFortificationVisuals;
    const z = 440 + Math.round((x + y) * 10);

    if (gate && visuals?.gateArt) {
      const metrics = visuals.metrics?.gate || { width: 220, height: 182 };
      return `<button class="castle-gate castle-real-gate wall-${orientation} fort-level-${tier}" data-action="castle-fortification-open" title="Muralha, portão e torres" style="left:${point.x - metrics.width / 2}px;top:${point.y - metrics.height + 31}px;z-index:${z + 72}">${visuals.gateArt(tier)}</button>`;
    }

    if (visuals?.wallArt) {
      const metrics = visuals.metrics?.wall || { width: 108, height: 90 };
      return `<span class="castle-iso-wall-segment castle-real-wall wall-${orientation} fort-level-${tier}" style="left:${point.x - metrics.width / 2}px;top:${point.y - metrics.height + 31}px;z-index:${z}">${visuals.wallArt(tier, orientation)}</span>`;
    }

    return `<${gate ? 'button' : 'span'} class="${gate ? 'castle-gate' : 'castle-iso-wall-segment'} wall-${orientation} fort-level-${tier}" ${gate ? 'data-action="castle-fortification-open" title="Muralha, portão e torres"' : ''} style="left:${point.x - 34}px;top:${point.y - (gate ? 28 : 18)}px;z-index:${z}">${gate ? '<span>⚔</span>' : ''}</${gate ? 'button' : 'span'}>`;
  }

  function towerSvg(level) {
    const tier = Math.min(5, Math.max(1, Number(level) || 1));
    if (globalThis.ReinosFortificationVisuals?.towerArt) return globalThis.ReinosFortificationVisuals.towerArt(tier);
    const roofColor = COLORS.roof[Math.min(COLORS.roof.length - 1, tier - 1)];
    return `<svg viewBox="0 0 100 130"><ellipse cx="50" cy="113" rx="38" ry="10" fill="#172019" opacity=".35"/>${prism(50, 52, 55, 27, 55 + tier * 4, '#96988f', '#62655f', '#797d75')}${roof(50, 48, 68, 30, 35 + tier * 2, roofColor, '#662823')}<rect x="44" y="84" width="12" height="22" fill="#27333a"/>${tier >= 4 ? '<circle cx="50" cy="70" r="7" fill="#d6a83a"/>' : ''}</svg>`;
  }

  function renderFortifications(bounds, profile) {
    const expansionSystem = globalThis.ReinosCastleExpansions;
    const edges = expansionSystem?.boundaryEdges?.(profile) || [];
    const gate = expansionSystem?.gateEdge?.(profile);
    const gateKey = gate ? `${gate.x}:${gate.y}:${gate.orientation}` : '';
    let walls = '';
    for (const edge of edges) {
      const key = `${edge.x}:${edge.y}:${edge.orientation}`;
      walls += wallSegment(edge.x, edge.y, edge.orientation, profile, key === gateKey);
    }

    const points = expansionSystem?.towerPoints?.(profile) || [
      { x: bounds.minX - 0.72, y: bounds.minY - 0.72 }, { x: bounds.maxX + 0.72, y: bounds.minY - 0.72 },
      { x: bounds.minX - 0.72, y: bounds.maxY + 0.72 }, { x: bounds.maxX + 0.72, y: bounds.maxY + 0.72 }
    ];
    const towers = points.map(({ x, y, kind }) => {
      const point = project(x, y);
      const metrics = globalThis.ReinosFortificationVisuals?.metrics?.tower || { width: 94, height: 124 };
      const detailed = Boolean(globalThis.ReinosFortificationVisuals?.towerArt);
      return `<span class="castle-tower castle-iso-tower ${detailed ? 'castle-real-tower' : ''} ${kind === 'expansion' ? 'expansion-tower' : ''}" style="left:${point.x - metrics.width / 2}px;top:${point.y - metrics.height + 35}px;z-index:${580 + Math.round((x + y) * 10)}">${towerSvg(profile.castleState?.towerLevel)}</span>`;
    }).join('');
    return `<div class="castle-wall castle-iso-wall-edge castle-wall-dynamic">${walls}</div>${towers}`;
  }

  function deterministic(seed) {
    const value = Math.sin(seed * 12.9898) * 43758.5453;
    return value - Math.floor(value);
  }

  function scenerySvg(kind, variant) {
    if (kind === 'rock') return `<svg viewBox="0 0 70 60"><ellipse cx="35" cy="50" rx="27" ry="7" fill="#172019" opacity=".25"/><polygon points="8,48 23,19 42,48" fill="#787b75"/><polygon points="30,49 47,11 65,49" fill="#92958e"/><path d="M47 11 L41 27 L54 24 Z" fill="#c5c5bc"/></svg>`;
    if (kind === 'water') return `<svg viewBox="0 0 120 70"><ellipse cx="60" cy="38" rx="55" ry="26" fill="#3d9db5" stroke="#b9a76a" stroke-width="6"/><path d="M22 38 Q48 24 72 38 T106 38" stroke="#a8e7ef" stroke-width="4" fill="none" opacity=".65"/></svg>`;
    const greens = variant % 2 ? ['#3f7e37', '#5b9c43', '#2e6731'] : ['#4c8c38', '#6aaa48', '#376f32'];
    return `<svg viewBox="0 0 80 105"><ellipse cx="40" cy="93" rx="29" ry="8" fill="#172019" opacity=".25"/><rect x="35" y="55" width="11" height="38" fill="#725033"/><circle cx="40" cy="42" r="29" fill="${greens[0]}"/><circle cx="23" cy="55" r="20" fill="${greens[1]}"/><circle cx="57" cy="56" r="21" fill="${greens[2]}"/><circle cx="42" cy="24" r="20" fill="${greens[1]}"/></svg>`;
  }

  function renderScenery(bounds, profile) {
    let html = '';
    let count = 0;
    const rangeX = Math.max(24, (bounds.maxX - bounds.minX + 1) + 8);
    const rangeY = Math.max(24, (bounds.maxY - bounds.minY + 1) + 8);
    const originX = Math.max(-2, bounds.minX - 4);
    const originY = Math.max(-2, bounds.minY - 4);
    for (let i = 0; i < 180; i++) {
      const x = originX + deterministic(i + 3) * rangeX;
      const y = originY + deterministic(i + 47) * rangeY;
      const inside = globalThis.ReinosCastleExpansions?.isCellUnlocked?.(profile, Math.floor(x), Math.floor(y));
      if (inside) continue;
      const kindRoll = deterministic(i + 91);
      const kind = kindRoll > .9 ? 'water' : kindRoll > .7 ? 'rock' : 'tree';
      const point = project(x, y);
      const width = kind === 'water' ? 125 : kind === 'rock' ? 72 : 82;
      const height = kind === 'water' ? 72 : kind === 'rock' ? 62 : 108;
      html += `<span class="castle-iso-scenery scenery-${kind}" style="left:${point.x - width / 2}px;top:${point.y - height + 16}px;width:${width}px;height:${height}px;z-index:${180 + Math.round((x + y) * 5)}">${scenerySvg(kind, i)}</span>`;
      count++;
      if (count >= 70) break;
    }
    return html;
  }

  function renderFields(bounds, stage) {
    if (stage.id < 2) return '';
    const positions = [
      [bounds.maxX + 2.2, bounds.minY + 2.5], [bounds.maxX + 2.7, bounds.minY + 6], [bounds.minX + 2.5, bounds.minY - 2.4]
    ].slice(0, Math.min(3, stage.id - 1));
    return positions.map(([x, y], index) => {
      const point = project(x, y);
      return `<span class="castle-iso-field field-${index}" style="left:${point.x - 100}px;top:${point.y - 42}px;z-index:${160 + Math.round((x + y) * 4)}"><i></i><i></i><i></i><i></i><i></i><i></i></span>`;
    }).join('');
  }

  function renderRoads(bounds, profile) {
    const center = 29.5;
    let html = '';
    const cells = globalThis.ReinosCastleExpansions?.cells?.(profile) || [];
    for (const cell of cells) {
      if (cell.x !== 29 && cell.y !== 29) continue;
      const point = project(cell.x, cell.y);
      html += `<span class="castle-iso-road ${cell.x === 29 ? 'road-y' : 'road-x'}" style="left:${point.x - TILE_W / 2}px;top:${point.y - TILE_H / 2}px;z-index:${105 + Math.round(cell.x + cell.y)}"></span>`;
    }
    return html;
  }

  function renderScene({ profile, ctx, bounds, helpers }) {
    const stage = stageFor(profile);
    const buildings = [...(profile.buildings || [])].sort((a, b) => {
      const pa = helpers.slotToPosition(a.slot); const pb = helpers.slotToPosition(b.slot);
      return (pa.x + pa.y) - (pb.x + pb.y);
    });
    const keep = buildings.find(item => item.type === 'keep');
    const keepPos = keep ? helpers.slotToPosition(keep.slot) : { x: 9, y: 9 };
    const keepPoint = project(keepPos.x + 1, keepPos.y + 1);
    return {
      html: `<div class="castle-world-shell castle-iso-shell stage-${stage.id}">
        <div class="castle-camera-controls"><button type="button" data-castle-camera="out" title="Afastar">−</button><output data-castle-zoom-output>${Math.round((profile.castleState?.camera?.zoom || 1) * 100)}%</output><button type="button" data-castle-camera="in" title="Aproximar">＋</button><button type="button" data-castle-camera="home" title="Centrar no castelo">⌂</button></div>
        <div class="castle-world-viewport" id="castle-world-viewport">
          <div class="castle-iso-stage" id="castle-iso-stage">
            <div class="castle-world isometric-castle-world" id="castle-isometric-world" data-base-width="${WORLD_WIDTH}" data-base-height="${WORLD_HEIGHT}" style="width:${WORLD_WIDTH}px;height:${WORLD_HEIGHT}px">
              <div class="castle-iso-land"></div><div class="castle-iso-stream stream-a"></div><div class="castle-iso-stream stream-b"></div>
              ${globalThis.ReinosCastleExpansions?.groundHtml?.(profile, project) || globalThis.ReinosFortificationVisuals?.courtyard?.(bounds, project) || ''}${renderScenery(bounds, profile)}${renderFields(bounds, stage)}${renderTerrain(profile, bounds, helpers.gridSize || 60)}${renderRoads(bounds, profile)}${renderFortifications(bounds, profile)}
              ${buildings.map(building => renderBuilding(building, ctx, helpers)).join('')}
              <span class="castle-inhabitant inhabitant-a" style="left:${keepPoint.x - 115}px;top:${keepPoint.y + 105}px;z-index:1300">🧑‍🌾</span>
              <span class="castle-inhabitant inhabitant-b" style="left:${keepPoint.x + 100}px;top:${keepPoint.y + 55}px;z-index:1300">🛒</span>
              <span class="castle-bird bird-a" style="left:${keepPoint.x - 220}px;top:${keepPoint.y - 230}px;z-index:1500">⌁</span>
              <span class="castle-bird bird-b" style="left:${keepPoint.x + 180}px;top:${keepPoint.y - 190}px;z-index:1500">⌁</span>
            </div>
          </div>
        </div>
        <div class="castle-legend"><b>Controlos do castelo</b><span>Roda do rato: aproximar ou afastar</span><span>Arrasta o terreno para percorrer o castelo</span><span>Usa o botão Construir para adicionar edifícios</span><span>Seleciona e arrasta um edifício para o reposicionar</span><span>Clica sem arrastar para abrir as opções do edifício</span></div>
      </div>`,
      center: keepPoint,
      stage
    };
  }

  function activate({ profile, ctx, center }) {
    const viewport = document.querySelector('#castle-world-viewport');
    const stage = document.querySelector('#castle-iso-stage');
    const world = document.querySelector('#castle-isometric-world');
    return globalThis.ReinosCastleCamera?.mount?.({ viewport, stage, world, profile, ctx, center }) || false;
  }

  globalThis.ReinosCastleIsometricView = {
    VERSION: 4,
    TILE_W,
    TILE_H,
    WORLD_WIDTH,
    WORLD_HEIGHT,
    project,
    tierFor,
    stageFor,
    renderScene,
    activate
  };
})();
