/**
 * Cast Conductor Proprietary License v5
 * SPDX-License-Identifier: LicenseRef-CastConductor-Proprietary-v5
 * 
 * Copyright (c) 2025 CastConductor.com. All Rights Reserved.
 * 
 * This file is part of Cast Conductor ("Software"). The Software and its source
 * code constitute proprietary, confidential, and trade secret information of
 * CastConductor.com ("Company"). Any access or use is governed strictly by the
 * Cast Conductor Proprietary License v5 ("License"). By installing, copying,
 * accessing, compiling, or otherwise using the Software you agree to be bound by
 * all terms of the License. If you do not agree, you must cease use immediately.
 * 
 * Key Terms (Summary – see full License for binding terms):
 *  1. No Redistribution: You may not publish, distribute, sublicense, rent,
 *     lease, transfer, sell, or otherwise make the Software (or any derivative)
 *     available to any third party without prior written consent of Company.
 *  2. No Modification: Modification, reverse engineering, decompilation, or
 *     disassembly is prohibited except to the limited extent expressly permitted
 *     by applicable law that cannot be contractually waived.
 *  3. Confidentiality: Treat all source code and related artifacts as Company
 *     Confidential Information. Maintain at least the same degree of care as for
 *     your own confidential materials, and not less than reasonable care.
 *  4. No Patent License: No express or implied patent rights are granted. Future
 *     patents (if any) are fully reserved.
 *  5. No Trademark License: Company names, marks, and logos may not be used
 *     without prior written permission.
 *  6. Limited Internal Use: Use is limited solely to internal evaluation and
 *     operation of licensed Cast Conductor deployments. Commercial hosting or
 *     resale as a service requires a separate written agreement.
 *  7. Telemetry & License Validation: The Software may periodically transmit a
 *     hashed installation identifier, domain (or site ID), plugin/app version,
 *     and a truncated (non-reversible) fragment of the license key solely to
 *     validate activation status and enforce licensing. This minimal "phone home"
 *     check contains no personal or content data. If optional telemetry is later
 *     introduced it will be limited to aggregate operational metrics (no PII),
 *     fully documented, and optionally disableable per published instructions.
 *  8. Third-Party Components: The Software may include open source components
 *     covered by their own licenses. See THIRD-PARTY-NOTICES.md. Those licenses
 *     govern their respective components; this License governs all remaining code.
 *  9. Export Compliance: You are responsible for compliance with all applicable
 *     export control and sanctions laws.
 * 10. Warranty Disclaimer: THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF
 *     ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY,
 *     FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.
 * 11. Limitation of Liability: IN NO EVENT WILL COMPANY OR AUTHORS BE LIABLE FOR
 *     ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE
 *     DAMAGES, OR LOST PROFITS, EVEN IF ADVISED OF THE POSSIBILITY.
 * 12. Acceptance: Use of the Software constitutes acceptance of the License.
 * 13. Enforcement: Unauthorized reproduction or distribution may result in civil
 *     and criminal penalties and will be prosecuted to the maximum extent allowed
 *     by law.
 * 
 * Authoritative EULA: EULA-v5.1.md (repository root – private) and https://castconductor.com/eula
 * Precedence: If this summary conflicts with the EULA, the EULA governs.
 * Revision: Current EULA revision v5.1 (subject to update; check EULA for current enterprise thresholds).
 * 
 * Full License text available from: licensing@castconductor.com
 * Security reports: security@castconductor.com
 * Commercial inquiries: licensing@castconductor.com
 * 
 * END OF HEADER
 */

// Phase 2.6 extraction: container collection + canvas rendering + stage sizing

export async function loadContainerData(editor) {
	try {
		editor.showNotification('Loading container data...', 'info');
		console.debug('[CC] loadContainerData:start');
		await fetchAndRenderContainers(editor);
		const containers = document.querySelectorAll('.container-item');
		for (const container of containers) {
			const containerId = container.getAttribute('data-container-id');
			if (containerId) await editor.loadContainerBlocks(containerId);
		}
		editor.hideNotification();
		console.debug('[CC] loadContainerData:end');
	} catch (e) {
		console.error('Error loading container data:', e);
		editor.showNotification('Error loading container data', 'error', true);
	}
}

export async function fetchAndRenderContainers(editor) {
	try {
		const resp = await fetch(`${castconductorCanvasAjax.rest_url}castconductor/v5/containers`, { method:'GET', headers:{ 'Content-Type':'application/json','X-WP-Nonce':castconductorCanvasAjax.nonce } });
		if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
		const containers = await resp.json();
		editor._containersById = {}; (containers||[]).forEach(c => { editor._containersById[String(c.id)] = c; });
		renderContainersList(editor, containers);
		renderContainersOnCanvas(editor, containers);
		if ((!containers || containers.length === 0) && !editor._offeredPresetOnce) { editor._offeredPresetOnce = true; editor.showPresetChooserModal?.(); }
	} catch(e) {
		console.error('Error fetching containers:', e);
		editor.showNotification('Unable to load containers', 'error', true);
	}
}

export function renderContainersList(editor, containers) {
	const listEl = document.querySelector('.containers-list');
	if (!listEl) return;
	if (!containers || containers.length === 0) { listEl.innerHTML = '<div class="no-containers">No containers found</div>'; return; }
	listEl.innerHTML = (containers||[]).map(c => `
		<div class="container-item" data-container-id="${editor.escapeHtml(String(c.id))}">
			<div class="container-item-header">
				<h5>${editor.escapeHtml(c.name || 'Untitled Container')}</h5>
				<div class="container-controls">
					<label class="container-toggle">
						<input type="checkbox" class="container-enabled-toggle" data-container-id="${editor.escapeHtml(String(c.id))}" ${c.enabled ? 'checked' : ''}>
						<span class="toggle-slider"></span>
					</label>
					<label class="container-shuffle-toggle" title="Shuffle impression order for this container only" style="display:inline-flex;align-items:center;gap:6px;">
						<input type="checkbox" data-behavior-key="shuffle_items" ${c.behavior?.shuffle_items ? 'checked' : ''} />
						<span style="font-size:12px;color:#334155;">Shuffle</span>
					</label>
					<button type="button" class="container-defaults-btn" title="Apply production defaults" data-container-id="${editor.escapeHtml(String(c.id))}">Defaults</button>
					<button type="button" class="container-edit-btn" data-container-id="${editor.escapeHtml(String(c.id))}">⚙️</button>
					<button type="button" class="container-delete-btn" data-container-id="${editor.escapeHtml(String(c.id))}">🗑️</button>
				</div>
			</div>
			<div class="container-details">
				<span class="container-position">${editor.escapeHtml(c.position || c.type || '')}</span>
				<span class="container-size">${parseInt(c.width,10)||0}×${parseInt(c.height,10)||0}</span>
				<span class="container-zindex">Z: ${parseInt(c.z_index,10)||0}</span>
			</div>
			<div class="container-assignments">
				${editor.renderZoneSelectorHtml ? editor.renderZoneSelectorHtml(c) : ''}
				<h6>Assigned Content Blocks:</h6>
				<div class="assigned-blocks" id="assigned-blocks-${editor.escapeHtml(String(c.id))}"></div>
				<button type="button" class="assign-block-btn" data-container-id="${editor.escapeHtml(String(c.id))}">+ Assign Content Block</button>
			</div>
		</div>`).join('');
}

export function renderContainersOnCanvas(editor, containers) {
	const canvasEl = document.getElementById('canvas-containers');
	if (!canvasEl) return;
	if (!containers || containers.length === 0) { canvasEl.innerHTML=''; return; }
	ensureCanvasStage(editor);
	try { editor.renderActiveBackground?.(); } catch(_) {}
	canvasEl.innerHTML = (containers||[]).map(c => {
		const pos = (c.position || 'custom').toLowerCase();
		const def = (p) => { if (p==='lower_third' || p==='upper_third') return { w:1280, h:240 }; if (p==='full_screen') return { w:1280, h:720 }; return { w:600, h:200 }; };
		const d = def(pos);
		let w = parseInt(c.width,10); if (!Number.isFinite(w) || w<=0) w=d.w;
		let h = parseInt(c.height,10); if (!Number.isFinite(h) || h<=0) h=d.h;
		w = Math.max(40, Math.min(1280, w)); h = Math.max(40, Math.min(720, h));
		let x = parseInt(c.x_position,10); if (!Number.isFinite(x)) x=0;
		let y = parseInt(c.y_position,10); if (!Number.isFinite(y)) y = (pos==='lower_third' ? (720 - h) : 0);
		if (pos==='lower_third' && (y + h > 1080 || y < 0)) y = 1080 - h;
		if (x<0) x=0; if (y<0) y=0; if (x+w>1920) x=1920-w; if (y+h>1080) y=1080-h;
		const padTop = parseInt(c.padding_top,10); const padRight=parseInt(c.padding_right,10); const padBottom=parseInt(c.padding_bottom,10); const padLeft=parseInt(c.padding_left,10);
		const pT=Number.isFinite(padTop)?padTop:0; const pR=Number.isFinite(padRight)?padRight:0; const pB=Number.isFinite(padBottom)?padBottom:0; const pL=Number.isFinite(padLeft)?padLeft:0;
		const opacity = c.enabled ? '' : 'opacity:0.5;';
		return `<div class="canvas-container" data-container-id="${editor.escapeHtml(String(c.id))}" data-enabled="${c.enabled?'1':'0'}" data-position="${editor.escapeHtml(pos)}" data-padding-top="${pT}" data-padding-right="${pR}" data-padding-bottom="${pB}" data-padding-left="${pL}" data-rotation-interval="${parseInt(c.rotation_interval,10)||15}" style="position:absolute;left:${x}px;top:${y}px;width:${w}px;height:${h}px;z-index:${parseInt(c.z_index,10)||0};${opacity}">
			<div class="container-border">
				<div class="container-label">${editor.escapeHtml(c.name || 'Untitled Container')}<span class="container-status">${c.enabled ? '✅' : '❌'}</span></div>
				<div class="container-inner" style="position:absolute;inset:${pT}px ${pR}px ${pB}px ${pL}px;">
					<div class="container-content-preview" id="container-content-${editor.escapeHtml(String(c.id))}"></div>
					${editor.renderZonesOverlayHtml(c)}
				</div>
				<div class="resize-handle tl" data-dir="tl" title="Resize"></div>
				<div class="resize-handle tr" data-dir="tr" title="Resize"></div>
				<div class="resize-handle bl" data-dir="bl" title="Resize"></div>
				<div class="resize-handle br" data-dir="br" title="Resize"></div>
			</div>
		</div>`;
	}).join('');
	editor.bindCanvasInteractions?.();
	editor.bindContainerSelection?.();
	applyCanvasScale(editor);
	if (!editor._resizeBound) { editor._resizeBound = true; window.addEventListener('resize', () => applyCanvasScale(editor)); }
	try { const toggle=document.getElementById('toggle-zone-edit'); if (toggle && toggle.checked) editor.toggleZoneEditMode(true); } catch(_){}
	try { const toggle=document.getElementById('toggle-grid'); if (toggle) editor.toggleCanvasGrid(!!toggle.checked); } catch(_){}
	editor.buildLayersPanel?.();
}

export function ensureCanvasStage(editor) {
	const stage = document.getElementById('canvas-containers'); if (!stage) return;
	stage.style.width='1920px'; stage.style.height='1080px'; stage.style.transformOrigin='top left';
	const parent = stage.parentElement; if (parent) { const rect = parent.getBoundingClientRect(); editor._canvasParentRect = { w: rect.width, h: rect.height }; }
}

export function applyCanvasScale(editor) {
	const stage = document.getElementById('canvas-containers'); if (!stage) return; const g = window.ccveSharedGeometry; if (!g) return;
	const { w: pw, h: ph } = g.getAvailableBox(stage); const s = g.computeUniformScale(pw, ph, g.LOGICAL_STAGE_WIDTH, g.LOGICAL_STAGE_HEIGHT);
	stage.style.transform = `scale(${s})`; stage.style.transformOrigin='top left'; editor._canvasScale = { x: s, y: s };
}

export function persistContainerRect(editor, id, rect) {
	return fetch(`${castconductorCanvasAjax.rest_url}castconductor/v5/containers/${id}`, { method:'PUT', headers:{ 'Content-Type':'application/json','X-WP-Nonce':castconductorCanvasAjax.nonce }, body: JSON.stringify({ x_position: rect.x, y_position: rect.y, width: rect.w, height: rect.h }) }).catch(()=>{});
}

export const containerCanvasApi = { loadContainerData, fetchAndRenderContainers, renderContainersList, renderContainersOnCanvas, ensureCanvasStage, applyCanvasScale, persistContainerRect };
